Linux – Routing through iptables

iptableslinuxrouting

I have this vpn client that touches the routing table and then keeps watching it to exit if it gets touched.
It is the kind of setup needed for an endpoint, such as a laptop.

I want to use a small pc as vpn endpoint and route through it for other machines on my LAN(192.168.0.0/24).
As I can't touch the routing table and all the packets are forced through the vpns tun0 device, I was thinking iptables could help me POSTROUTEing packets to the 192.168.0.0 network back to the eth1 device.
I am not sure though, how would this work, because once it exits eth1 it should resolve the IPtoMAC because it is already on the destination network, and I don't know if the packet has already that resolved or won't happen till it reaches the iface.
Any hints?

Best Answer

Since you haven't provided more information, I am unsure how to best answer.

So here goes my attempt at giving you some directions, willfully ignoring that you can't modify your routing table (you will understand why reading my suggestion):

Depending on the VPN client and where it hooks into the FIB (forward information base) of the kernel, you might have some luck in that the monitoring of the FIB, or, using your expression routing table, by the VPN only happens for the local and main rule tables. You can check your routing rules using

ip rule show

For each of the strings behind the tag "lookup" (which are the rule table entries), you can query the according routing information from the FIB, using

ip route show table <name>

With a bit of luck you could try to construct a rule that matches your requirements and give it preference in the rule lookup table. For example (I made something up to give you a head-start), let's add a new rule with higher preference than main to certain flows:

ip rule add from 192.168.1.0/24 to 10.10.212.1/30 iif eth0 oif eth2 lookup 888 pref 12000
ip rule show
   0:   from all lookup local 
   12000:   from 192.168.1.0/24 to 10.10.212.1/30 iif eth0 oif eth2 lookup 888 
   32766:   from all lookup main 
   32767:   from all lookup default 

On a standard Linux (Ubuntu in the case of this post) system, you'd be seeing the three default rule tables local, main and default, of which you normally only see the main table when invoking netstat -rn for example.

Now we want to populate the FIB entries in lookup table 888 with a new routing entries:

ip route add default via 10.37.129.4 dev eth2 table 888

Let's see how our routing entries in table 888 look like:

ip route show table 888
  default via 10.37.129.4 dev eth2

I think you get the idea. Now, with regard to your specific routing needs, it's unclear as to what exactly you're trying to achieve. Make sure that you flush the routing cache when toying with rule tables:

ip route flush cache

Note, that using the iproute2 architecture you can basically filter and modify virtually any FIB entry; rule entries can even be made based on fwmarks and/or u32 classifiers, like follows (example taken from the policy routing book):

tc filter add dev eth1 parent ffff: protocol ip prio 1 u32 \
    match ip src 10.1.1.0/24 classid :1
ip rule add fwmark 1 table 1 prio 15000 realms 3/4
ip route add default via 192.168.1.1 table 1 src 192.168.1.254
ip route flush cache

For things go haywire in rule tables entries, many years ago I had prepared a small bash snippet to put my system back to original routing rules state:

: ${KEEP:="local main default"}
while read prio rule; do
     continue=0
     for keep in ${KEEP}; do
         if [ "${rule//lookup ${keep}/}" != "${rule}" ]; then
             continue=1
         fi
     done
     if [ ${continue} -eq 0 ]; then
         ip rule del prio ${prio%%:*} ${rule//all/0/0}
     fi
done < <(ip rule show)

Surprisingly, it seems that after over 10 years of iproute2's existence, still only few people seem to know that there is an universe beyond classical "broken" tools like ifconfig or netstat.

Related Question