OpenVPN Server on Docker Swarm
This How-To will show you how to launch an OpenVPN server in Docker Swarm, running in dual (TCP/UDP) mode. It will use swarm-launcher to start the processes in privileged
mode and Nginx as a loadbalancer/proxy for allowing connections to the VPN server.
Rationale
If you ever tried running a privileged container in docker swarm, you might have noticed that it’s currently not possible use --cap-add
, --cap-drop
or --privileged
with docker stack deploy
. Here is a workaround for that.
I’ll be using in this example the following docker images:
- registry.gitlab.com/ix.ai/openvpn:latest - OpenVPN server in a Docker container complete with an EasyRSA PKI CA
- registry.gitlab.com/ix.ai/swarm-launcher:latest - A docker image to allow the launch of container in docker swarm, with options normally unavailable to swarm mode
- nginx:latest - an open source reverse proxy server for HTTP, HTTPS, SMTP, POP3, and IMAP protocols, as well as a load balancer, HTTP cache, and a web server (origin server)
Objectives
The objective is to have a fully functional OpenVPN server, that you can connect to, running on docker swarm. I’ll be using ports 1194/udp
and 8443/tcp
in this example.
Note: All the commands below need to be run on a swarm manager. You can see your manager nodes by running: sudo docker node ls -f role=manager
.
Prerequisites
- Have a fully functional docker swarm
- Have a public IP address that points is configured on the swarm
- (optional) Have a DNS entry that points at the IP address
Architectures Supported
linux/amd64
linux/arm64
linux/arm/v7
linux/arm/v6
OpenVPN
Getting the OpenVPN server up and running requires a few manual steps before deploying it. Make sure you read the documentation if you run into any problems.
Storage
OpenVPN needs a storage for the configuration and certificates. Ideally, you have a secure distributed storage available in your swarm (like NFS or CEPH). For this tutorial, I will assume that it is mounted under /var/docker/openvpn
.
Run the following on one of your swarm
export OVPN_DATA="/var/docker/openvpn"
Initialise the Configuration
If you have a domain name, make sure to replace it below. If not, you can use the public IP address
export ENDPOINT="VPN.EXAMPLE.COM"
Generate the Configuration
sudo docker run -v "${OVPN_DATA}":/etc/openvpn --log-driver=none --rm registry.gitlab.com/ix.ai/openvpn ovpn_genconfig -u udp://"${ENDPOINT}" -b
Click to see output example
Unable to find image 'registry.gitlab.com/ix.ai/openvpn:latest' locally
latest: Pulling from registry.gitlab.com/ix.ai/openvpn
8fa90b21c985: Already exists
a6e1cf67f1ae: Pull complete
29c596d05c0e: Pull complete
3c36e8be4cab: Pull complete
748c329393a2: Pull complete
Digest: sha256:c7eb026fad0d1b7f9d299d5375b025c3f84451782fc31e6baeed8bf171c17efc
Status: Downloaded newer image for registry.gitlab.com/ix.ai/openvpn:latest
Disable default setenv opt for 'block-outside-dns'
Processing Route Config: '192.168.254.0/24'
Processing PUSH Config: 'dhcp-option DNS 1.1.1.1'
Processing PUSH Config: 'dhcp-option DNS 1.0.0.1'
Processing PUSH Config: 'comp-lzo no'
Successfully generated config
Cleaning up before Exit ...
This will effectively set the default client configuration to use the port 1194/udp
. Take a look at docs/tcp.md for information on TCP.
Initialise the PKI
sudo docker run -v "${OVPN_DATA}":/etc/openvpn --log-driver=none --rm -it registry.gitlab.com/ix.ai/openvpn ovpn_initpki
You will need to choose a password (using the nopass
option is not secure). You can also set a name for the PKI, or just use the default one.
The command will take some time, since it generates Diffie-Hellman parameters.
Click to see output example
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/pki
1+0 records in
1+0 records out
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
Generating RSA private key, 2048 bit long modulus (2 primes)
....................................................................................................+++++
....+++++
e is 65537 (0x010001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/etc/openvpn/pki/ca.crt
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
...........................................................................................................................................................................................................................................................................................................................................................+............................................................................................................................................................+.......................................+............................................................................+.......................................................................................................................................................................................................+..........................................................................+.............................................................................................................................+....................+........................................................................+...+................................................................+...........................................................................................+..................................................................................................................+........................................................................................................+...............................+.......+....................................+..+...................+...................................................................................................................+.................................................................+..........................+......................+..................................................................................................................................................................................+....+..........+...................................................+....................................................................................+...............................................+.............................................................................................+...............................................................................................................................+.......+................................+.................................................+..................................................................................+.............................................................+......................................................................................................+......................................+..............+...+...........................................+.............................................................................+......................................................................................................................+........................................................................................................................................................................+..................+..............................................................................................................................................................................................................................................................+............................+...........+..........................................................++*++*++*++*
DH parameters of size 2048 created at /etc/openvpn/pki/dh.pem
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Generating a RSA private key
.+++++
...........................................................................................................................+++++
writing new private key to '/etc/openvpn/pki/private/VPN.EXAMPLE.COM.key.XXXXAEGCfL'
-----
Using configuration from /etc/openvpn/pki/safessl-easyrsa.cnf
Enter pass phrase for /etc/openvpn/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :ASN.1 12:'VPN.EXAMPLE.COM'
Certificate is to be certified until Feb 7 08:06:49 2023 GMT (1080 days)
Write out database with 1 new entries
Data Base Updated
Using SSL: openssl OpenSSL 1.1.1d 10 Sep 2019
Using configuration from /etc/openvpn/pki/safessl-easyrsa.cnf
Enter pass phrase for /etc/openvpn/pki/private/ca.key:
An updated CRL has been created.
CRL file: /etc/openvpn/pki/crl.pem
Nginx
Nginx needs a configuration file (nginx.conf
). We’ll be using docker config
to store it in the swarm.
error_log /dev/stdout info;
events {}
http {}
stream {
resolver 127.0.0.11 valid=1s ipv6=off;
map $remote_addr $backend_udp {
default vpn_vpn-udp_1; # Set this to ${LAUNCH_PROJECT_NAME}_${LAUNCH_SERVICE_NAME}_1 or to ${LAUNCH_CONTAINER_NAME}
}
map $remote_addr $backend_tcp {
default vpn_vpn-tcp_1; # Set this to ${LAUNCH_PROJECT_NAME}_${LAUNCH_SERVICE_NAME}_1 or to ${LAUNCH_CONTAINER_NAME}
}
server {
listen 1194 udp;
proxy_pass $backend_udp:1194;
}
server {
listen 8443;
proxy_pass $backend_tcp:1194;
}
}
Make sure this file is on the swarm manager and is called nginx.conf
.
Create the Config
sudo docker config create nginx.conf.v1 nginx.conf
You can see that it’s been created by running:
docker config ls
ID NAME CREATED UPDATED
8tx79ul78nwtjvb47xjm4qu7a nginx.conf.v1 14 seconds ago 14 seconds ago
You’ll notice that I’ve added .v1
to the config name. This will allow you to update later on the config and just point nginx to the new one.
Docker Stack
Luckily, the swarm-launcher doesn’t need any additional configuration, so we can now create and deploy the stack.
Create the Stack YML File
On a swarm manager, create stack.yml
with the following content:
version: "3.7"
services:
vpn-launcher-udp:
deploy:
labels:
ai.ix.auto-update: 'true'
image: registry.gitlab.com/ix.ai/swarm-launcher:latest
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:rw'
environment:
LAUNCH_IMAGE: registry.gitlab.com/ix.ai/openvpn:latest
LAUNCH_PULL: 'true'
LAUNCH_EXT_NETWORKS: 'vpn_vpn-proxy' # Set this to NameOfStack_NameOfNetwork
LAUNCH_PROJECT_NAME: 'vpn'
LAUNCH_SERVICE_NAME: 'vpn-udp'
LAUNCH_CAP_ADD: 'NET_ADMIN'
LAUNCH_PRIVILEGED: 'true'
LAUNCH_ENVIRONMENTS: 'OVPN_NATDEVICE=eth1'
LAUNCH_VOLUMES: '/var/docker/openvpn:/etc/openvpn:rw'
vpn-launcher-tcp:
deploy:
labels:
ai.ix.auto-update: 'true'
image: registry.gitlab.com/ix.ai/swarm-launcher:latest
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:rw'
environment:
LAUNCH_IMAGE: registry.gitlab.com/ix.ai/openvpn:latest
LAUNCH_PULL: 'true'
LAUNCH_EXT_NETWORKS: 'vpn_vpn-proxy' # Set this to NameOfStack_NameOfNetwork
LAUNCH_PROJECT_NAME: 'vpn'
LAUNCH_SERVICE_NAME: 'vpn-tcp'
LAUNCH_CAP_ADD: 'NET_ADMIN'
LAUNCH_PRIVILEGED: 'true'
LAUNCH_ENVIRONMENTS: 'OVPN_NATDEVICE=eth1'
LAUNCH_VOLUMES: '/var/docker/openvpn:/etc/openvpn:rw'
LAUNCH_COMMAND: 'ovpn_run --proto tcp'
nginx-proxy:
deploy:
labels:
ai.ix.auto-update: 'true'
image: nginx:latest
networks:
- vpn-proxy
configs:
- source: nginx.conf.v1
target: /etc/nginx/nginx.conf
ports:
- '1194:1194/udp'
- '8443:8443'
configs:
nginx.conf.v1:
external: true
networks:
vpn-proxy:
attachable: true
driver: overlay
driver_opts:
encrypted: 'true'
Note: You’ll notice the label ai.ix.auto-update: 'true'
. I use this with registry.gitlab.com/ix.ai/cioban, to automatically update swarm services to the latest version of the docker image. You can leave it out, if you don’t use it.
WARNING: If you decide not to use the name vpn
for the stack, but something else (say beldeneige
), you must change the variable LAUNCH_EXT_NETWORKS
to match it (e.g. beldeneige_vpn-proxy
).
Deploy the Stack
sudo docker stack deploy --compose-file stack.yml --prune vpn
That’s it. You should soon see the services running:
sudo docker service ls -f name=vpn
ID NAME MODE REPLICAS IMAGE PORTS
fp8qyz2divix vpn_nginx-proxy replicated 1/1 nginx:latest *:8443->8443/tcp, *:1194->1194/udp
7aix7z5mrtnk vpn_vpn-launcher-tcp replicated 1/1 registry.gitlab.com/ix.ai/swarm-launcher:latest
xk14lwmvwbw7 vpn_vpn-launcher-udp replicated 1/1 registry.gitlab.com/ix.ai/swarm-launcher:latest
You can also look on which node registry.gitlab.com/ix.ai/swarm-launcher was started:
sudo docker service ps vpn_vpn-launcher-tcp
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
q02qnd9c9q1o vpn_vpn-launcher-tcp.1 registry.gitlab.com/ix.ai/swarm-launcher:latest docker-c Running Running 3 hours ago
1fziscmqskxn \_ vpn_vpn-launcher-tcp.1 registry.gitlab.com/ix.ai/swarm-launcher:latest docker-a Shutdown Shutdown 3 hours ago
Finally, you can look at all containers started by registry.gitlab.com/ix.ai/swarm-launcher locally:
sudo docker ps -f label=ai.ix.started-by=ix.ai/swarm-launcher
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e7e31a40dc79 registry.gitlab.com/ix.ai/openvpn:latest "ovpn_run --proto tcp" 3 hours ago Up 3 hours 1194/udp vpn_vpn-tcp_1
ab39ac215297 gitlab/gitlab-runner:alpine "/usr/bin/dumb-init …" 4 days ago Up 4 days gitlab-ci-runner
(Yes, I start my GitLab Runner also with registry.gitlab.com/ix.ai/swarm-launcher)
Troubleshooting
All the logs of registry.gitlab.com/ix.ai/swarm-launcher and of the registry.gitlab.com/ix.ai/openvpn container are available in the docker service. In our case, we can run:
sudo docker service logs vpn_vpn-launcher-tcp
Click to see output example
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | swarm-launcher: Doing startup check
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | swarm-launcher: Testing compose file
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | networks:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn_vpn-proxy:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | external: true
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | name: vpn_vpn-proxy
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | services:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | cap_add:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | - NET_ADMIN
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | command: ovpn_run --proto tcp
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | environment:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | OVPN_NATDEVICE: eth1
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | image: registry.gitlab.com/ix.ai/openvpn:latest
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | labels:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | ai.ix.started-by: ix.ai/swarm-launcher
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | networks:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn_vpn-proxy: null
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | privileged: true
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | restart: "no"
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | volumes:
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | - /var/storage/docker/openvpn:/etc/openvpn:rw
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | version: '3.7'
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a |
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | swarm-launcher: Pulling registry.gitlab.com/ix.ai/openvpn:latest
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | latest: Pulling from registry.gitlab.com/ix.ai/openvpn
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | c9b1b535fdd9: Already exists
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 83a8a9aaf865: Pulling fs layer
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 4ae626e5972b: Pulling fs layer
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 2dd917a98926: Pulling fs layer
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 190cce0f75ce: Pulling fs layer
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 190cce0f75ce: Waiting
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 4ae626e5972b: Verifying Checksum
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 4ae626e5972b: Download complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 2dd917a98926: Verifying Checksum
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 2dd917a98926: Download complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 83a8a9aaf865: Download complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 190cce0f75ce: Verifying Checksum
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 190cce0f75ce: Download complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 83a8a9aaf865: Pull complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 4ae626e5972b: Pull complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 2dd917a98926: Pull complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | 190cce0f75ce: Pull complete
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | Digest: sha256:c7eb026fad0d1b7f9d299d5375b025c3f84451782fc31e6baeed8bf171c17efc
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | Status: Downloaded newer image for registry.gitlab.com/ix.ai/openvpn:latest
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | ------------------------------------------------------
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | The Docker Engine you're using is running in swarm mode.
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a |
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a |
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | To deploy your application across the swarm, use `docker stack deploy`.
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a |
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | Creating vpn_vpn-tcp_1 ...
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | Attaching to vpn_vpn-tcp_1
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | iptables: No chain/target/match by that name.
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | iptables: No chain/target/match by that name.
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Enabling IPv6 Forwarding
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | net.ipv6.conf.all.disable_ipv6 = 0
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | net.ipv6.conf.default.forwarding = 1
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | net.ipv6.conf.all.forwarding = 1
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Running 'openvpn --config /etc/openvpn/openvpn.conf --client-config-dir /etc/openvpn/ccd --crl-verify /etc/openvpn/crl.pem --proto tcp'
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Unrecognized option or missing or extra parameter(s) in /etc/openvpn/openvpn.conf:27: block-outside-dns (2.4.8)
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 OpenVPN 2.4.8 x86_64-alpine-linux-musl [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] built on Feb 7 2020
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 library versions: OpenSSL 1.1.1d 10 Sep 2019, LZO 2.10
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Diffie-Hellman initialized with 2048 bit key
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Failed to extract curve from certificate (UNDEF), using secp384r1 instead.
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 ECDH curve secp384r1 added
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Outgoing Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Outgoing Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Incoming Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Incoming Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 ROUTE_GATEWAY 172.18.0.1/255.255.0.0 IFACE=eth1 HWADDR=02:42:ac:12:00:1f
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 TUN/TAP device tun0 opened
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 TUN/TAP TX queue length set to 100
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 /sbin/ip link set dev tun0 up mtu 1500
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 /sbin/ip addr add dev tun0 local 192.168.255.1 peer 192.168.255.2
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 /sbin/ip route add 192.168.254.0/24 via 192.168.255.2
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 /sbin/ip route add 192.168.255.0/24 via 192.168.255.2
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Could not determine IPv4/IPv6 protocol. Using AF_INET
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Socket Buffers: R=[131072->131072] S=[16384->16384]
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Listening for incoming TCP connection on [AF_INET][undef]:1194
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 TCPv4_SERVER link local (bound): [AF_INET][undef]:1194
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 TCPv4_SERVER link remote: [AF_UNSPEC]
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 GID set to nogroup
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 UID set to nobody
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 MULTI: multi_init called, r=256 v=256
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 IFCONFIG POOL: base=192.168.255.4 size=62, ipv6=0
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 MULTI: TCP INIT maxclients=1024 maxevents=1028
vpn_vpn-launcher-tcp.1.9jjzfgjlelpo@docker-a | vpn-tcp_1 | Sun Feb 23 09:58:30 2020 Initialization Sequence Completed
Next Steps
Take a look at the OpenVPN README and Advanced Client Management documentation.
You can start by creating the configuration for your VPN clients:
sudo docker run -v "${OVPN_DATA}":/etc/openvpn --log-driver=none --rm -it registry.gitlab.com/ix.ai/openvpn easyrsa build-client-full CLIENTNAME nopass
You then can save the configuration:
sudo docker run -v "${OVPN_DATA}":/etc/openvpn --log-driver=none --rm registry.gitlab.com/ix.ai/openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn
Updates
This article was updated on:
- 2020-11-01: Change the docker images from docker hub (
ixdotai/[...]
) toregistry.gitlab.com/ix.ai/[...]