Linux – Route forwarded traffic through eth0 but local traffic through tun0

iproute2linuxroutingUbuntuubuntu-12.04

I have a Ubuntu 12.04/Zentyal 2.3 server configured with WAN NATed on eth0, local interfaces eth1 and wlan0 bridged on br1 on which DHCP runs, and an OpenVPN connection on tun0. I only need the VPN for some things running on the gateway itself and I need to make sure that everything running on the gateway goes through the VPNs tun0.

root:~# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         gw...           0.0.0.0         UG    100    0        0 eth0
link-local      *               255.255.0.0     U     1000   0        0 br1
192.168.1.0     *               255.255.255.0   U     0      0        0 br1
A.B.C.0         *               255.255.255.0   U     0      0        0 eth0

root:~# ip route
169.254.0.0/16 dev br1  scope link  metric 1000
192.168.1.0/24 dev br1  proto kernel  scope link  src 192.168.1.1
A.B.C.0/24 dev eth0  proto kernel  scope link  src A.B.C.186

root:~# ip route show table main
169.254.0.0/16 dev br1  scope link  metric 1000
192.168.1.0/24 dev br1  proto kernel  scope link  src 192.168.1.1
A.B.C.0/24 dev eth0  proto kernel  scope link  src A.B.C.D

root:~# ip route show table default
default via A.B.C.1 dev eth0 

How can I configure routing (or otherwise) such that all forwarded traffic for other hosts on the LAN goes through eth0 but all traffic for the gateway itself goes through the VPN on tun0? Also, since the OpenVPN client changes routing on startup/shutdown, how can I make sure that everything running on the gateway itself loses all network access if the VPN goes down and never goes out eth0.

Best Answer

You need to use some form of policy routing, because you want to route the traffic based on something other than the destination address. I would first try source policy routing, which uses the source address of the packet to select the route. I haven't used it in this kind of situation before, so I'm not if the source address will have already been selected when the rules are checked for new outgoing connections.

First label a new routing table for the VPN connection. This only needs to be done once.

echo 10 vpn >> /etc/iproute2/rt_tables

Populate the new routing table with the rules to send traffic over the VPN (assuming that 1.0.0.10/24 is the eth0 address, and the VPN gateway is at 10.8.0.1).

ip route add 169.254.0.0/16 dev br1 table vpn
ip route add 192.168.1.0/24 dev br1 table vpn
ip route add 1.0.0.0/24 dev eth0 table vpn
ip route add default via 18.8.0.1 table vpn

Then add a rule to use this new table for traffic from the host itself.

ip rule add from 1.0.0.10/32 lookup vpn

If this doesn't work then you're going to have to use firewall marking to select the correct packets instead.

Related Topic