mdnsfr / docker-rancher-openvpn

OpenVPN Server with optionnal Rancher specific abilities, with multiple authentication backends
58 stars 32 forks source link

OpenVPN for Rancher with modular authentication

OpenVPN server image made to give access to Rancher network with modular authentication.

This Server doesn't relies on clients certificates, but on credential based authentication

Current version is shipped with following authentication :


How to configure the image

The only mandatory variables are AUTH_METHOD, and method dependant variables.

Each non mandatory environment variable is optionnal and has default value.

Following variables are the answers to common questions during certificate creation process

These variables define the network address and CIDR netmask for the ip pool which will be the VPN subnet for OpenVPN to draw client addresses from

Next two variables are used in client configuration generation process, to indicate OpenVPN clients where to connect to establish the link

If you don't want to expose the full Rancher network, you can set your own network and netmask with following variables:

If you don't want to expose the interunal Rancher metadata api, you can set any value to this variable, it will prevent to add the route to metadata api. Default is to expose the metadata api, in this case this variable is empty.

You can also set your custom search domain and DNS server pushed to VPN clients:

There is also an optionnal variable to let you customize OpenVPN server config, for example to push your own custom route. This variable accept multiple line by adding a simple \n between lines.


How to run this image

You must have to run this image with privileged mode.

Here is the minimal docker run example with httpbasic authentication :

docker run -d --privileged=true -p 1194:1194 \
    -e AUTH_METHOD=httpbasic \
    -e AUTH_HTTPBASIC_URL=https://api.github.com/user \
    mdns/rancher-openvpn

And here is an exhaustive docker run example with ldap authentication :

docker run -d \
    --privileged=true \
    -e REMOTE_IP=1.2.3.4 \
    -e REMOTE_PORT=1194 \
    -e CERT_COUNTRY=FR \
    -e CERT_PROVINCE=PACA \
    -e CERT_CITY=Marseille \
    -e CERT_ORG=MDNS \
    -e CERT_EMAIL=none@example.com \
    -e CERT_OU=IT \
    -e VPNPOOL_NETWORK=10.8.0.0 \
    -e VPNPOOL_CIDR=24 \
    -e OPENVPN_EXTRACONF='# Example of multiline extraconf\npush "10.10.0.0 255.255.0.0"\npush "10.20.0.0 255.255.0.0"'
    -e ROUTE_NETWORK=10.42.103.143 \
    -e ROUTE_NETMASK=255.255.255.255 \
    -e PUSHDNS=169.254.169.250 \
    -e PUSHSEARCH=rancher.internal \
    -e NO_RANCHER_METADATA_API=1 \
    -e AUTH_METHOD=ldap \
    -e AUTH_LDAP_URL=ldap://ldap.acme.tld \
    -e AUTH_LDAP_BASEDN='dc=acme,dc=tld' \
    -e AUTH_LDAP_SEARCH='(uid=$username)' \
    -e AUTH_LDAP_BINDDN='cn=admin,dc=acme,dc=tld' \
    -e AUTH_LDAP_BINDPWD='thisIsTheBindDnPassword' \
    -v /etc/openvpn \
    --name=vpn \
    -p 1194:1194 \
    mdns/rancher-openvpn

Note bene : First launch takes more time because of certificates and private keys generation process


Authentication methods

HTTP Basic

Authentication is made by trying to connect to a HTTP Server with credentials in Basic HTTP Auth mechanism.

Each variable is mandatory :

You can test authentication against the GitHub api server :

docker run -d --privileged=true -p 1194:1194 \
    -e AUTH_METHOD=httpbasic \
    -e AUTH_HTTPBASIC_URL=https://api.github.com/user \
    mdns/rancher-openvpn

Warning ! If you use GitHub api url in production, anyone who has a github account will be able to connect your VPN !!

HTTP Digest

Authentication is made by trying to connect to a HTTP Server with credentials in Digest HTTP Auth mechanism.

Each variable is mandatory :

You can test authentication against the httpbin sandbox server :

docker run -d --privileged=true -p 1194:1194 \
    -e AUTH_METHOD=httpdigest \
    -e AUTH_HTTPDIGEST_URL=https://httpbin.org/digest-auth/auth/myuser/mypwd \
    mdns/rancher-openvpn

LDAP

Authentication is made by trying to connect a ldap server with client credentials

These are mandatory variable to setup ldap authentication :

If your ldap server need to be authenticated to search directory, you can use optionnals binding variables:

You can test ldap authentication with osixia/openldap ldap docker image, with login "admin" :

docker run -d --name=ldap -e LDAP_ORGANISATION="ACME" -e LDAP_DOMAIN="acme.tld" -e LDAP_ADMIN_PASSWORD="mypwd" osixia/openldap:1.1.1
docker run -d --privileged=true -p 1194:1194 --link ldap:ldapsrv \
    -e AUTH_METHOD=ldap \
    -e AUTH_LDAP_URL=ldap://ldapsrv \
    -e AUTH_LDAP_BASEDN='dc=acme,dc=com' \
    -e AUTH_LDAP_SEARCH='(uid=$username)' \
    -e AUTH_LDAP_BINDDN='cn=admin,dc=acme,dc=tld' \
    -e AUTH_LDAP_BINDPWD='mypwd' \
    mdns/rancher-openvpn

Rancher Server in local mode

Authentication is made by trying to connect to a Rancher Server configured in local mode.

Each variable is mandatory :

You can test authentication against the Rancher api server :

docker run -d --privileged=true -p 1194:1194 \
    -e AUTH_METHOD=rancherlocal \
    -e AUTH_RANCHERLOCAL_URL=https://rancher.example.com/v1/token \
    mdns/rancher-openvpn

Client configuration

The client configuration is printed at dock start on stdout, but you can also retrieve it through the "vpn_get_client_config.sh" script.

docker exec -it vpn bash
root@35972bb51cc9:/# vpn_get_client_config.sh
remote $REMOTE_IP $REMOTE_PORT
client
dev tun
proto tcp
remote-random
resolv-retry infinite
cipher AES-128-CBC
auth SHA1
nobind
link-mtu 1500
persist-key
persist-tun
comp-lzo
verb 3
auth-user-pass
auth-retry interact
ns-cert-type server
<ca>
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIJALhlg01BvAIvMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
...
[Your generated OpenVPN CA certificate]
...
X0yOqF6doV0+DPt5T+vEeu9oiczscg==
-----END CERTIFICATE-----
</ca>

Save this configuration in your ".ovpn" file, don't forget to replace IPADDRESS and PORT with your server ip and the exposed port to reach OpenVPN server

Here is an example of a final client.ovpn :

remote 5.6.7.8 1194
client
dev tun
proto tcp
remote-random
resolv-retry infinite
cipher AES-128-CBC
auth SHA1
nobind
link-mtu 1500
persist-key
persist-tun
comp-lzo
verb 3
auth-user-pass
auth-retry interact
ns-cert-type server
<ca>
-----BEGIN CERTIFICATE-----
MIIEkjCCA3qgAwIBAgIJALhlg01BvAIvMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
...
[Your generated OpenVPN CA certificate]
...
X0yOqF6doV0+DPt5T+vEeu9oiczscg==
-----END CERTIFICATE-----
</ca>

Volumes and data conservation

Everything is stored in /etc/openvpn.