patterndockerMinor
Accessing remote servers through a VPN tunnel from within docker container
Viewed 0 times
vpncontainerserversdockerwithintunnelthroughremotefromaccessing
Problem
My laptop has an IPsec VPN tunnel set up to access a remote site (with my side being the VPN client).
As an experiment, I started up a simple docker container on my laptop using
I expected the ping to not work, but I was surprised that it actually did.
I expected that in order to be able to access one of the remote machines from within a docker container, I'd have to first set up the VPN connection from within the container.
If not a full-fledged VPN connection from within the container, I thought that I would at least need to set up some
So my question is how is it that communicating with the remote machines through the tunnel just works without any additional setup?
p.s. in case it matters, my laptop is running Arch Linux and I'm using strongswan to set up the IPsec connection.
As an experiment, I started up a simple docker container on my laptop using
docker run --rm -it alpine:3.7 /bin/sh and from within the container tried to ping one of the remote machines on the other side of the tunnel.I expected the ping to not work, but I was surprised that it actually did.
I expected that in order to be able to access one of the remote machines from within a docker container, I'd have to first set up the VPN connection from within the container.
If not a full-fledged VPN connection from within the container, I thought that I would at least need to set up some
iptables rules on the host machine. (My laptop's private IP address is 192.168.10.1, that of the remote server is 10.2.5.100 and that of my docker container is 172.17.0.2.) But even this wasn't needed...So my question is how is it that communicating with the remote machines through the tunnel just works without any additional setup?
p.s. in case it matters, my laptop is running Arch Linux and I'm using strongswan to set up the IPsec connection.
Solution
If you run
You can see the properties of this network using the following command:
Additionally, if you run
Then, Docker by default creates NAT iptables rules, which allows the containers to communicate with outside world (as the container IP address is not known to the internet). You can see the rules using
Finally, for your container, there is no difference, if you try to reach remote site of your VPN or the internet, as the container only knows how to reach Docker network. You can see that using
So when traffic from the container goes via default route, it hits host routing table (I'm not 100% sure if this is right), it is being routed to your tunnel and then iptables NAT rule applies, changing the source IP of your traffic to IP of your end of the tunnel, so returning traffic will come back over the tunnel as well and then back to your container.
docker run --rm -it alpine:3.7 /bin/sh, created docker container will use default bridge network.You can see the properties of this network using the following command:
docker network inspect bridge. You can see there to which host interface (usually docker0) the network is associated and also what is the subnet for this network (usually 172.17.0.0/16).Additionally, if you run
docker run --rm -it alpine:3.7 ip addr command, you should see the IP address of your container, which should be part of previously mentioned subnet.Then, Docker by default creates NAT iptables rules, which allows the containers to communicate with outside world (as the container IP address is not known to the internet). You can see the rules using
sudo iptables -t nat -nvL POSTROUTING command. It should look similar to:Chain POSTROUTING (policy ACCEPT 144K packets, 15M bytes)
pkts bytes target prot opt in out source destination
392 75916 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0Finally, for your container, there is no difference, if you try to reach remote site of your VPN or the internet, as the container only knows how to reach Docker network. You can see that using
docker run --rm -it alpine:3.7 ip r command:default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link src 172.17.0.2So when traffic from the container goes via default route, it hits host routing table (I'm not 100% sure if this is right), it is being routed to your tunnel and then iptables NAT rule applies, changing the source IP of your traffic to IP of your end of the tunnel, so returning traffic will come back over the tunnel as well and then back to your container.
Code Snippets
Chain POSTROUTING (policy ACCEPT 144K packets, 15M bytes)
pkts bytes target prot opt in out source destination
392 75916 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link src 172.17.0.2Context
StackExchange DevOps Q#11504, answer score: 3
Revisions (0)
No revisions yet.