I am trying to route traffic via an OpenVPN tunnel which is running inside a docker container, but cannot get NAT to work

+-------------------+            |   Docker Container  |
|    LAN DEVICE     |            |   eth0  |
|  | +----->    |                     |  +----->   WAN
+-------------------+            |   tun0    |

All routing is setup correctly, and traffic from inside the docker container is routed correctly

/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:0A:0A:19
          inet addr:  Bcast:  Mask:
          RX packets:5104 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3955 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2960043 (2.8 MiB)  TX bytes:908271 (886.9 KiB)

lo        Link encap:Local Loopback
          inet addr:  Mask:
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:576 errors:0 dropped:0 overruns:0 frame:0
          TX packets:576 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:40013 (39.0 KiB)  TX bytes:40013 (39.0 KiB)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:  P-t-P:  Mask:
          RX packets:1748 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3363 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:2231032 (2.1 MiB)  TX bytes:393222 (384.0 KiB)

/ip route via dev tun0
default via dev eth0 dev tun0  proto kernel  scope link  src dev eth0  proto kernel  scope link  src via dev tun0 via dev eth0

I have setup a MASQUERADE rule to NAT traffic from the LAN to the tunnel

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 MASQUERADE  all  --  any    tun0    anywhere             anywhere
  206 14200 DOCKER_POSTROUTING  all  --  any    any     anywhere   

The issue is that the traffic from the LAN is routed directly to tun0 but does not hit the MASQUERADE rule. Note the pkts/bytes are 0/0

I have also confirmed this using tcpdump and wireshark - the connections via tun0 are using the IP, not a NATed IP

enter image description here

This means that the response cannot be routed correctly

I have tried various combinations of iptables rules, but cannot get it to NAT the traffic from eth0 to tun0

I am wondering if this is specific to how docker's container networking is setup, but cannot find any reference to this issue.

  • What happens if you add ! -o tun0 to the second rule with DOCKER_POSTROUTING target? – cburn11 Oct 24 '18 at 2:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.