A minimal Alpine Linux based Docker container with OpenVPN and s6 as a process supervisor.
All traffic from within the container to the Internet is forced through a VPN
tunnel by iptables
rules and the container is configured to terminate in case
the VPN connection drops.
An alternative DNS server should be used to prevent DNS leaks. Use the DNS servers provided by the VPN provider or choose an alternative from the list that WikiLeaks has compiled.
Two configuration files are required by OpenVPN. VPN providers usually have
already made configuration files that can be used as is as the first file,
named config.ovpn
. The second file, named login.conf
, is used as a value
for auth-user-pass
parameter and it must contain username on the first line
and password on the second line. For more information on how to configure
OpenVPN see the official documentation at the website.
NETMON_INTERVAL
environment variable defines the interval in seconds between
connection checks. If left undefined a default value of 60 seconds will be used.
Environment variables can be passed using -e NETMON_INTERVAL=120
syntax.
The container requires a couple of mount points to work, which are listed below.
Host directories and files can be mounted using -v /host/path:/docker/path
commandline argument.
The container requires that the following files are mounted from the host.
/mnt/
openvpn/
config.ovpn
login.conf
OpenVPN process is configured to log its stdout
and stderr
into the files
listed below. To persist logs mount a directory as /var/log/
or a file as
a single log file.
/var/log/
netmon/
stdout.log
openvpn/
stderr.log
stdout.log
To use this container on a host that has SELinux enabled use the provided
s6-openvpn.te
policy module or create your own if it doesn't work. To
compile and install the policy module run the following commands.
$ checkmodule -M -m s6-openvpn.te -o /tmp/s6-openvpn.mod
$ semodule_package -m /tmp/s6-openvpn.mod -o /tmp/s6-openvpn.pp
# semodule -i /tmp/s6-openvpn.pp
In addition to installing the module, the volumes must be mounted using the
:Z
mount option so that Docker will relabel the volumes with a correct
security label.
To run the container interactively execute the following command. Modify the parameters to fit your environment.
# docker run -it --rm \
--cap-add=NET_ADMIN --device=/dev/net/tun \
--dns=8.8.8.8 --dns=8.8.4.4 \
--volume ~/.config/openvpn:/mnt/openvpn:Z \
scoobadog/s6-openvpn:latest
A reliable way to start the container at boot time and restart it, if something
goes wrong and the container shuts down, is to let systemd to manage the
container. Use the following code snippet as a template, modify the parameters
to fit your environment and save it as
/usr/lib/systemd/system/s6-openvpn.service
.
[Unit]
Description=s6-openvpn
After=docker.service
Requires=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker run \
--cap-add=NET_ADMIN --device=/dev/net/tun \
--dns=8.8.8.8 --dns=8.8.4.4 \
--volume ~/.config/openvpn:/mnt/openvpn:Z \
--name openvpn scoobadog/s6-openvpn:latest
ExecStop=/usr/bin/docker stop -t 10 openvpn
ExecStopPost=/usr/bin/docker rm -f openvpn
[Install]
WantedBy=multi-user.target
To enable and start the service run the following commands.
# systemctl enable s6-openvpn
# systemctl start s6-openvpn
This project is licensed under the MIT License.