Setting up Personal VPN


Introduction

In these days and times privacy is number one concern for most people while browsing the internet. The www ecosystem is designed and developed in such a way that forces its users to live in glass houses. Even if users have nothing to hide it doesn’t mean that the corporation behind the web services gets a free pass to log and monitor all of their activities and make a business plan out of it. The Internet is supposed to be a public space that should have no boundaries like we have in the physical world. Even with ad-blockers, anti-trackers there is no way to completely avoid services from logging you. Only sure way is to provide an assumed identity at the time of check-in and tear down the trail once you leave. The VPN does exactly that for you.

Private VPN

Using commercial VPN is not that bad actually but the cost and lack of available bandwidth might be a bottleneck. Also VPN at least allows you to avoid monitoring by any middle-man, like ISPs, the end service is bound to know you.

Privately setting up a VPN has never been easier. With services like DigitalOcean and Lightsail, spinning up a private server in a location of your choice is a matter of a few clicks and happens in minutes.

There are multiple open-source options to set up a VPN server and clients. Also, there are automated one-click suites to setup everything like AlgoVPN.This post is about getting to know a little bit better how a VPN works and why setting up your own could be more cost-effective and actually useful.

WireGuard

WireGuard is one of the options to set up your own VPN beside other popular options like IPSec, OpenVPN etc. originally written for Linux it is now a cross platform high performing VPN Tunnel loved by people all around the world. I’m not going to explain all the goodness that it offers but will try to visualize the overview of its working.

WireGuard takes some unique approaches in setting up a VPN.

  • Creates a kernel virtual network interface
  • 32 byte public key represented as base64 whose exchange is not the responsibility of WireGuard layer
  • Cryptographically opinionated makes it less complex and vulnerabilities discovery affects all endpoints
  • layer-3 only

The virtual interface has its own public and private key along with a UDP listening port. Each interface maintains a routing table which maps a public key with a set of allowed IPs. The static information is used for handshake and establishing a secure session. Once established the client can start using VPN server peers to communicate with the internet.

Outgoing packets consult the routing table based on the destination IP and use the mapped public key to encrypt IP frames.

Incoming UDP datagram destined to wg0 configured port reach wireguard stack. The header inserted by wireguard is used to determine the session key for decryption. Packet is dropped if session key lookup fails, or if post decryption the data is not an IP datagram or the if the src_ip is not matching the routing table. Once satisfied the header and IP info is used to update the endpoint info and the packet is pushed up the stack.

Outgoing Flow

outgoing

Incoming Flow

incoming

I highly recommend using AlgoVPN to setup wireguard seamlessly, but knowing the manual is beneficial to understanding the working of Wireguard.

Setup

I am using DigitalOcean to spin up a basic Ubuntu 20.04 VM with a good enough transfer limit. My client is a windows laptop. Things to consider and note down while setting up the server are, public IP, login credentials or keys and region.

Setting up Manually

Install WireGuard

sudo apt install wireguard

before setting up anything else, you should ideally see three interfaces on the machine

  • lo: localhost
  • eth0: public IP
  • eth1: backplane traffic IP

Enable IPv4 forward

do this before doing anything else

sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0

vim /etc/sysctl.conf
net.ipv4.ip_forward=1
net.ipv4.conf.all.forwarding=1

reboot

sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Create public and private keys

It is not advisable to keep keys on the machine but for this tutorial we will make an exception.

mkdir keys
cd keys
wg genkey > private_key
wg pubkey < private_key > public_key
wg genkey > ranuzz_private_key
wg pubkey < ranuzz_private_key > ranuzz_public_key

Setup wg0


; create wg0
ip link add dev wg0 type wireguard

; assign IP
ip address add dev wg0 192.168.0.1/24

; set server private key
wg set wg0 listen-port 51820 private-key ./private_key

; activate wg0
ip link set up dev wg0

; add peer (replace ranuzz_public_key with its conten)
wg set wg0 peer ranuzz_public_key allowed-ips 192.168.0.2/32

wg0 interfaces configuration should look like this

wg showconf wg0
[Interface]
ListenPort = 51820
PrivateKey = private_key

[Peer]
PublicKey = ranuzz_public_key
AllowedIPs = 192.168.0.2/32

Creating client config file

Based on the keys generated and information above you should be able to write a configuration file for the client/peer. DNS configuration is required to access the internet, you can use any public DNS like google or cloudflare.

[Interface]
PrivateKey = ranuzz_private_key
Address = 192.168.0.2/32
DNS = 8.8.8.8

[Peer]
PublicKey = public_key
AllowedIPs = 0.0.0.0/0,::/0
Endpoint = server_public_ip:51820

install wireguard on windows

https://www.wireguard.com/install/

load client config via UI

Import tunnel from config file and click activate

AlgoVPN Setup (alternate)

Setting manually is all well and good but there could be a lot of variables depending on the type of system or configuration you are using. Using an automated solution is always a safe bet and AlgoVPN is the most suitable choice. There github has a detailed installation instruction. I’m including what I used to configure my Ubuntu 20.04 VM.

Run this once you login to your fresh installation

sudo apt-get update
sudo apt install -y --no-install-recommends python3-virtualenv
git clone https://github.com/trailofbits/algo.git
cd algo
python3 -m virtualenv .env
source .env/bin/activate
pip install -U pip virtualenv
pip install -r requirements.txt

Open config.cfg file and add a user if you want. But it’s ok to go with default three users. Then execute the script and follow the prompts

./algo

What provider would you like to use ?
12 (Ubuntu Server Local installation)

Cellular on demand: N
Wifi on demand: N
retain PKI: N
DNS ad Block: N
SSH Tunelling: N

Enter the IP address of your server:
(localhost)

Enter the public IP address or domain name of your server:
(server_public_ip)

Once done you should find all client config files in ~/algo/configs/server_public_ip/wireguard. Use one of the clients to add a tunnel.

Not receiving anything from the server

Make sure that firewall rules allow the port your tunnel is using.

could not locate file in lookup

If you encounter this error in the ‘.pki’ folder then simply generate the keys yourself using wg genkey command.