Some days ago I deployed a service on my Kubernetes cluster, but I didn't want the service to be publicly available. So I thought about protecting the service behind a VPN. That is an easy and common way to secure such applications. And I also wanted to access this service via a TLD domain, because nobody wants to memorize IP addresses. And because my brain can't stand websites running without SSL encryption, I had to use HTTPS for this local service. To my surprise, I couldn't find a single write up related to this topic. That is why I wanted to share how I managed to secure applications behind a VPN that still run within my Kubernetes cluster and how I made these apps accessible via HTTPS.
Requirements
K8s Cluster
TLD Domain
DNS provider capable of DNS challenges (e.g. Cloudflare)
VPN (I bought a VPS from IONOS for 1€/month and installed Wireguard on it)
VPN Installation
This is very easy, because there are already open source scripts for exactly this purpose. I used this one and just left most settings default. As always: Never run a script blindly on your server. Take a look at it and understand what it actually does.
Deploying the K8s Application
I am going to create a deployment with the application and a VPN sidecar container. And because configmaps are always read only and the VPN clients needs write permissions for the Wireguard config file, I used an initContainer to create the Wireguard configuration.
That is it for securing your application behind a VPN. You don't even need a service, because your are not going to use the internal cluster network. Simply connect to the VPN and enter the address (in my case http://10.7.0.2:8080) in the browser bar. You should see the homepage of your application now.
Running the App via HTTPS
OK. So far so good. Only the HTTPS domain is still missing. First of all we will need a reverse proxy. I used Caddyserver because it is just simple and I love it. Unfortunately I couldn't use the base image, because we are going to make Cloudflare DNS challenges and therefore we need to have the Cloudflare DNS plugin installed. I stuck to this image for now. But I will create my own image in future, so that I don't have to rely on images from third parties. Now I just need to add this reverse proxy to the VPN network. Same deployment file as before, only with the reverse proxy instead of the application.
The Caddyfile.
And finally the DNS records.
That is all. You should now be ready to go. The service should be accessible via your domain but still secured behind a VPN.