By default, routing is based on destination IP address, i.e., the routing table will decide where to route the packet depending on the destination address field in the packet. But there are a number of other utilities and options on routing in linux. One interesting fact is that most of the routers are using linux kernel for their IOS (inter operating system). Isn’t that cool? Now you can use your linux machine as your local router with more confidence, right?
Other than destination IP address we can also use source IP address , Tos (Type of service) , fwmark (Marking of packets by kernel) and the interface on which packet arrived as the parameters for routing decision. Before getting in to IP routing let me explain some scenarios where we need Advanced routing features. Suppose we have 3-4 gateways and we can easily differentiate them on their bandwidth, reliability, QoS and cost, which one do we select? We would definitely choose the one with the best combination of all these features. But if everyone selects that gateway and start using it, it would obviously be overwhelmed with the traffic. So it is best to differentiate services based on their priority. We should give more priority to services which need higher bandwidth or more reliability. Then the route packet will be used by higher priority services through the most reliable gateway. One example for such service is the SSH.
Now let’s begin with the commands for this advanced routing feature. We will be using the combination of iptables, IP route and IP rule commands here. All linux systems have an iptable package by default. If you don’t have IP route or IP rule command, you have to download the iproute2 package. Before writing the rules on iptables, check kernel modules and options that are required for the full operation of iptable. But since the latest kernels have all the modules and options for iptables you will not have to worry about it.
Let’s start from the iptable. Here we shall take SSH as the service for routing. Use ‘mangle’ table of iptable for modifying the SSH packets. We will need root access for this. We are assuming that SSH is using its default port 22.
1. #iptables -t mangle -A OUTPUT -p tcp –dport 22 -j MARK –set-mark 0x1
We are marking all packets with destination port 22 as ‘0x1’ .Now save and restart iptables.
#service iptables save
#service iptables restart
To delete this entry from iptables we can use -D instead of -A.
2. Next, create a new IP route table in /etc/iproute2/rt_table by just giving an entry
3. Write rule for SSH packets.
#ip rule add fwmark 0x1 lookup sshtable
4. Add route at new table sshtable. Here we shall use ‘192.168.1.1’ as the gateway for SSH. All other traffic will go through the
default gateway, which can be seen by IP route show command.
We copy all entries except default gateway entry from main table.
# ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table sshtable $ROUTE; done
Add default gateway entry for SSH packets to table sshtable .
#ip route add default via 192.168.1.1 table sshtable
Use “ip route show table sshtable” to show all routes at sshtable.
That’s it..we have done it!!!
You can use SSH to log into your remote server and check your IP with “last” command. You can see that it’s showing your new gateway public IP other than the default gateway. You can use the same for web traffic. Use tcp ports 80,443 ,53 and udp 53 instead of 22 in the above example.
If you want perpetual route settings during reboots, make the following entries in /etc/sysconfig/network-scripts/route-eth0
and /etc/sysconfig/network-scripts/rule-eth0 .
If these files are not there, you can create them and:
in rule-eth0 file paste the following.
fwmark 0x1 lookup sshtable
in route-eth0 add the following line:
default via 192.168.1.1 table sshtable
Then paste # ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table sshtable $ROUTE; done in /etc/rc.local file.