policy / source based Routing – Linux

In the following example, we have 2 gateways to the internet and we have 1 default route. In this scenario, the default route(the link that all traffic will go out to), is WAN1. We want only SMTP/email traffic to go out via WAN2, but all other traffic to follow te default route via WAN1. The following assumes that you have already setup NAT, the routes and everything is running as per a normal Africa Online gateway solution.

PolicyRouting.gif
FIRST – Since the outgoing email/SMTP packets are locally generated packets, we will have to use the OUTPUT chain.
SECOND – Since there are two possible routes, you have to use MASQUERADE in order to force the source address of the packet to be the same as the source address of the intended network interface where the packet is going out from.

# /sbin/iptables -t mangle -A OUTPUT -p tcp --dport 25 -j MARK --set-mark 1
# /sbin/iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 25 -j MASQUERADE

Next, we’ll use “ip route” to route packets based upon protocol instead of source and destination. This is because of a limitation with the normal “route” command in linux- it only routes packets based on source and/or destination and we need something that does policy routing. From the ip(8) manpage: http://linux.die.net/man/8/ip

Route tables: Linux-2.x can pack routes into several routing tables identified by a number in the range from 1 to 255 or by name from the file /etc/iproute2/rt_tables. By default all normal routes are inserted into the main table (ID 254) and the kernel only uses this table when calculating routes.

So, we add a new table definition specifically for SMTP traffic to /etc/iproute2/rt_tables:

# echo 201 mail.out >> /etc/iproute2/rt_tables
# ip rule add fwmark 1 table mail.out
# ip rule ls
0:	from all lookup local
32764:	from all fwmark        1 lookup mail.out
32766:	from all lookup main
32767:	from all lookup default

Now we generate a route to the slow but cheap link in the mail.out table:
# /sbin/ip route add default via 192.168.2.1 dev eth2 table mail.out
Now all SMTP traffic generated locally by the box will route out the gateway 192.168.2.1. The normal “ip route” command won’t show the real state of things. Instead, we need to specify which table to look in for the route. Remember that we added the table to /etc/iproute2/rt_tables before, so do:

# ip route show table mail.out
default via 192.168.2.1 dev eth2

If you want to see what’s in the mangle table, do:

# iptables -t mangle -nvL