OpenVPN server and REST management interface package for DC/OS.
Please note: This is a DC/OS Community package, which is not formally tested or supported by Mesosphere.
Issues and PRs are welcome.
- Inherits OpenVPN in Docker from https://hub.docker.com/r/kylemanna/openvpn
- Automatically configures PKI, certificates and runs OpenVPN without user interaction
- Provides a REST interface for adding, revoking users and accessing their credentials for use with a suitable client
- Exposes endpoints for OpenVPN - 1194/UDP, REST interface - 5000/TCP
- The REST interface uses Flask-BasicAuth and defined environment variables ovpn_username & ovpn_password which must be defined before installation
- TLS is enabled by default on the REST interface - currently using the self signed OpenVPN certificate
- The Zookeeper znode
/openvpn
has ACLs enabled, to protect the OpenVPN server and client credentials - Synchronisation of assets between the container and Zookeeper in case the container is restarted
- Clients revoked through the REST interface are correctly revoked from OpenVPN
- Merged the previously separate openvpn server & openvpn-admin 0.0.0-0.1 packages into one. The openvpn-admin package is no longer required.
You must configure the OVPN_USERNAME & OVPN_PASSWORD environment variables before installation These are required for both the REST interface credentials and for the Zookeeper znode ACL.
- From the DC/OS Dashboard > Universe > Packages > enter openvpn in the search box
- Select Install Package > Advanced Installation and scroll down
- Configure both the OVPN_USERNAME & OVPN_PASSWORD
- Select Review and Install > Install
- The service is installed and initialises, when complete, it'll be marked as Running and Healthy
- See Troubleshooting for any issues, otherwise go to Usage
- Clone this repository locally and amend marathon.json to configure the ovpn_username & ovpn_password environment variables
- Add the task to Marathon using the DC/OS CLI
dcos marathon app add marathon.json
The task can be also be added as a package to a local Universe repository
- Clone https://github.com/mesosphere/universe
- Read https://docs.mesosphere.com/1.9/administering-clusters/deploying-a-local-dcos-universe/
- Read and amend the source of local_universe_setup.sh to facilitate building and publishing
The exact endpoints can be confirmed from DC/OS Dashboard > Services > OpenVPN > > Details
- OpenVPN is presented on 1194/UDP and any OpenVPN client will default to this port
- The REST management interface is available on 5000/TCP and will be accessed at https://:5000
- /status /test /client are all valid REST endpoints. /status does not require authentication as it is used for health checks
- Authenticate and POST to the REST endpoint, the new user's credentials will be output to the POST body
curl -k -u username:password -X POST -d "name=richard" https://<IP>:5000/client
- Copy the entire ouput and save to a single file - you may need to amend the target server IP if on an internal network
- Save the file as dcos.ovpn and add to any suitable OpenVPN client, like Tunnelblick for macOS for example
- Test connecting with the OpenVPN client. See Troubleshooting for help.
- The new client credentials will be backed up to Zookeeper for persistence in case the task is killed, and will be copied back as required
- Using the same client endpoint, append the name of the user you wish to revoke
curl -k -u username:password -X DELETE https://<IP>:5000/client/richard
- The client is correctly revoked from OpenVPN and the assets are removed from the container and Zookeeper
During installation, an ACL is set on the Zookeeper openvpn znode, restricting access based on the OVPN_USERNAME & OVPN_PASSWWORD credentials. In order to remove the znode data you must either authenticate with those same credentials or as the Zookeeper super user.
Some examples of how to achieve this using zk-shell which is shipped in the Docker image:
zk-shell connect master.mesos:2181
(CONNECTED) / add_auth digest <username>:<password>
(CONNECTED) / rmr openvpn/
(CONNECTED) / exit
If you intend to change the OVPN_USERNAME & OVPN_PASSWORD, you will need to change the ACL on the existing znode, then reinstall the package with new credentials
zk-shell connect master.mesos:2181
(CONNECTED) / add_auth digest <username>:<password>
(CONNECTED) / set_acl /openvpn world:anyone:cdrwa
(CONNECTED) / exit
If you wish to remove the znode entirely, you will need to authenticate with the Zookeeper super user credentials
zk-shell connect master.mesos:2181
(CONNECTED) / add_auth digest <super>:<password>
(CONNECTED) / rmr /openvpn
(CONNECTED) / exit
Inherits the OpenVPN image from https://hub.docker.com/r/kylemanna/openvpn with a shell script to auto-configure OpenVPN without prompts, execute the OpenVPN daemon and launch the REST interface.
bin/run.sh, dcos_openvpn/web.py & dcos_openvpn/cert.py provide the main functionality.
Python Flask provides the web microframework.
zk-shell https://github.com/rgs1/zk_shell is used to interact with Zookeeper. In order to enable ACLs and use it programmatically, required creative use of their stdin option. This is wrapped in the run_command function in run.sh.
zkshrun.sh is a little standalone helper script that provides run_command to the cert.py.
A modified version of easyrsa is shipped which removes user prompts.
- run.sh checks for existing assets in Zookeeper and copies them to the container if they exist, otherwise initpki and genconfig are run
- Launchs the OpenVPN daemon in daemon mode
- Starts the Python REST interface
- Review stdout and stderr from the task's logs under the DC/OS Dashboard > Service > openvpn > running task > logs
- If the task is running on DC/OS, find out which agent is running the service using the DC/OS cli
dcos task | grep openvpn
- SSH to that agent and get a shell on the running container
docker ps
docker exec -it <Container ID> /bin/bash
- /dcos is the working directory,
ps
should show both the openvpn daemon and the REST interface running - /dcos/bin/run.sh has a number of useful functions for resetting and reconfiguring the container, review the source
- If you kill openvpn process, relaunch it manually and pass --log-append /var/log/openvpn.log you can then review connectivity issues
If you wish to debug further, building the Docker image from the Dockerfile and amending bin/run.sh
as follows allows you disable services for testing
function run_server {
source /dcos/bin/envs.sh
check_status
setup
#ovpn_run --daemon
ovpn_run
#/usr/bin/python -m dcos_openvpn.main
}
Zookeeper Super User credentials must be configured on deployment of DC/OS to allow you to delete the root openvpn znode. Setting ZK credentials is recommended as part of DC/OS hardening.
- Get defined host ports working in the marathon.json - works in the Universe marathon template
- The patch for zk-shell rgs1/zk_shell#82 as managed in run.bash around line 100 needs removing when zk-shell is fixed
- Update the /status endpoint for ovpn_status output and tie into a healthcheck
- run.sh usage and tidying
- Update for DC/OS 1.10 and file based secrets
- Either extend zk-shell to add auth to its params or replace with Kazoo code
- Replace the location function which calls out to ifconfig.me as it's of no use for internal networks