Roll Your Own VPN

Everyone has heard the term VPN, but many do not understand why they came about, how they work, or how to set one up.

They are useful for more than just watching country-specific streaming video.

Luckily, Devil is here to bring light to the whole rotten affair.

The Origins of VPN

The concept of a VPN (Virtual Private Network) was introduced by Microsoft in the mid-90s with their PPTP (Peer to Peer Tunneling Protocol). PPTP allows two peers to establish an encrypted connection and exchange data between them. The encrypted connection is therefore the “tunnel”.

An encrypted tunnel between two peers is fairly banal, and similar protocols exist for many different purposes. I’m typing this in an SSH session, which establishes an encrypted tunnel between my local workstation and the VPS that hosts this blog.

Here’s a thought experiment. If instead of just establishing a peer-to-peer tunnel, what if the two peers acted as messengers passing information to and from their respective networks? Well, now you’ve got a VPN!

A VPN allows two isolated networks to communicate directly with each other through an encrypted tunnel. How the tunnel is established and maintained is specific to the protocol, but the concept is the same.

VPN for Commercial Use

If you do remote work for a corporation, you’re likely connected to their central system across a VPN. We will cover cryptography later, but for now please think of encryption and cryptography as a secure way to communicate even when exposed to a hostile environment. This is obviously useful for a corporation, since an unencrypted tunnel could allow a compromise remote machine to access and create trouble in their isolated network.

VPN for Private Use

Even if you don’t use a VPN for work, having access to a VPN is extremely useful for individual users. The primary advantage of VPN is the ability to route ALL traffic to and from your local machine to a known and trusted machine.

Consider this scenario — I bring my laptop to a local coffee shop to do some work. They provide a public Wi-Fi network, which I join. Unknown to me, a shadowy super-coder has compromised their network and is recording all traffic occuring on that network. My machine has no idea that this has occured, it only connects and follows the directions from the network.

If I were to browse the Internet normally, the attacker could execute any number of MITM (Man In The Middle) exploits on me. Perhaps I could have my passwords, address, identify, or documents compromised. Not good!

A VPN solves this.

Let’s consider the alternative — I connect to the compromised network, then before doing anything else, establish a VPN connection to a trusted machine. The VPN connection is set up to route all traffic to and from the machine over that encrypted tunnel. The encryption protocol will not allow any compromised host along the way to modify the data, so if I cannot establish the connection I am given a clue and a red flag. If the attacker allows the connection to be established, he will not be able to determine anything useful from observing it. He will only see encrypted data moving back and forth along it, with no hints about what it may be doing. I can use this tunnel continuously, and it will automatically re-establish itself when the connection is dropped.

It will introduce some latency into my Internet activity, since the traffic has to be routed to and from my trusted machine before finally going to the Internet. But that’s a small price to pay for safety.

3rd Party VPN

The rise of VPNs for personal use has lead to the proliferation of 3rd party VPN providers. They offer many promises and some may actually deliver on them. I will not recommend any particular 3rd party VPN provider, but I will offer some caution.

It’s very common to see VPN providers touting how safe and secure their service is, and they make many claims about how your identity is protected if you use them.

My philosophy is somewhat at odds with the Internet at large. I don’t trust any of them, and will not use a 3rd party VPN.

Do-It-Yourself VPN

No surprise here, I am in favor of building a VPN directly and using it. With the rise of multi-continental VPS services, it’s trivially easy to set up a server with a VPN stack in any country that I want.

I’m fully aware that my activity on the Internet is traceable back to the VPS, but I already believe that 3rd party VPNs carry that same risk. So instead I prefer to control as much of that pipeline as possible.

There are two popular VPN protocols, which I’ll share here:


OpenVPN is the most well-established of the modern VPN protocols. It was developed in 2001, and is the “industry standard” protocol. OpenVPN was audited in April 2017 by 3rd party firms and only minor vulnerabilities were found. The project has been developed since then with no follow-up audits, so I cannot comment on their current vulnerability status.


Wireguard is a recent entry to the space, first developed in 2015. It has been quickly adopted by the industry and accepted into the mainline Linux kernel. Because it is developed primarily for speed and small attack surface, Wireguard is quite performant when compared to OpenVPN. It is also simpler to configure and offers some new features like roaming.

I prefer to use Wireguard since it’s quite simple to set up and very fast.

Setting Up Wireguard on the Server

Open a console and prepare the directories for each service as follows:

devil@linodevm:~$ sudo su -
devil@linodevm:~# mkdir -p /docker/wireguard
devil@linodevm:~# cd /docker/wireguard

Then create a docker-compose.yml file with the following contents using nano or vim:

version: "2"


    image: linuxserver/wireguard:latest
    container_name: wireguard
    restart: unless-stopped
      - NET_ADMIN
      - SYS_MODULE
      - PEERS=client1,client2,client3
      - TZ=America/Los_Angeles
      - config:/config
      - /lib/modules:/lib/modules
      - "51820:51820/udp"


Then bring the container up using docker-compose up and confirm that it runs successfully. If so, kill it with CTRL + c and re-run with docker-compose up -d to detach the container from the shell.

The client keys will be saved inside the wireguard_config volume, which is stored at /var/lib/docker/volumes/wireguard_config/_data.

Setting up Wireguard on the Client

My favorite part about Wireguard is the QR code setup. Client keys are stored in QR format during container creation, which is just a PNG image. You can download this image using WinSCP on Windows or Cyberduck on MacOS.

Download the image from the /var/lib/docker/volumes/wireguard_config/_data/peer_client1/, then save it to your desktop.

Then download the Wireguard app for your phone (Android or AppleOS) and use the camera to read the QR code. This will import the correct settings for your new server and you’ll be set.

Happy VPNing!

What Else Can the VPN Do?

I will cover a few of these in greater depth later, but with your new VPN you can create internal services that are only reachable inside your network. It’s more than just moving your external IP around.