Setting up a VPN Server in 5 Minutes with Docker
A few days ago we ran into the need to set up a new VPN server for our company. A Virtual Private Network (VPN) is a method of remotely connecting a computer to a network over the Internet. This is commonly used for roadwarrior employees accessing the office network, or for system administrators securely maintaining servers on the cloud (a security technique called “Bastion host”).
Previously, we used a VPN server based on the PPTP protocol, which has recently been deprecated by macOS Sierra and iOS 10 (another of those courageous decisions Apple is becoming famous for!), so we needed a new, supported server.
We didn’t want to have to frequently set up VPN servers, so we gave it some thought and came up with the following list of high-level requirements:
- Easy deployment: Most of our servers are Linux. Configurations can take several hours of manual work, installing packages and handcrafting config files. This is error-prone and is difficult to reproduce the procedure.
- Reusability: It may happen in the future that we need to move the service to another server or simply create a new server for a different set of users. We needed a way to replicate this setup easily.
- Easy administration and robustness: Several admins will need to be able to add and remove VPN users without spending too much time tweaking configuration files. Being a complex configuration, a person unfamiliar with the setup could easily break it when doing changes.
- Security: As VPN is a security feature, we needed to make sure vulnerabilities were not introduced when committing changes.
- Runs on an Ubuntu server: It’s the main server technology we use.
- Native support for iOS, Android, macOS and Windows clients: As Mobile Jazz is a web and mobile company, we need to support VPN access for our mobile devices and desktop computers, and avoid installing 3rd party tools if possible.
Docker seemed to be a good solution to satisfy all of our requirements. Using a Docker image allows for a replicable configuration totally independent from the host server. This makes moving the service around and making copies very easy. The configuration also remains in one a single place, making it easy to maintain and audit.
In order to support iOS, Android, macOS and Windows we looked into IPSec Xauth and L2TP protocols. Both of which made the cut, so we needed to use an Xauth or L2TP Docker image.
We scouted the Internet and found this Docker image by Lin Song that nearly fit our requirements. It is well documented and widely used, so it seemed like a good option. The only problem it has is that it’s designed to be used by a single-user and we needed multiple. However, it was a fantastic base to work on; that’s the beauty of open source!
Multi-User VPN Server
We decided to fork the base image and create a multi-user version from it. In the process we also made a couple of changes, making it easier to maintain.
Docker commands tend to get very long (and thus, easy to mess up) and we wanted to simplify maintenance. Along with the Docker image modifications. we also created a set of scripts to interact with it:
- Set up a container based on the image
- Create, list and remove users
- Check the service status
We published the changes in our GitHub repository, so check it out.
How to Setup a VPN Server in Less Than 5 Minutes
If you have a good Internet connection this may take even less! Here’s how in just three commands:
git clone https://github.com/mobilejazz/docker-ipsec-vpn-server.git
This will spin up a dual-protocol IPSec Xauth and L2TP VPN, ready to accept connections. In order to connect you’ll need to make a new user, which can also be easily done via a command:
The following would create a user called “john-ipad” and a password:
So there you have it, a fully-configured VPN in less than 5 minutes! If you want to know more, please check our GitHub repo.
Are you using our image? What are you using it for? Did you make changes to it? If so, leave comments here, we’d love to hear!
If you enjoyed this post, visit our blog for more.