How to set up a Wireguard VPN
WireGuard is a modern VPN software that uses state-of-the-art cryptographic algorithms and is designed to be significantly simpler to setup and faster than its main competitor, OpenVPN. In this post I’m going to give a rundown of my configuration of WireGuard for securing a VPN tunnel between a “client” running Arch Linux and and a “server” running Ubuntu Server 19.10.1
Most of this post is a summary and adaptation of the following documents, which are very helpful and worth reading:
Ubuntu 19.10 (server) setup
While on the older Ubuntu releases it was necessary to install a PPA repository, Ubuntu 19.10 includes WireGuard in its official universe repository. So to install it, it is sufficient to issue:
sudo apt install wireguard
followed by:
sudo modprobe wireguard
to load its kernel module. To verify that it’s been loaded, check that the following command doesn’t return an empty result:
lsmod | grep wireguard
Next we generate the private and public key of the server with:
wg genkey | tee privatekey | wg pubkey > publickey
Make sure to restrict access to the private key:
chmod 600 privatekey
We decide a port to use for the server, which in the following example will be
marked as $server_port
, and enable its use on the local firewall:
sudo ufw allow $server_port/udp
You can check the status of the firewall by issuing:
sudo ufw status
The configuration of WireGuard is all kept in /etc/wireguard/wg0.conf
, which
for the server, will be similar to the following:
[Interface]
Address = $server_private_ip/24
PrivateKey = $server_private_key
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = $server_port
[Peer]
PublicKey = $client_public_key
AllowedIPs = $client_private_ip/32
where:
$client_private_ip
is an arbitrarily chosen private IP address of the client$client_public_key
is the public key of the client (see below)$server_private_ip
is an arbitrarily chosen private IP address of the server, in the same subnet of the private IP address of the client$server_private_key
is the private key of the server, as created in the step above
To enabled the forwarding of IPv4 and IPv6 traffic issue:
sudo sysctl -w net.ipv6.conf.all.forwarding=1
sudo sysctl -w net.ipv4.ip_forward=1
and change the corresponding lines in /etc/sysctl.d/99-sysctl.conf
to make
this configuration durable.
Finally, let’s start WireGuard:
wg-quick up wg0
This command will make systemd start the WireGuard service at boot:
sudo systemctl enable wg-quick@wg0
Arch Linux (client) setup
On the Arch Linux client, to install WireGuard issue:
sudo pacman -S wireguard
Then, proceed to create public and private key exactly as in the server case (see above).
The client configuration stored in /etc/wireguard/wg0.conf
will be similar to:
[Interface]
Address = $client_private_ip/24
PrivateKey = $client_private_key
[Peer]
PublicKey = $server_public_key
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = $server_public_ip:$server_port
where
$client_private_key
is the private key of the client we just generated$server_public_key
is the public key of the server (see above)$server_public_ip
is the public IP address of the server0.0.0.0/0, ::/0
means that all traffic will be forwarded through the VPN tunnel
Finally, let’s start WireGuard on the client too:
wg-quick up wg0
Connectivity check
To check that the tunnel is actually established we can use the wg
command:
sudo wg show
on both client and server.
A quick check of the exposed IP address, for instance with curl ifconfig.me
,
will confirm that our network traffic is now passing through the server.
Cost analysis
A back-of-the-envelope calculation reveals that the price of this setup placing the VPN server on a virtual machine in a cloud computing platform is comparable to (if not less than) the price of a commercial VPN service. The VPN server, being mostly computation and networking-heavy, won’t need much memory or storage. In my experience, even a single core is more than enough for individual daily use. The ballpark estimate of the price for such setup is around 10€/month, which is considerably further reduced by leveraging offers such as spot instances and free tiers.
-
for WireGuard and its official documentation, both client and server are simply “peers”. ↩