Setting up your own private VPN

Key Takeaways:

  • Create a VPS (virtual private server) using your preferred provider.
  • Use the open source Wireguard VPN - an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances.
  • Connect your device and enjoy free and private VPN.

Benefits:

  • No subscription required
  • Reduce costs significantly by creating a VPS only when requiring a VPN. E.g., spin up a server before you need a VPN for streaming, use it and then delete it when done and you pay only for the hours used since most VPS providers use that kind of pricing.
  • Complete privacy.

Downsides:

  • manual setup - although this can be successfully overcome with automated solutions (cloud init, cli).

The Problem

I wanted to watch a movie that had become unavailable in the cinemas in my region and I knew that it is still available using a streaming subscription I was already using but again, not in my region, only in the US. As anyone would, I immediately thought of using a VPN service but I didn't want to pay the full month price for a two hour watching experience.

So, I built my own custom VPN with WireGuard. Later that evening, I was able to watch the movie using a custom VPN installation and paying less then 2 cents for it (literaly, $0.018 with Hetzner.de VPS provider).

What follows is the process I went through to implement a solution that I eventually ended up using, instead of the manual steps. The potential is actually huge (not just for streaming), you check out an extensive use case list here: https://github.com/acondura/yopvpn#use-cases.

The Solution

Cloud init approach

Step 1 - Create your VPS instance with required packages and Wireguard VPN

First off, you need a computer, a server where your VPN software (Wireguard, in this case) can be installed. To use our previous streaming example, this has to be placed in a region where you know that it will allow you to stream unrestricted content. If you're in Europe/Asia and you know some movie is available in USA, then choose a VPS provider with USA server locations and create a VPS server in that location.

Choose a VPS provider, like DigitalOcean, Vultr, Linode, Hetzner, etc., you can check out an extensive list here https://www.vpsbenchmarks.com/hosters.

As a specific example, I'm going to use the Hetzner provider since I'm very pleased with their service and I get a lot of resources for the price:

  • I'm located in Europe so I will choose a server location from the US east coast.
  • Server image - latest Ubuntu OS.
  • Server type - their cheapest VPS (which is almost 6 EUR) is more than enough for a VPN.
  • Networking - use defaults.
  • Leave everything else as is until you get to the "Cloud config" step and you'll want to insert the following lines:
     
#cloud-config
packages:
  - docker.io
  - docker-compose
package_update: true
package_upgrade: true
runcmd:
  - systemctl enable docker
  - mkdir -p /opt/wireguard/config
  - docker run -d --name=wireguard --cap-add=NET_ADMIN --cap-add=SYS_MODULE -e PUID=1000 -e PGID=1000 -e TZ=Etc/UTC -e SERVERURL=$(ip -4 addr show eth0 | grep inet | awk '{print $2}' | cut -d/ -f1) -e SERVERPORT=51820 -e PEERS=1 -e PEERDNS=auto -e INTERNAL_SUBNET=10.13.13.0 -e ALLOWEDIPS=0.0.0.0/0 -e LOG_CONFS=true -p 51820:51820/udp -v /opt/wireguard/config:/config -v /lib/modules:/lib/modules --sysctl="net.ipv4.conf.all.src_valid_mark=1" --restart unless-stopped lscr.io/linuxserver/wireguard:latest
  - reboot


After that, click Save or Create server and give it up to a minute to finish setting up.

Step 2 - Connect your device(s)

Connect to your server:
- ssh root@SERVER_IP

and run this command to get your client configuration:
- cat /opt/wireguard/config/peer1/peer1.conf

Copy and paste that into your WireGuard client and click the Activate button.

The CLI (script) approach

You can use the ready made script from https://github.com/acondura/yopvpn in order to reduce the manual steps involved.

First, you'll need to:

  • add your SSH public key in your account of your chosen VPS provider. You can generate an SSH key pair using command:
    • ssh-keygen -t rsa -b 4096 in Windows powershell/MacOS terminal/Linux terminal.
  • then upload the file contents of C:\Users\<YourUsername>\.ssh\id_rsa.pub (for Win) (or ~/.ssh/id_rsa.pub for MacOS/Linux) to your VPS account.

Then, create a server using the cheapest option available in the desired geographical region (ensure you selected the SSH key previously uploaded).
Take note of the given server IP.

Download the installation script from the link above, make sure it is executable and in your terminal/powershell, run this:

./yopvpn SERVER_IP

and replace SERVER_IP with your server's actual IP from your VPS provider.

This will download the conf file and QR code in your Downloads folder for Win/MacOS/Linux.

Open the WireGuard client on your desktop and import the conf file OR for your mobile device, open WireGuard and scan the QR code and activate the connection.

Your devices are now ready to use the VPN.