Find the answer to your Linux question:
Results 1 to 9 of 9
Hi All, I have huge problem that I'm trying to solve for more than a week and I need advice. My app is a Border Controller (BC) that forward RTP ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Oct 2008
    Posts
    6

    How can I forward udp packets between two networks with iptables and iproute2


    Hi All,
    I have huge problem that I'm trying to solve for more than a week and I need advice.
    My app is a Border Controller (BC) that forward RTP packets between two endpoints in two different networks (it defines the IPs and port dynamically).
    Each network has its own default gateway thus each network connects to the BC through its own interface.



    Scenario description:
    1. Endpoint A (IP=10.20.5.30:16001) send packets to my Border Controller to 10.20.5.50:35004 which is configured on eth0.
    2. The Border Controller is already configured with iptables DNAT and SNAT in order to change the IP header as described below.
    3. With the help of iproute the packets are routed to Endpoint B (IP=199.203.72.53:1600 through the Border Controller's IP - 172.16.34.51:35006 which is configured on eth1.
    4. Packets from endpoint B to A traverse in the exact opposite direction.
    Schema:
    10.20.5.30:16001(A)<-->10.20.5.254(GW)<-->10.20.5.50:35004(BC_eth0)<-->172.16.34.51:35006(BC_eth1)<-->172.16.0.1(GW)<-->199.203.72.53:16008(B)




    As far as I understand the process goes as follow:
    1. Packets arrive on the Border Controller and marked by the MARK rule in the mangle table in PREROUTING chain (see output of "iptables t mangle nvL")
    2. DNAT occur in PREROUTING chain which change the target IP in the IP header (see output of "iptables t nat nvL")
    3. The routing stage is done by choosing the route according to the mark done in stage 1 (see "ip rule show") or by fallback way to the default route (see "route n"). Which means go to gateway 172.16.0.1 through eth1 or to 10.20.5.254 through eth0.
    4. SNAT occur in POSTROUTING chain which change the source IP in the IP header (see "iptables t nat nvL")
    The actual result is that packet go from endpoint A (10.20.5.30) to endpoint B (199.203.72.53) through the Border Controller correctly however packet from endpoint B arrive the Border Controller but I can't see them go out (I use wireshark to trace the packets).
    These are my iptables and iproute configuration:

    * Command: "iptables t mangle nvL"
    Chain PREROUTING (policy ACCEPT 885K packets, 209M bytes)
    pkts bytes target prot opt in out source destination
    885K 209M PREDSCP all -- * * 0.0.0.0/0 0.0.0.0/0
    0 0 MARK udp -- * * 10.20.5.30 0.0.0.0/0 udp spt:16001 MARK set 0x3

    Chain INPUT (policy ACCEPT 13M packets, 1744M bytes)
    pkts bytes target prot opt in out source destination

    Chain FORWARD (policy ACCEPT 41584 packets, 8295K bytes)
    pkts bytes target prot opt in out source destination

    Chain OUTPUT (policy ACCEPT 868K packets, 202M bytes)
    pkts bytes target prot opt in out source destination
    868K 202M OUTDSCP all -- * * 0.0.0.0/0 0.0.0.0/0
    868K 202M DSCP_EVENTS all -- * * 0.0.0.0/0 0.0.0.0/0

    Chain POSTROUTING (policy ACCEPT 13M packets, 1813M bytes)
    pkts bytes target prot opt in out source destination

    Chain DSCP_EVENTS (1 references)
    pkts bytes target prot opt in out source destination

    Chain OUTDSCP (1 references)
    pkts bytes target prot opt in out source destination

    Chain PREDSCP (1 references)
    pkts bytes target prot opt in out source destination

    * Command: "iptables t nat nvL"
    Chain PREROUTING (policy ACCEPT 32057 packets, 14M bytes)
    pkts bytes target prot opt in out source destination
    0 0 DNAT udp -- * * 0.0.0.0/0 172.16.34.51 udp dpt:35006 to:10.20.5.30:16001
    0 0 DNAT udp -- * * 0.0.0.0/0 10.20.5.50 udp dpt:35004 to:199.203.72.53:16008
    Chain POSTROUTING (policy ACCEPT 25661 packets, 1422K bytes)
    pkts bytes target prot opt in out source destination
    0 0 SNAT udp -- * * 0.0.0.0/0 199.203.72.53 udp dpt:16008 to:172.16.34.51:35006
    0 0 SNAT udp -- * * 0.0.0.0/0 10.20.5.30 udp dpt:16001 to:10.20.5.50:35004
    Chain OUTPUT (policy ACCEPT 25661 packets, 1422K bytes)
    pkts bytes target prot opt in out source destination
    * Command "ip rule show"
    0: from all lookup local
    32762: from all fwmark 0x3 lookup eth1_172.16.0.1
    32763: from 172.16.34.51 lookup eth1_172.16.0.1
    32764: from all fwmark 0x2 lookup eth0_10.20.5.254
    32765: from 10.20.5.33 lookup eth0_10.20.5.254
    32766: from all lookup main
    32767: from all lookup default
    * Command "ip route show table eth1_172.16.0.1"
    default via 172.16.0.1 dev eth1
    * Command "ip route show table eth0_10.20.5.254"
    default via 10.20.5.254 dev eth0
    * Command "route n"
    Kernel IP routing table
    Destination Gateway Genmask Flags Metric Ref Use Iface
    10.20.5.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
    172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
    169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
    0.0.0.0 10.20.5.254 0.0.0.0 UG 0 0 0 eth0

  2. #2
    Just Joined!
    Join Date
    Oct 2008
    Posts
    6
    Hi,

    Finally, after spending on that issue so much time, I found the answer.
    The rp_filter system parameter was set to true thus blocked all packets that need to pass from one interface to another (note that it was only to one direction).

    To solve this you need to run the following command:
    echo 0 > /proc/sys/net/ipv4/conf/<device>/rp_filter
    or
    echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter

    Hope this will help others to solve their problem.

  3. #3
    Just Joined!
    Join Date
    Jun 2013
    Posts
    5
    Hi Kfir,

    If it's possible for you, can you please share the commands done in steps 1,3 and 4. (I am very new with the usage of iptables)
    I am trying to do exactly the same thing which you have achieved here.

    For me, ingress IP is 10.201.1.106 with rtp port 6000 while egress IP is 10.201.1.57 with rtp port 6000.
    I have a proxy with IP configured on eth0 10.201.102.25 with rtp port 10002 for ingress while port 10000 for egress.

    10.201.1.106:6000 --->10.201.102.25:10002 --->10.201.102.25:10000--->10.201.1.57:6000 and vice versa.

    As of now I have done prerouting but rtp packets are not getting forwarded from 10.201.102.25:10002 to 10.201.1.57:6000
    iptables -t nat -A PREROUTING -i eth0 -p udp -m udp --dport 10002 -j DNAT --to-destination 10.201.1.57:6000
    iptables -t nat -A PREROUTING -i eth0 -p udp -m udp --dport 10000 -j DNAT --to-destination 10.201.1.106:6000

    Looking forward to your response.

    Regards,
    _Ayush

  4. $spacer_open
    $spacer_close
  5. #4
    Just Joined!
    Join Date
    Oct 2008
    Posts
    6
    Did you got my reply (think it was deleted)

  6. #5
    Just Joined!
    Join Date
    Oct 2008
    Posts
    6
    Looks like you didn't got it
    Anyway, This issue was a long time ago and I even don't work for that company anymore so I don't have the code to refer to for exact answer, in addition I know that iptables gone considerably forward from those days so some of the stuff I done may not work. However I will give you suggestions and guidance to my best.
    In your case your border controller receive and send packets from the same Network Device (eth0) which is good because it ease the process (no need for the rp_filter stuff I wrote about on this thread).
    It seems that your second rule is not correct. The idea is that you change the packet's destination IP header in prerouting and the packet's source IP header in postrouting.
    So the second command should be as follow (please check my syntax since I'm digging it from the back of my memory 5 years back)
    iptables -t nat -A POSTROUTING -i eth0 -p udp -m udp --dport 10000 -j SNAT --to-destination 10.201.1.106:6000

    I wanted to post a flow chart of the packet lifecycle in iptables but it seems I'm not allowed to post URLs to other sites in this forum thus I'm suggesting you go to google images and look for "iptables flow". Your case is PREROUTING --> FORWARD --> POSTROUTING

  7. #6
    Just Joined!
    Join Date
    Oct 2008
    Posts
    6
    By the way, since you mentioned you are new to iptables you should know about conntrack (connection tracking).
    When a connection is establish it is added to the conntrack which is a module sits before the prerouting box (this make connection more robust and your system more capable) however when you connection is closed the conntrack keep your the entry of your connection for 200 seconds which can be a problem (RTP may continue after the session ends).
    When we work with it we change some kernel stuff to do it however I think that iptables provide API to link to conntrack and remove/add entries dynamically.
    If you are dealing with high sessions capacity you should consider learning connection tracking as well.

  8. #7
    Just Joined!
    Join Date
    Jun 2013
    Posts
    5
    Hi Kfir,

    Thanks a lot for your kind reply. I would definitely go through conntrack as well.
    Just today morning, I could successfully route my media through my proxy. Here is the list of prerouting, forward and postrouting commands I used.
    Actually my case also, proxy interfaces could be different , may not be same IP always, so I may need rp_filter stuff later

    #PREROUTING
    iptables -t nat -A PREROUTING -i eth0 -p udp -m udp --dport 10002 -j DNAT --to-destination 10.201.1.57:6000
    iptables -t nat -A PREROUTING -i eth0 -p udp -m udp --dport 10000 -j DNAT --to-destination 10.201.1.106:6000

    #POSTROUTING
    iptables -t nat -A POSTROUTING -s 10.201.1.106 -d 10.201.1.57 -p udp -o eth0 -j SNAT --to 10.201.102.25:10000
    iptables -t nat -A POSTROUTING -s 10.201.1.57 -d 10.201.1.106 -p udp -o eth0 -j SNAT --to 10.201.102.25:10002

    #FORWARDING
    echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
    echo 1 >/proc/sys/net/ipv4/ip_forward
    iptables -A FORWARD -i eth0 -p udp --dport 6000 -d 10.201.1.57 -j ACCEPT

    Actually, I have a challenge here now.
    In postrouting, I have used a combination of -s and -d to make sure for the rtp packets coming from -s destined to -d, source address should be changed as that of my proxy IP and rtp port. But my postrouting should be based on source IP as well as port as I can receive multiple streams through same IP but different ports. iptables is not allowing me to specify port using -s option.
    Can you help me with the same?

    Regards,
    _Ayush

  9. #8
    Just Joined!
    Join Date
    Jun 2013
    Posts
    5
    I can also use the destination ip/port to specify my SNAT rule here.
    Previously it was not working as I was specifying -p udp after --dport

    iptables -t nat -A POSTROUTING -d 10.201.1.57 --dport 6000 -p udp -o eth0 -j SNAT --to-source 10.201.102.25:10000
    iptables v1.4.10: unknown option `--dport'
    Try `iptables -h' or 'iptables --help' for more information.

    Changing it to below guess is working
    iptables -t nat -A POSTROUTING -p udp -d 10.201.1.57 --dport 6000 -o eth0 -j SNAT --to-source 10.201.102.25:10000

    I think this should keep things working

    Regards,
    _Ayush

  10. #9
    Just Joined!
    Join Date
    Oct 2008
    Posts
    6
    Note that when the packet is in POSTROUTING the packet is already has the new source ip so in your case the packet source IP will be 10.201.102.25:10002

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •