Source port routing
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.
- 10.4.0.1 – your additional gateway, through which you only want to route web traffic (TCP port 80),
- 10.4.0.2 – server which needs source port routing altered,
- tun0 – device on 10.4.0.2 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 10.4.0.1 address, we have to manipulate routing with the two rules below:
ip route add default via 10.4.0.1 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, 10.4.0.1, 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 10.4.0.2 --sport 80 -j MARK --set-mark 1
This means that in the mangle table, locally-generated packets with 10.4.0.2 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 10.0.0.10 traceroute to 10.0.0.10 (10.0.0.10), 30 hops max, 60 byte packets 1 10.255.255.254 (10.255.255.254) 0.978 ms 1.185 ms 1.218 ms 2 10.0.0.10 (10.0.0.10) 0.159 ms 0.154 ms 0.179 ms
It has to look like below:
# traceroute 10.4.0.1 traceroute to 10.4.0.1 (10.4.0.1), 30 hops max, 60 byte packets 1 10.4.0.1 (10.4.0.1) 0.597 ms 0.593 ms 0.590 ms
- not sure what you have to change on your new gateway (10.4.0.1 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 10.4.0.1