I have the following setup :

  • A CentOS host running the docker service
  • A user defined docker bridge network
  • 2 Docker containers connected to that user defined bridge network
  • An OpenVPN installation (currently running on the host. Can also run in a docker container)
  • Some clients connected to the OpenVPN

How can I allow for docker containers on the docker bridge network to communicate with the openvpn clients on the tun0 network ?

I would like to be able to have tcp based communication between docker1 ( and clients connected to the vpn (172.19.0.x range) in a transparent way.

What do I need to setup on docker (networking / iptables / ...) side and on the host (iptables ?)

  • 1
    Maybe late, but in your case I believe you need tap, nut tun, I have been working on that for more 12 hours with no success till now. Jul 15, 2017 at 12:31
  • @MohammedNoureldin did you guys found a solution? I’m also considering now going to tap device. What’s frustrating is that from within the ovpn container I can access the vpn clients. And from vpn clients I can access the other containers on the same Docker network. But the forwarding between “eth0” and tun0 inside the ovpn container isn’t working. I guess it’s due to tun0 nature vs. tap.
    – Huygens
    Oct 19, 2017 at 16:32
  • @Huygens, yes I solved it, please ask a separate question and give a reference to me and I will do my best to help you. Oct 20, 2017 at 0:45
  • 1
    Hi @MohammedNoureldin I’ve found the 2 missing instructions for it to work. They were in openvpn man pages 👍. I’ll post an answer soon to this question for others.
    – Huygens
    Oct 21, 2017 at 7:21
  • 1
    @Huygens, good to know, actually I have not had yet time to post the answer, but I am interested to see what worked for your case. Oct 21, 2017 at 11:12

1 Answer 1



I have been using the very good Docker container from Kyle Manna (https://github.com/kylemanna/docker-openvpn). I'm using the so-called "paranoid" documentation to set-up my OpenVPN server, but in my view this should be the standard way and not the paranoid way.


In order to allow bi-directional connection between selected Docker containers and the VPN clients, you need to create a Docker network on which you are going to attach container which should be allowed to be accessed by the VPN clients. The VPN server is going to be one of those containers.

The VPN server should have the client-to-client, topology subnet, dev tun0 (or other tun device) and push "route <docker net IP> <docker net mask>" configured.

The host of the VPN server should be configured to support forwarding of IP packets from one subnet to another. This means setting the sysctl ip_forward to 1 (it should be the case if you have Docker install), allowing packets from the tun device to go through the iptables FORWARD chain and setting proper routing. This can be summarise with these commands:

$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add via <IP address of OpenVPN server container>

Anyway, here are the options I've used to set-up the server:

$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://<FQDN> -N -d -c -p "route <docker net IP> <docker net range>" -e "topology subnet"

This should generate a server config file similar to:

verb 3
key /etc/openvpn/pki/private/vpn.example.com.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.example.com.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60

proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log

user nobody
group nogroup

### Push Configurations Below
push "dhcp-option DNS"
push "route"

### Extra Configurations Below
topology subnet

Concrete example

I will now take a concrete example. In this example, I will run the above mention OpenVPN server inside Docker on host vpn.example.com. This container is attached to the Docker network docker-net-vpn. Here are the commands (in this example I generate the server configuration directly on the server and I skip the CA generation, please follow the paranoid documentation of the above mention project instead):

$ docker network create --attachable=true --driver=bridge --subnet= --gateway= docker-net-vpn
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://vpn.example.com -N -d -c -p "route" -e "topology subnet"
$ docker run --detach --name openvpn -v $PWD/files/openvpn:/etc/openvpn --net=docker-net-vpn --ip= -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn:2.4
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add via

The first command creates a dedicated new Docker network which define a new subnet. We will attach the OpenVPN server to this network.

The second one creates the OpenVPN configuration using the same subnet as defined in the 1st command.

The third one creates the OpenVPN server. It is attached to the newly created Docker network and uses a fix IP.

The fourth and fifth commands configure IP forwarding.

The last command adds a new route towards the VPN client configuration via the OpenVPN container fixed IP.


I haven't tried it, but it should be possible to restrict the FORWARD rule for iptables. The Docker network creation created a new bridge device. This bridge is named br-<ID> with ID being the first 12 characters of the Docker network ID. This ID can be obtained with docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12. Therefore the following command is maybe more restrictive (so better security-wise) but should still allow our traffic to be routed:

$ NET_VPN_BRIDGE="br-$(docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12)"
$ sudo iptables -A FORWARD -i tun+ -o ${NET_VPN_BRIDGE} -j ACCEPT
  • Hey, can't get this to work, I can tracerote to and I get: 1 gnet ( 1966.269 ms !H 1966.248 ms !H 1966.239 ms !H, but I can't ping or reach open ports.
    – GuySoft
    Dec 29, 2018 at 23:27
  • Hi @GuySoft what traceroute is reporting is that your last hop ( cannot reach the host So it means your routing table is probably incorrect. Can we chat to see where is the problem?
    – Huygens
    Dec 30, 2018 at 22:26
  • It started working, I think what happend is that both machines had docker installed, and both had a subnet, that made things clash, I need to find a way to make docker not create a subnet that would clash on the client machine.
    – GuySoft
    Jan 1, 2019 at 14:04
  • If you use Docker Compose, you can specify the IP address range that the network should use. See the Compose documentation. It’s also possible to do it from the command line with docker network….
    – Huygens
    Jan 1, 2019 at 14:13
  • 1
    I realised that it's because I was trying to use an overlay network instead of a bridge` network. Is there any way to make this work with an overlay network, because the VPN can be running on one host and a container can be on another one connected by the overlay!
    – James
    Apr 14, 2020 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.