WireGuard

I’ve been using OpenVPN for a few things and I’ve been very interested in setting up WireGuard instead as it has a lot less overhead and is less cumbersome than OpenVPN. Well I finally took the plunge last night and it was surprisingly easy after only a few missteps!

One of my use cases is to tunnel all traffic to the VPN server, so it appears as if my internet traffic originates from the VPN server. Here is how I set it up (with thanks to a few other articles).

On the Server (Ubuntu 18.04 LTS)

Install WireGuard on the server. I am running Ubuntu 18.04 and so I had to add the repository.

Move to the /etc/wireguard directory (you may need to sudo su)

Generate the public and private keys by running the following commands. This will create two files (privatekey and publickey) in the /etc/wireguard so you can re-reference them while building out the config.

$ umask 077  # This makes sure credentials don't leak in a race condition.
$ wg genkey | tee privatekey | wg pubkey > publickey

Create the server config file (/etc/wireguard/wg0.conf). Things to note:

  1. The IP space used is specifically reserved for a shared address space per RFC6598
  2. I only care about IPv4. It is possible to add IPv6 address and routing capabilities into the configuration
  3. For routing, my server’s local interface name is eth0.
  4. You can choose any port number for ListenPort, but note that it is UDP.
  5. Add as many peer sections as you have clients.
  6. Use the key in the privatekey file in place of <Server Private Key>. Wireguard doesn’t support file references at this time.
  7. We haven’t generated the Client public keys yet, so those will be blank.
[Interface]
Address = 100.62.0.1/24
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = <Server Private Key>

[Peer]
PublicKey = <Client1 Public Key>
AllowedIPs = 100.62.0.2/32

[Peer]
PublicKey = <Client2 Public Key>
AllowedIPs = 100.62.0.3/32

Test the configuration with wg-quick

root@wg ~# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip address add 100.62.0.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0

Remove the interface with wg-quick

root@wg ~# wg-quick down wg0
[#] ip link delete dev wg0

Use systemd service to start the interface automatically at boot

systemctl start wg-quick@wg0
systemctl enable wg-quick@wg0

To forward traffic of the client through the server, we need to enable routing on the server

echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/wg.conf
sysctl --system

On the Client (Android)

  1. Install the WireGuard App from the Play store
  2. Open the app and create a new profile (click the +)
  3. Create from scratch (you could move a pre-created config file too)
    1. Give the interface a name
    2. Generate a private key
    3. Set the address to the address listed in the peer section of your server config – 100.62.0.2/32
    4. (Optionally) Set DNS servers as your local DHCP servers will no longer work as all packets will encrypted and sent across the VPN
    5. Click Add Peer
      1. Enter the Server’s public key
      2. Set Allowed IPs to 0.0.0.0/0 to send all traffic across the VPN
      3. Set the endpoint to the IP address you’ll access the server on, along with the port (i.e. <InternetIP/Name>:51820)

Revisit the Server Config

Now that the client has a public key, you need to update /etc/wireguard/wg0.conf

[Peer]
PublicKey = <INSERT PUBLIC KEY>
AllowedIPs = 100.62.0.2/32 

Restart the wireguard service

systemctl restart wg-quick@wg0 

Connect to the Server from the Client

Within the wireguard app, enable the VPN.

You can validate by visiting ipleak.net to verify that traffic is going through the VPN.