Search code examples
network-programmingroutesiptablesopenvpngateway

Route traffic from internal network (eth1) through openvpn (tun0)


I have two virtual machines both of them in the same internal network (eth1) but only one (the gateway) is actually connected to internet (via eth0) and has openvpn running (on tun0).

In the VM-gateway I want to route eth1 through tun0 but I am not able to do it.

This is the actual set up:

     10.152.152.12                                    
     VM-workstation <===eth1===> VM-gateway <===eth0==> {internet}
                                      /\
                                      ||
                                      \\
                                       \===tun0===> {openvpn tunnel}

Network configuration inside VM-gateway

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.211.1.18     128.0.0.0       UG    0      0        0 tun0
0.0.0.0         10.0.2.2        0.0.0.0         UG    0      0        0 eth0
10.0.2.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
10.152.128.0    0.0.0.0         255.255.192.0   U     0      0        0 eth1
10.211.1.18     0.0.0.0         255.255.255.255 UH    0      0        0 tun0
128.0.0.0       10.211.1.18     128.0.0.0       UG    0      0        0 tun0
220.123.19.246  10.0.2.2        255.255.255.255 UGH   0      0        0 eth0

#220.123.19.246 is the ip address of the vpn server


$ ifconfig
eth0      Link encap:Ethernet  HWaddr 08:00:27:c8:73:5d  
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:157704 errors:0 dropped:0 overruns:0 frame:0
          TX packets:85478 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:139871643 (133.3 MiB)  TX bytes:9667249 (9.2 MiB)
          Interrupt:19 Base address:0xd000

eth1      Link encap:Ethernet  HWaddr 08:00:27:99:f1:e4  
          inet addr:10.152.152.10  Bcast:10.152.191.255  Mask:255.255.192.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1649 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1306 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:139887 (136.6 KiB)  TX bytes:122465 (119.5 KiB)
          Interrupt:16 Base address:0xd040

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:43763 errors:0 dropped:0 overruns:0 frame:0
          TX packets:43763 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:114248277 (108.9 MiB)  TX bytes:114248277 (108.9 MiB)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.211.1.17  P-t-P:10.211.1.18  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:1295 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2092 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:968529 (945.8 KiB)  TX bytes:269286 (262.9 KiB)


$ sysctl net.ipv4.conf.all.forwarding 
net.ipv4.conf.all.forwarding = 1

Inside the VM-gateway I can correctly use tun0

$ ping -I tun0 4.2.2.2
PING 4.2.2.2 (4.2.2.2) from 10.211.1.17 tun0: 56(84) bytes of data.
64 bytes from 4.2.2.2: icmp_seq=1 ttl=55 time=423.2 ms
64 bytes from 4.2.2.2: icmp_seq=2 ttl=55 time=421.7 ms
^C
--- 4.2.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1801ms
rtt min/avg/max/mdev = 421.762/422.484/423.207/12.737 ms

Things I tried (with no success)

As I said before I want to route all traffic coming from VM-workstation (on eth0) through tun0. I tried to use iptables to redirect the traffic but it's working only partially and anyway it's not using tun0

iptables -t nat -A PREROUTING -i eth1 -s 10.152.128.0/18 ! -d 10.152.128.0/18 -J REDIRECT
iptables -t nat -A POSTROUTING -o eth0 -s 10.152.128.0/18 -J MASQUERADE

I also tried with FORWARD but it didn't work at all

iptables -A FORWARD -i eth1 -o tun0 -J ACCEPT
iptables -A FORWARD -i tun0 -o eth1 -J ACCEPT

I tried with ip route but also that didn't work at all:

ip rule add from 10.152.128.0/18 table 200
ip route add default dev tun0 table 200

I feel like there's an easy solution but I can't manage to find it


Solution

  • The second solution (FORWARD) you posted should be possible to use. However you need to enable IP-Forwarding for your system, otherwise this wont work. You can enable it like this

    echo 1 > /proc/sys/net/ipv4/ip_forward
    

    Note: The OpenVPN server does not know that you're providing a route from eth1 to tun0, so it does not know how to respond to traffic coming from your LAN (10.152.128.0/18). Because of this you will also need to tell your OpenVPN server about the local net being accessable by this specific client. Here is a explanation how this can be done. Also you will need to tell your VM-Workstation about the now available route to the VPN network on the normal network interface.

    Edit: If you just want to route traffic through your vpn gateway, proxying would be indeed the correct approach. Dont forget to enable forwarding ofc. This should do the trick:

    iptables -t nat -A POSTROUTING -s 10.152.128.0/18 -o tun0 -j MASQUERADE
    

    Using this approach would require you to inform your VM-Workstation about the VM-Gateway being it's default gateway.