Capacytron
Capacytron

Reputation: 3729

Docker container and host network VPN

I'm trying to run docker image on MacOS with VPN turned on (TUN device). Docker container can access internet, but is not able to access resources behind vpn. What is the right way to make Docker go to VPN network?

I've tried docker run --net host to make docker share host network, it didn't help. Host can access VPN resources, docker container can't resolve their names..

Upvotes: 75

Views: 105082

Answers (14)

ka3ak
ka3ak

Reputation: 3181

In my case the app I used to connect to corporate VPN was a decisive factor. When I switched from Cisco Anyconnect to OpenConnect docker containers began to "see" resources behind VPN.

I run the following command to connect to VPN:

sudo openconnect --protocol=anyconnect --servercert <value> --user=<value> --authgroup=<group> <vpn-host> --useragent='AnyConnect'

I'm using Ubuntu but it solves the problem on MacOS too according to my colleagues who use this OS.

Upvotes: 0

chronoclast
chronoclast

Reputation: 145

I had a similar issue, but in my case, a few package sources needed to be accessed from the VPN in order to build the image.

The host had access to the sources, but the build process was failing. The container couldn't reach them, and apt-get commands were throwing timeout errors.

Using Rancher Desktop in Windows, the solution was rather simple. Head to PreferencesWSLNetwork, and activate the option "Enable networking tunnel", as shown below:

Rancher Desktop Preferences (Windows)

It may be necessary to start the VPN client first, and then launch the Docker daemon (in this case just the Rancher Desktop app).

Upvotes: 0

Petar Nikov
Petar Nikov

Reputation: 1447

None of those solutions worked for me. I am using MacOs with an OpenVPN client. My use case was to have the following setup:

  1. OpenVPN client running locally, providing access to private resources ( e.g Kafka )
  2. Spinning up one service through docker-compose, that needs access to the private resources
  3. Spinning up another service, through a separate docker-compose file, that again needs access to the private resources.

After a quick research on the "host" option, it turns out Docker’s host networking feature is not supported on MacOs — even though the docker run command doesn’t complain about it. The reason for that behaviour is that on MacOs, the docker daemon is running in a virtual machine, not natively on the host, which means it’s not connecting to host ports for your MacOs, but rather it’s connecting to host ports of the virtual machine.

From the official documentation: "The host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, or Docker EE for Windows Server."

Here's also the official GitHub thread about it.

However, the solution turned out to be straightforward.

First, I had to check my OpenVPN configuration. As per the picture, you can see it gave me a private IP address of 172.27.232.98.

enter image description here

After knowing this, I could set up the network's subnet and gateway, which my docker-compose files should use. The code is as follows:

version: "3"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    restart: "no"
    networks:
      - vpn

networks:
  vpn:
    name: vpn
    driver: bridge
    ipam:
      config:
        - subnet: 172.27.0.0/16
          gateway: 172.27.0.1

Some considerations:

  1. It's beneficial to have this same code for each docker-compose file, so that every configuration uses the same network
  2. Under the networks: VPN: name - it's necessary to have this name specified, otherwise docker would try to create a network, prefixed with the service name ( e.g app_vpn ), which will lead to creating a separate network. This generates a new problem - when you try to spin the other docker-compose, it will try to create a second network ( e.g app2_vpn ), but because of the overlapping config, it will possibly fail with the message "ERROR: Pool overlaps with other one on this address space".

Upvotes: 1

Mike
Mike

Reputation: 1273

Restarting Docker Desktop (4.20.1 (110738) on macOS) fixed this for me briefly, but it would eventually stop working again. What ultimately seemed to work was to disable Kubernetes. This is probably caused by a conflict between the VPN subnet and the default Kubernetes subnet (i.e. 10.x.x.x).

See: https://github.com/docker/for-mac/issues/2820#issuecomment-1225980567

Upvotes: 0

Kennethz3
Kennethz3

Reputation: 689

I had to restart docker after connecting host machine to VPN.

sudo systemctl restart docker
docker start {name-of-container}

Upvotes: 52

Andy Mikhailenko
Andy Mikhailenko

Reputation: 1692

For those who are facing a similar issue (with timeout) but when --network host does work: it could be the mismatch in MTU (especially with WireGuard defaults).

Look at the output of ip link. What is the mtu for docker0 and wg0? If the former is larger than the latter (e.g. 1500 vs 1420), the packets coming from your container are probably just being dropped as they are too large.

This can help (in your docker-compose.yaml, or just create a similar external network):

networks:
  default:
    driver: bridge
    driver_opts:
      com.docker.network.driver.mtu: 1420

See also an article on this particular source of problems: https://sylwit.medium.com/how-we-spent-a-full-day-figuring-out-a-mtu-issue-with-docker-4d81fdfe2caf

(I wish I could find that article before solving the problem myself... let this be yet another gateway to the solution).

Upvotes: 1

Rob Dunbar
Rob Dunbar

Reputation: 161

Using docker run --net nat did the trick for me. This was for a Windows container running on Docker for Desktop (Windows)

Upvotes: 0

M C
M C

Reputation: 31

Neither of the previously posted solutions worked for me on MacOS with OpenVPN client. I figured I only need to define extra_hosts like this:

version: "3.9"
services:
    app:
        extra_hosts:
            - "something.vpn:192.168.196.3"

Now accessing something.vpn inside Docker container leads to 192.168.196.3. There was no need to change docker subnet or anything else.

Upvotes: 1

Stanislav Gaistruk
Stanislav Gaistruk

Reputation: 31

Not sure why, but as others have suggested here changing Docker subnet worked. The only difference is that on Docker Desktop for Windows v4.14.0 setting subnet to /28 was not working.

screeshot of error message

But just bumping the subnet IP addess from 192.168.65.0/24 to 192.168.66.0/24 did the trick.

Upvotes: 1

Babad00k
Babad00k

Reputation: 95

Had this issue on docker version 3.6.0 (67351) running on Mac

What worked for me is combining the solutions posted by @Sheridan Rea and @Marco

  1. Changed Docker subnet to 192.168.65.0/28. It was set to 192.168.63.0/24 before. Clicked Apply & Restart / Restart Docker

  2. Run docker network prune

  3. Run docker compose up

Simply changing Docker subnet didn't worked for me

Now I can ping IP addresses behind VPN

Upvotes: 5

Sheridan Rea
Sheridan Rea

Reputation: 151

I had this exact problem. I tried other solutions suggested here, but they didn't work for me. After a lot of trial and error this solution worked very nicely:

Add "bip": "192.168.1.5/24" to the daemon.json configuration file. This file can be found in the docker desktop settings under docker engine or at /etc/docker/daemon.json. BIP is the setting for bridge IP addresses and will change the IPs docker assigns in its subnet. By changing this setting I avoided conflicts between VPN and docker ip addresses.

Restart docker daemon.

Stop all containers.

Run ‘docker network prune’ to remove unused networks.

Restart all containers. This will recreate their networks with the new IP addresses.

You may still need to restart docker after connecting to the VPN in the future. See this thread for other solutions and ideas: https://github.com/docker/for-mac/issues/2820

Upvotes: 15

Marco
Marco

Reputation: 2892

What worked for me was to change docker subnet mask from /24 to /28, then restarted and I can now ping, telnet and other things on my vpn network. It says the default is /28 but docker desktop ships with /24 on it. Maybe it's a typo, I don't know.

Upvotes: 4

Capacytron
Capacytron

Reputation: 3729

Not sure if it's best solution.

I took DNS that appears on my host after connecting to VPN

scutil --dns | grep 'nameserver\[[0-9]*\]'
nameserver[0] : xxx.xxx.xxx.xxx

Modified docker run command:

docker run --cidfile="docker.pid" --dns=xxx.xxx.xxx.xxx --publish-all

Now docker container can access resources behind VPN... It works, but I have no idea if it's good or bad...

Upvotes: 22

ccb
ccb

Reputation: 79

Had a similar problem. OP's solution worked, but so did simply restarting my docker vm:

docker-machine restart $host

Inspiration: https://www.reddit.com/r/docker/comments/39z4xd/when_my_docker_host_is_connected_to_vpn_i_can_no/

Upvotes: 6

Related Questions