Split Routing
To get traffic from one service to bypass the default routing tables, we can create a substitute routing table.
Marking Connections
Create New Routing Table
Create a new named routing table by creating a file like
/etc/iproute2/rt_tables.d/redirect.conf
with the contents:
2 redirect
The table number is arbitrary, but 253-255 and 0 are reserved. The name is likewise arbitrary.
Create Routes in New Table
If your routes you want to avoid haven’t been created yet, this is easy:
ip route show table main | \
while read rule ; do
ip route add $rule table redirect
done
You can also use grep to eliminate (for example) tunnel connections:
ip route show table main | grep -v tun | grep -v tap | \
while read rule ; do
ip route add $rule table redirect
done
Select Which Traffic Uses this Table
ip rule add fwmark 0x2 table redirect
Again, the value 0x2
is arbitrary, but 0x0
is reserved.
Mark the appropriate traffic
As an example, this covers traffic coming from the SSH port (i.e., response traffic to an SSH connection).
iptables -A PREROUTING -j CONNMARK --restore-mark
iptables -A PREROUTING -m mark ! --mark 0x0 -j ACCEPT
iptables -A PREROUTING -p tcp -m tcp --dport 22 -j MARK --set-mark 0x2
iptables -A PREROUTING -j CONNMARK --save-mark
iptables -A OUTPUT -j CONNMARK --restore-mark
iptables -A OUTPUT -m mark ! --mark 0x0 -j ACCEPT
iptables -A OUTPUT -p tcp -m tcp --sport 22 -j MARK --set-mark 0x2
iptables -A OUTPUT -j CONNMARK --save-mark
The CONNMARK
lines use the connection tracking module to get all of the
packets in a single connection (as tracked by nf_conntrack
) the same mark.
The mark value in the --set-mark
statement should be the same as the value
used in the ip rule
statement above. OUTPUT
rules are for the packets
originating from the local host. PREROUTING
rules are for the packets coming
in from remote hosts. (This initially sets up the connection tracking with the
mark.)
Flush the Cache
ip route flush cache
This clears any cached routes.
References
- https://arstechnica.com/civis/viewtopic.php?f=16&t=1195455
- http://linux-ip.net/html/routing-tables.html
Just Sending Via Incoming Interface
echo 200 isp2 >> /etc/iproute2/rt_tables
ip rule add from <interface_IP> dev <interface> table isp2
ip route add default via <gateway_IP> dev <interface> table isp2
From https://unix.stackexchange.com/questions/4420/reply-on-same-interface-as-incoming.