0

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.

EightBitTony
  • 9,311
  • 1
  • 34
  • 46
Ross Patterson
  • 149
  • 2
  • 8
  • 3
    If you are going to ask a question about routing, can you give us some useful information, like your network configuration, including all your IP addresses and routing tables? Given the current lack of information, about the only think I can say is that **you need to create the routes you need to create**. – Zoredache Jun 25 '12 at 19:25
  • Jeez, people, I'm happy to add details and just have. If you're all this upset, maybe take a break from trying to help others. – Ross Patterson Jun 25 '12 at 19:31
  • @RossPatterson, Could you give a practical example of what you mean when you say "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`."? Specifically, what do you mean when you say "running on the gateway". What services on the gateway need to go out `tun0` and what interfaces are those services bound to? – Mike Pennington Jun 25 '12 at 22:05
  • @mike-pennington I mean that there are various applications running on the gateway itself and any network access they use should go through the VPN/tun0. All the network access from other machines on the network should go through eth0 without going through the VPN/tun0. I'm not talking about services here, none of these are bound to interfaces. Clearer? – Ross Patterson Jun 26 '12 at 00:21

2 Answers2

3

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.

mgorven
  • 30,615
  • 7
  • 79
  • 122
  • Sorry for the delay in processing this, just getting back to it now. I also note that `ip rule add` supports `iif` and the [man page suggests](http://www.linuxmanpages.com/man8/ip.8.php#lbBF) it for exactly this. – Ross Patterson Jul 16 '12 at 21:06
  • 1
    @RossPatterson I haven't used that before, but it looks like it's what you want. – mgorven Jul 16 '12 at 21:44
  • Thanks for the inspiration: https://serverfault.com/questions/864606/how-to-route-locally-initiated-traffic-to-different-gateway-than-nated-traffic/864787#864787 – Tobias Jul 24 '17 at 07:27
0

I was able to accomplish this using iif lo as follows.

Move the default route to a separate table so the local rule can override it:

default_route=$(ip route list | grep -m 1 "default via")
ip route add $default_route table default
ip route delete $default_route

Move the priority of the main rule so that the local role can be placed between it and the default rule.

main=$(ip rule list | grep -m 1 "lookup main $")
main_rule=$(echo $main | cut -d ":" -f 2)
main_priority=$(echo $main | cut -d ":" -f 1)
ip rule add $main_rule priority 16384
ip rule delete $main_rule priority $main_priority

Add the VPN default gateway route to a separate table and add the rule.

echo "10 vpn" >> /etc/iproute2/rt_tables
ip rule add priority 24576 iif lo lookup vpn

Tell the OpenVPN client to put the default route in the vpn table by adding the following to the /etc/openvpn/* config file:

script-security 2
route-up "/bin/sh -x -c 'route_net_gateway=$(ip route ls table default | cut -d \" \" -f 3) && ip route add $trusted_ip via $route_net_gateway table vpn && /sbin/ip route add default via $ifconfig_remote table vpn' route-up"
Ross Patterson
  • 149
  • 2
  • 8