8

I'm not able to do a ping in a container when the VPN is started on my host machine.

I try do this :

docker run adiazmor/docker-ubuntu-with-ping ping 8.8.8.8

It fails when the VPN is started but this works :

docker run --net=host adiazmor/docker-ubuntu-with-ping ping 8.8.8.8

I can't always have the --net=host options because we can't use links in docker-compose.

I use IKE to start my VPN. Here is conf of the VPN (without seensible data) :

n:version:4
n:network-ike-port:500
n:network-mtu-size:1380
n:client-addr-auto:1
n:network-natt-port:4500
n:network-natt-rate:10
n:network-frag-size:540
n:network-dpd-enable:1
n:client-banner-enable:1
n:network-notify-enable:1
n:client-dns-used:1
n:client-dns-auto:0
n:client-dns-suffix-auto:1
n:client-splitdns-used:1
n:client-splitdns-auto:1
n:client-wins-used:1
n:client-wins-auto:1
n:phase1-dhgroup:2
n:phase1-keylen:256
n:phase1-life-secs:86400
n:phase1-life-kbytes:0
n:vendor-chkpt-enable:0
n:phase2-keylen:256
n:phase2-life-secs:28800
n:phase2-life-kbytes:0
n:policy-nailed:0
n:policy-list-auto:0
b:auth-mutual-psk:----
n:phase2-pfsgroup:-1
s:network-host:[network-host-ip]
s:client-auto-mode:pull
s:client-iface:virtual
s:network-natt-mode:enable
s:network-frag-mode:enable
s:client-dns-addr:8.8.8.8,8.8.4.4
s:auth-method:mutual-psk-xauth
s:ident-client-type:address
s:ident-server-type:any
s:phase1-exchange:main
s:phase1-cipher:aes
s:phase1-hash:sha1
s:phase2-transform:esp-aes
s:phase2-hmac:sha1
s:ipcomp-transform:disabled
s:policy-level:auto
s:policy-list-include:0.0.0.0 / 0.0.0.0

Here is the results of route -n :

On the host when the VPN is not running :

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.254   0.0.0.0         UG    100    0        0 enp4s0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp4s0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-c57946727b62
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-e5b5cdaf12ea
172.20.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-0f8aa3757cdc
172.21.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-89f7a8041283
172.22.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9313de2b3cda
172.23.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-5eb78801c6be
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 enp4s0

When the VPN is running :

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.226.1   0.0.0.0         UG    0      0        0 tap0
0.0.0.0         192.168.1.254   0.0.0.0         UG    100    0        0 enp4s0
78.109.86.184   192.168.1.254   255.255.255.255 UGH   0      0        0 enp4s0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp4s0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-c57946727b62
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-e5b5cdaf12ea
172.20.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-0f8aa3757cdc
172.21.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-89f7a8041283
172.22.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9313de2b3cda
172.23.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-5eb78801c6be
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 enp4s0

On the container (no change if the container is mounted or not) :

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.19.0.1      0.0.0.0         UG    0      0        0 eth0
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

I checked other questions and I didn't found something working in my case. I don't think it's related to DNS because I try to access to an IP address.

What can I do?

Dougui
  • 167
  • 1
  • 2
  • 13
  • did you find a solution to your problem, got the same... – Pascal Gula Dec 03 '18 at 22:05
  • I don't have a real solution. It still hard. I used docker-debian-ike to act like a proxy. So, when a request is performed in the first container, it's transfered to docker-debian-ike and continue the request. – Dougui Dec 04 '18 at 15:10
  • thanks for your quick reply, a workaround is still a valid option! :) – Pascal Gula Dec 05 '18 at 17:52
  • Your question is an answer to my question :). I had problem with connecting to the Internet from container while being connected to a client's VPN. The `--net=host` option is a solution for my issue. – itachi Mar 07 '19 at 17:12
  • @itachi I'm glad it's useful for someone. I still have the problem. – Dougui Mar 07 '19 at 19:49
  • @Dougui I know mate. This trick might be useful when using only one container, but if I need to create a stack of linked containers (like you), then I'll surely have to put them on a bridge and the problem comes back. So I can relate. – itachi Mar 08 '19 at 09:43

1 Answers1

2

Facts-ish:

  • Outbound traffic from your container without the --net=host mode is translated (NAT/PAT) to the host's IP address on the 192.168.1.0 network (bridge mode)
  • Your VPN creates a tap interface in the 192.168.226.X network (it might well be .1/32).
  • Your VPN creates a second default route with lower metric than the usual default route to send all the traffic through the VPN (tap interface).

Considerations:

When the host sends outbound traffic for a new connection (i.e. not replying for an incoming one) it has to decide which route to apply and also which interface is suitable for that traffic.

Based on the route table above, traffic generated on the host will choose the tap interface as it has a lower metric than the en4ps0 interface.

The root cause of the problem:

Traffic generated from inside the container will get translated to the host's IP address in the en4ps0 interface, so it will apply the route suitable for that interface, thus completely skipping the VPN.

The ping might fail due to asymmetric traffic, your VPN software black-holing traffic to/from en4ps0, etc - but the point here is that your container's traffic does not go through the tunnel because of the NAT/PAT.

Depending on your underlying network and other requirements, the macvlan driver might be a better choice than bridge or host. Alternatively you'll have to re-think your architecture or the need to put a VPN on the host (and not on a separate host / device instead)

Pedro Perez
  • 6,202
  • 1
  • 11
  • 11
  • 1
    Thank you very much for your answer. I created a network with `docker network create -d macvlan -o parent=enp4s0 --gateway=192.168.1.254 --subnet=192.168.1.0/24 vpn`. Now, I can ping a domain when the VPN is ON but I cannot access to the container from my host. I tried with localhost and with the given IP. Do you have an idea? – Dougui Mar 13 '19 at 18:50
  • Also, I'm not able to access to domains behind the VPN so I guess it doesn't do the translation. – Dougui Mar 13 '19 at 19:01
  • Hi, maybe you need to add a route for the container to use the IP address of the host as gateway (and make sure the host can route traffic, check the forwarding flag), then apply NAT/masquerading rules in iptables to "hide" behind the host's IP traffic from the container to the hosts behind the VPN – Pedro Perez Mar 15 '19 at 15:33
  • As per accessing the container from the host, I'm guessing some iptables rule might be blocking that traffic... maybe a simultaneous tcpdump on the host and inside the container will shed some more light. – Pedro Perez Mar 15 '19 at 15:34
  • Finally, I'd like to say that at this point you might want to use an external machine to connect to the VPN and route traffic against that... it seems the setup is getting too complex – Pedro Perez Mar 15 '19 at 15:34
  • I tried to allow all connections in iptables and I still have the problem. As I said in the comments of my question, I created a container with the VPN connexion. Maybe I can redirect requests from the host to this container. WDYT? Is it possible? – Dougui Mar 15 '19 at 18:16
  • If that container also uses macvlan (i.e. it's not behind a NAT and can be configured as gateway for your VPN routes) I think it should be possible – Pedro Perez Mar 21 '19 at 09:10
  • I posted [this question](https://serverfault.com/questions/961759/use-a-docker-container-as-a-proxy-to-use-a-vpn). – Dougui Apr 05 '19 at 20:18