Wireguard is one of the most widely adopted protocol to provide a secure virtual private network (VPN). Note that there are much easier ways of getting started and off the shelf solutions that fit a wide variety of use cases. Examples include:

Even amongst wireguard there are other soultions that use the technology that may also satisfy - I’d recommend also checking out:

I use pangolin for deployments of services I want publicly accessible - refer to my other blog post on my lab setup for more info.

However, in this instance I wanted to setup the VPN manually and get a better idea at how wireguard works and is configured.

Quickstart

Wireguard is reknown for being easy to use and using cutting edge cyrptography for security. The service provides a quickstart on their website for getting the VPN setup and getting connectivity going. There’s a good paper on wireguard that describes the protocol - and the original designer has their website at https://www.zx2c4.com/.

Ubuntu has a decent article which we’re using as a first pass on getting wireguard going in a peer-to-site configuration.

Router Configuration

First thing is to update the router to avoid assigning DHCP Addresses that would conflict with the range we want to use for the VPN. The DHCP server settings should only include a subset of the full range (e.g. 10.0.0.0/24 with a subset for the addressable ranges). Ideally the router would be able to provision a separate VPN network, but until I get my network setup with a dedicated router we’ll just be using the router/gateway combo and using the ISP provider tools.

We need to reserve a range for another service (VPN) in the DHCP server configuration and port forward the wireguard port for our device. The port that wireguard uses is configurable, it’s only necessary to make sure the router configuration and the wireguard configuration match up.

Wireguard Setup

I’m using an ubuntu distribution to run the wireguard enpoint - and wireguard is provided by the package manager:

sudo apt install wireguard

After installing wireguard - configure the endpoint to accept traffic on the same port the router is port forwarding. As an example:

[Interface]
Address = <SERVER_WG_VPN_ADDRESS>/32
ListenPort = 12345
PrivateKey = <SERVER_PRIVATE_KEY>

# Packet forwarding
PreUp = sysctl -w net.piv4.ip_forward=1

[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = <CLIENT_WG_VPN_ADDRESS>/32 # any available IP in the VPN range (avoided in DHCP config)

The server keys are created with wireguard:

# Create private key
wg genkey > internal-private.key

# Create public key
wg pubkey < internal-private.key > internal-public.key

The client key pairs are generated in the next session.

Setup the client

The people who make wireguard also have an app that is available on many platforms: https://www.wireguard.com/install/ For setting up the client, you can either opt to have the application create the key-pair, or generate it on the server and use a QR code to import into the client. The QR code process is outlined nicely in this blog. In essence install a QR code renderer so we can visualize the configuration and easily import it into the app.

sudo apt install qrencode

Follow the same process for creating the key-pairs that we did in the previous section. The main difference comes in the form of the configuration. The configuration will include a wider subnet - if you notice in the previous section, the CIDR subnet mask is /32 which resolves only the single specified IP address. For the client configuration, you’ll want to match up the allowed IP address.

[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = <CLIENT_WG_VPN_ADDRESS>/24

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
AllowedIPs = <SERVER_WG_VPN_ADDRESS>/24
Endpoint = <ROUTER_PUBLIC_IP_ADDRESS>:12345

The AllowedIPs in the peer configuration is wider subnet mask /24 which will resolve everything X.X.X.0 through X.X.X.255.

To visualize the configuration run the tool qrencode:

qrencode -t ansiutf8 < /etc/wireguard/clients/client.conf

Use the resulting rendered QR code to load the configuration into your app.

Firewall

The last bit of configuration that is required for the VPN to work correctly to expose the desired port and protocol (udp). A common firewall manager is the uncomplicated firwall ufw. Another blog goes through the setup using ufw with wireguard. If you desire wireguard to access other resources you’ll need to configure a ufw rule to forward the traffic coming in on the wireguard interface.

# Allow the traffic on the wireguard port and protocol (a common port is 51821)
sudo ufw allow 51821/udp

# Forward HTTP traffic to the local network from the wireguard network
sudo ufw route allow in on wg0 proto tcp to any port 80

More information on practical uses of ufw is available on a blog from digital ocean for how to setup a firewall with ufw on ubuntu.

Future work

There are alternatives for point to point connectivity - one which may be interesting for future exploration is mTLS which satisfies the needs of mutual authenticaition by verifying certificates between two hosts.