Thursday, May 9, 2013

Routing and traffic control in Linux: using MARKed packets

On our Linux gateway box we can establish different routes for different hosts or nets using ip route. If we would like to do this, depending for example in the machine originating the traffic, a neat way to do it would be using netfilter, marking the packets we want to route.

First, to use this we need these kernel options (enabled by default on Debian):
IP: advanced router (CONFIG_IP_ADVANCED_ROUTER)
IP: policy routing (CONFIG_IP_MULTIPLE_TABLES)
IP: use netfilter MARK value as routing key (CONFIG_IP_ROUTE_FWMARK)
Now, let's say our gateway is 10.65.17.153. We have two internet providers, one very fast and one slow. We have a user (10.65.17.8) who we want to access a specific website (106.10.165.51) via the slow link.

First, we will mark the packets from our user. We will use the mark '1' using the mangle table:

 # iptables -A PREROUTING -t mangle -s 10.65.17.8 -d 106.10.165.51 -j MARK --set-mark 1

Now we need to add an action for marked packets. Let's have a look to the default rt_tables:

# cat /etc/iproute2/rt_tables
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep

We are going to add a table starhub.link with table number 20 :

# echo 20 starhub.link >> /etc/iproute2/rt_tables

Now we associate table 20 with the Mark 1:

# ip rule add fwmark 1 table starhub.link

Last, we specify what does the table 20 (AKA starhub.link) do:

# ip route add default via 10.65.17.253 table starhub.link

That's it. Now our client will use Starhub link instead of the default one. The route appears in our system as follows:

# ip route ls
default via 10.65.17.1 dev eth0  proto static
10.65.17.0/24 dev eth0  proto kernel  scope link  src 10.65.17.153

Done. Thanks to the flexibility of IPTABLES we can make a lot of uses from this.


No comments:

Post a Comment