OpenVPN on a Kubernetes cluster. Roll your own secure VPN cluster!
OpenVPN on a Kubernetes cluster. This implementation of OpenVPN simply let’s you create your own secure VPN service on a cluster running on some cloud provider (this is tested on Google Cloud Platform). Other kuberized OpenVPN solutions right now aim to provide direct access to services inside the clister itself, but this is not the aim of k8s-openvpn.
k8s-openvpn relies on excellent existing Docker implementations of OpenVPN and turns it into a reliable, scalable, and easy-to-deploy Kubernetes Deployment. It runs in a separate Namespace to isolate it from the rest of the cluster, and uses Secrets and ConfigMaps instead of Persistent Volumes to store configuration and PKI.
With Kubernetes OpenVPN you can roll your own secure VPN service with the ability to easily deploy multiple configurations and authorise friends and family too!
Note that we’ve chosen NodePort 31304 here. You can run shuf -i 30000-32767 -n 1
to get a random port number in the Kubernetes NodePort range if for some reason you need to use a different port number. Don’t forget to update the respective port fields in the commands and configurations.
Initialise the configuration files and ECC certificates
$ mkdir ovpn0 && cd ovpn0
# Modify the crypto algos to your liking and see documentation here
# https://github.com/kylemanna/docker-openvpn/blob/master/docs/paranoid.md
$ docker run --net=none --rm -it -v $PWD:/etc/openvpn kylemanna/openvpn ovpn_genconfig \
-u udp://VPN.SERVERNAME.COM:31304 \
-C 'AES-256-GCM' -a 'SHA384' -T 'TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384' \
-b -n 185.121.177.177 -n 185.121.177.53 -n 87.98.175.85
$ docker run -e EASYRSA_ALGO=ec -e EASYRSA_CURVE=secp384r1 \
--net=none --rm -it -v $PWD:/etc/openvpn kylemanna/openvpn ovpn_initpki
$ docker run --net=none --rm -it -v $PWD:/etc/openvpn kylemanna/openvpn ovpn_copy_server_files
$ export CLIENTNAME="your_client_name"
$ docker run -e EASYRSA_ALGO=ec -e EASYRSA_CURVE=secp384r1 \
--net=none --rm -it -v $PWD:/etc/openvpn kylemanna/openvpn easyrsa build-client-full $CLIENTNAME
$ docker run --net=none --rm -v $PWD:/etc/openvpn kylemanna/openvpn ovpn_getclient $CLIENTNAME > $CLIENTNAME.ovpn
$ export CLIENTNAME="your_client_name"
$ docker run --net=none --rm -it -v $PWD:/etc/openvpn kylemanna/openvpn easyrsa build-client-full $CLIENTNAME
$ docker run --net=none --rm -v $PWD:/etc/openvpn kylemanna/openvpn ovpn_getclient $CLIENTNAME > $CLIENTNAME.ovpn
$ kubectl apply -f ../00-namespace.yaml
$ kubectl config set-context $(kubectl config current-context) --namespace=ovpn
# Validate it
$ kubectl config view | grep namespace:
$ sudo chown -R $USER:$USER server/*
$ kubectl create secret generic ovpn0-key --from-file=server/pki/private/VPN.SERVERNAME.COM.key
$ kubectl create secret generic ovpn0-cert --from-file=server/pki/issued/VPN.SERVERNAME.COM.crt
$ kubectl create secret generic ovpn0-pki \
--from-file=server/pki/ca.crt --from-file=server/pki/dh.pem --from-file=server/pki/ta.key
$ kubectl create configmap ovpn0-conf --from-file=server/
$ kubectl create configmap ccd0 --from-file=server/ccd
$ kubectl apply -f ../ovpn0-Deployment.yaml
$ gcloud compute firewall-rules create ovpn0 --allow=udp:31304
# Optional: specify the target instances instead of opening port for whole network
$ gcloud compute firewall-rules create ovpn0 --allow=udp:31304 --target-tags <your_cluster>-minion
Thanks to suda this is available as a Helm chart.
--tls-crypt
option in ovpn_genconfig
of the Docker image.This project relies on the very comprehensive kylemanna/docker-openvpn image.