A simple lightweight OpenVPN container for Docker running on Alpine Linux.
1.1K
This container provides the openvpn service coupled with a simple, versatile, and robust firewall that will block all outgoing data except to one vpn provider's address, port and protocol that is taken automatically from your provided client.ovpn file.
The container is configured for out-of-the-box for port-forwarding when used with a capable private internet access server. Other providers can be added by request.
It is based on Alpine Linux, a streamlined distribution tailored for Docker then augmented with s6-overlay to utilize its advanced process management capabilities.
The goal is to start this container first then run another container within the vpn container's network with --net=container:openvpn, or as part of a docker-compose stack with network_mode: service:openvpn.
NOTE: this container has only been tested on linux systems at time of writing.
docker run -d --rm \
--name openvpn \
--cap-add=NET_ADMIN \
--device /dev/net/tun \
--net=vpn_network \
-e LAN=1.2.3.4\24 \
-v path/to/ovpn/config:/config \
-v vpn_port:/var/run/ovpn \
-p 9091:9091 \
pyunramura/openvpn
The parameters are split into two halves, separated by a colon, the left hand side representing the host and the right the container side.
For example with -p external:internal - what this shows is the port mapping from external to internal of the container.
So -p 80:9091 would expose port 9091 from inside the container to be accessible from the host's IP on port 80. http://192.168.x.x:80 would show you what's running INSIDE the container on port 9091.
--dns - needed by the firewall for internet address resolution; see below for explanation-p 9091 - the mapped port for the service(s) you wish to access, in this example transmission-web-v /config - where openvpn will look for its ovpn configuration files at /config/client.ovpn-v vpn_port - a docker volume for the the forwarded port for other containers that access the vpn tunnel-e LAN - the local subnet you will be accessing services from; remote access is untested at time of writingDue to the nature of the ovpn client, this container must be started with some additional privileges. --cap-add=NET_ADMIN makes sure that the tunnel can be created from within the container.
The --device /dev/net/tun command will allow the container access to your host's tunnel adapter. This could be automated, but would require unconfined privileges to your host which is undesirable, and so is intentionally omitted. To check if your host has a tunnel adapter see the note below.
The vpn_port volume is made with docker create volume vpn_port. It is used by the service to announce the forwarded port to other containers behind the vpn tunnel. This is configured for private internet access servers that allow port forwarding; with additional providers planned for future releases. A current list an be found on their client support page under Port Forwarding.
DNS NOTE: In most cases, you will want a DNS server to be specified using --dns <ip-address>. It is recommended to use a secure DNS server that is not from your ISP as it can result in DNS leakage that could expose your identity even behind a vpn tunnel. One recommended option is to use the PIA DNS servers which can be found on their client support page under DNS Leak Protection.
For shell access while the container is running
docker exec -it openvpn /bin/sh
Monitor the logs of the container in realtime
docker logs -f openvpn
For the container version number
docker inspect -f '{{ index .Config.Labels "build_version" }}' openvpn
For the image version number
docker inspect -f '{{ index .Config.Labels "build_version" }}' pyunramura/openvpn
Check if the host machine has a tunnel device with ls /dev/net and you will see tun if a tunnel device exists. If there is no tunnel device, copy the make_tun.sh from my repository root onto your host machine and change into the directory it was copied to and chmod +x make_tun.sh, then ./make_tun.sh to create the device. Verify that it has been given the proper attributes with cat /dev/net/tun. If it has been created successfully it will present a message such as cat: /dev/net/tun: File descriptor in bad state. Now you can run the container with the --device /dev/net/tun option to allow OpenVPN to create the tunnel inside the container.
A container started with --net=container:<vpn> will use the same network stack as the <vpn> container, and will share the same container IP subnet. In addition with docker-compose the command would read network_mode: service:<vpn> to get the same result. A compose file is provided in the git repository for reference.
Since Docker 1.9, it is recommended to use a non-default network allowing containers to address each other by name.
docker network create vpn_network
This creates a network called vpn_network in which containers can address each other by name; the /etc/hosts is updated automatically for each container added to the network.
docker run ... --net=vpn_network --name=openvpn -p 9091:9091 pyunramura/openvpn
Within the vpn_network there is now a resolvable name openvpn that points to that newly created container.
This step is the same as the earlier one
# Create the transmission service that listens on port 9091
docker run ... --net=container:openvpn --name=transmission transmission
This container is not addressable by name outside the vpn_network, but given that the network stack used by transmission is the same as the openvpn container, they have the same IP address outside the docker network. The service running in this container will be accessible at http://openvpn:9091.
If there are errors in docker logs -f openvpn on container start that show failure to create a tunnel, check that the address, port, and protocol are given in the /config/client.ovpn file. For example, you should see:
remote <address> <port> <proto>
or
remote <address>
port <port>
proto <protocol>
or any combination of the above three values.
Additional values for ca, crl-verify, or auth-* will either need to be specified in-line in the file, or referenced by the file. For example:
auth-user-pass <path/to/credentials file>
ca <path/to/ca.crt file>
crl-verify <path/to/crl.pem file>
or
auth-user-pass
<ca>
.............
</ca>
<crl-verify>
.............
</crl-verify>
The structure of these files are highly variable and dependant on how your provider creates them. Make any referenced authentication or kty-files only have read/write permissions for the owner with chmod 600 <files>. For additional information on the ovpn file, consult the OpenVPN Reference Manual.
If you are using private internet access as a provider, and are not able to open a port for forwarding, you will see an error on container start in the Docker logs as shown below. To correct this, connect to one of the port-forwarding providers listed on their client support page under Port Forwarding.
[cont.init.d] [INFO] Port forwarding is already activated on this connection, has expired, or you are not connected to a provider that supports port forwarding'
Otherwise you will see a output in the Docker logs similar to:
[cont.init.d] [INFO] Forwarding {"port":12345}
Content type
Image
Digest
Size
7.3 MB
Last updated
over 7 years ago
docker pull pyunramura/openvpn