Home > OS >  Docker NET_ADMIN container's ports are inaccessible from outside the host machine
Docker NET_ADMIN container's ports are inaccessible from outside the host machine

Time:06-01

I have a docker-compose file, where I have a VPN running as NET_ADMIN, and the traffic of a bunch of other containers is routed though the VPN container.

The issue is that I can only access web APIs of the other containers (routed through the VPN) from the host machine.

version: "3.5"
services:
  vpn:
    image: ilteoood/docker-surfshark:latest
    container_name: surfshark
    env_file:
      - .env
    cap_add: 
      - NET_ADMIN
    devices:
      - /dev/net/tun
    ports:
      - 8080:8080
      - 8085:8085
    restart: unless-stopped

When I connect to http://localhost:8080/ from the host machine, everything works. When I connect to the container from another machine on the local network via http://192.168.1.6:8080 (the host machine's IP), the connection times out.

This issue only affects the VPN container (and those which route through it). Other containers in the same docker-compose file which aren't routed through the VPN container are working as expected.

The host machine is running Pop!_OS 22.04, on an Intel CPU.

Edit: Routes inside the container:

# ip route list
0.0.0.0/1 via 10.8.8.1 dev tun0 default via 172.21.0.1 dev eth0  
10.8.8.0/24 dev tun0 proto kernel scope link src 10.8.8.9  
84.17.60.250 via 172.21.0.1 dev eth0  128.0.0.0/1 via 10.8.8.1 dev tun0  
172.21.0.0/16 dev eth0 proto kernel scope link src 172.21.0.4 – 

CodePudding user response:

The problem here is that your container is using the VPN for it's default route:

  • A request comes in from your local 192.168.1.0/24 network
  • A service inside the container sends a reply
  • The kernel looks for an appropriate route to reach the 192.168.1.0/24 network, but it doesn't find one, so it chooses the default gateway.
  • The reply goes out the VPN, which doesn't know what to do with a 192.168.1.0/24 destination, so the reply gets dropped

The simplest solution would be to add an explicit route for your local network via the regular Docker default gateway:

# ip route add 192.168.1.0/24 via 172.21.0.1

(Here I'm inferring the gateway address from the address assigned to eth0.)

  • Related