Ip routing based on destination port
We have two connection providers P1 and P2 behind two IP 10.0.0.253 and 10.0.0.254. P1 has a high bandwidth but low latency, P2 is the oposite.
We will use Netfilter and iproute2 to filter output packet to port 22 to provider P2. Everything else will go through provider P1.
First we need to mark packets for TCP connections to port 22 with the iptables command:
$ sudo iptables -A OUTPUT -t mangle -p tcp --destination-port 22 -j MARK --set-mark 1
$ iptables -t mangle -n -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
MARK tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 MARK set 0x1
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
The OUTPUT chain is used for locally generated packets.
Each packet going to port 22 will be marked with value 1. This only command does nothing except marking packets, no behaviour is modified.
The when have to modify routing policies with the ip command.
First let’s display the routing rules:
$ ip rule show
: from all lookup local
32766: from all lookup main
32767: from all lookup default
Add a new routing table, identified by 22, for packets marked with value 1:
$ sudo ip rule add fwmark 1 table 22
$ ip rule show
0: from all lookup local
32765: from all fwmark 0x1 lookup 22
32766: from all lookup main
32767: from all lookup default
The fwmark 1 is a SELECTOR, we should have used from 10.0.0.5 iif eth0
for example.
The table 22 currently route nothing:
$ ip route show table 22
Let’s feed the table 22 with a new routing instruction:
$ sudo ip route add default via 10.0.0.254 dev eth0 table 22
$ ip route show table 22
default via 10.0.0.254 dev eth0