Source port routing

From lxadm | Linux administration tips, tutorials, HOWTOs and articles
Jump to: navigation, search

Sometimes, you may want some services (i.e. web) to be routed through a different interface. Here is a quick setup with some common problems.


  • – your additional gateway, through which you only want to route web traffic (TCP port 80),
  • – server which needs source port routing altered,
  • tun0 – device on which will be used for source port routing.

Now, we’re ready to start configuration:

  • first, add a new routing table to /etc/iproute2/rt_tables – we’ll call it “http” and it will be table “1” – with it, your /etc/iproute2/rt_tables file should look much like below:
# reserved values
255    local
254    main
253    default
0    unspec
# local
#1    inr.ruhep
1    http

  • assuming the peer through which you want to push http traffic is behind tun0 interface and has address, we have to manipulate routing with the two rules below:
ip route add default via dev tun0 table http
ip rule add from all fwmark 1 table http

Basically, they mean that “http” table traffic need to go through tun0,, and packets marked with “1” value should get there.

  • we also need to mark the packets – we’ll use iptables for that:
iptables -t mangle -A OUTPUT -p tcp -o eth0 -s --sport 80 -j MARK --set-mark 1

This means that in the mangle table, locally-generated packets with source which would by default go through eth0, will be marked with “1” value.

Still doesn’t work? Check these things below:

  • rp_filter has to be set to 0 for given interfaces – 0 is the default value set by the Linux kernel, but some distributions (i.e. Ubuntu, Mandriva) alter it and set it to 1; just adding that to /etc/sysctl.conf should do the trick to make sure this value is set to 0 after reboot:

If you’re not rebooting any time soon, see what these value currently are with:

find /proc/sys/net -name rp_filter | xargs cat
  • there has to be direct, not routed traffic between the hosts – for example, if you have more than one hop, source port routing will not work:
# traceroute
traceroute to (, 30 hops max, 60 byte packets
1 (  0.978 ms  1.185 ms  1.218 ms
2 (  0.159 ms  0.154 ms  0.179 ms

It has to look like below:

# traceroute
traceroute to (, 30 hops max, 60 byte packets
1 (  0.597 ms  0.593 ms  0.590 ms

  • not sure what you have to change on your new gateway ( in this example)? The below should be enough:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

  • note that web traffic should also come from