Wireguard is the latest version of VPN that is available in the Linux kernel, its fast and (in theory) simple to configure.

The server and client both need a private/public key pair. They exchange public keys and optionally the server can generate a pre-shared key. The IP addresses are configured for each peer and that is it. As its not something I do often it usually takes me a few tries but I've hopefully got it working with these notes.

Server Configuration

Install wireguard-tools

snippet.bash
# Arch
pacman -Syu wireguard-tools
# Gentoo
emerge -av wiregoard-tools

Server Configuration

Generate key pairs on the server for each client (<device> represents a unique name for the device you want to add so they don't over-write each other)…

snippet.bash
(umask 077 && wg genkey > wg-server-private.key)
wg pubkey < <device>_private.key > wg-server-client1-public.key
# All in one
(umask 077 && wg genkey | tee wg-server-private.key | wg pubkey > wg-server-client1-public.key)
# Preshared key
wg genpsk > wg-server-client1-psk

NB If you are returning to your server at a later date to create more keys for new clients you will already have generated your servers private key and need to use that to generate the public keys that will be shared with new clients. You can do that using the following line…

snippet.bash
grep 'PrivateKey = ' /etc/wireguard/wg0.conf | tail -n 1 | sed -e 's/.* = //g' > wg pubkey > wg-server-client2-public.key

You will need your public and private keys, show them with cat wg-private.key and cat wg-public.key.

/etc/wireguard/wg0.conf

Now configure /etc/wireguard/wg0.conf, note that you won't be able to add the PublicKey under [Peer] until you have generated it (see next section on Clients).

snippet.bash
[Interface]
Address = 10.200.200.1/24
ListenPort = 46879
PrivateKey = <wg-server-private.key>
DNS = 1.1.1.1
 
# note - substitute eth0 in the following lines to match the Internet-facing interface
# if the server is behind a router and receive traffic via NAT, this iptables rules are not needed
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
 
[Peer] #
PublicKey = <wg-client1-public.key>   # Generated in the steps below
PresharedKey = <wg-server-client1-psk>
=
AllowedIPs = 10.200.200.2/32

The server will have the address 10.200.200.1 listening on port 46879. It uses Cloudflares 1.1.1.1 for DNS. There are hooks to modify the iptables firewall rules after bringing the interface up and down. The client section requires you to complete the Client Configuration in a similar manner so that the public key from each client can be added to the server configuration.

Apply the configuration on the server and check it…

snippet.bash
wg syncconf wg0 /etc/wireguard/wg0.conf
wg show wg0

Client Configuration

Each client needs its own configuration and as mentioned its own pair of Private and Public keys.

Linux

Create private and public keys on your client…

snippet.bash
$ (umask 077 && wg genkey > wg-client1-private.key)
$ wg pubkey < wg-client-private.key > wg-client1-public.key

/etc/wireguard/wg0.conf

As with the server the clients needs a similar configuration

snippet.bash
# define the local WireGuard interface (client)
[Interface]
Address 10.200.200.2/32       # Note that this matches the IP address it is assigned by the server
PrivateKey = <wg-client1-private.key>
DNS = 1.1.1.1
 
# define the remote WireGuard interface (server)
[Peer]
# contents of wg-public.key on the WireGuard server
PublicKey = <wg-server-client1-public.key>
 
# the IP address that are allowed to use the device from the client, this allows everything on both IPv4 and IPv6 devices
AllowedIPs = 0.0.0.0/0, ::/0
 
# public IP address and port of the WireGuard server
Endpoint = 12.34.56.78:46879         # This is the public, non-VPN IP address and port of the server

Android

Install the Wireguard Application, add a new interface manually and in theory you should be able to fill in all fields between the client (the phone) and the server and it will work.

In practice I found this didn't work, I repeatedly got Handshake did not complete after 5 seconds, retrying (try 2) in the log files (available under settings for viewing and exporting). After checking the logs on the server (see section below on how to access these) I opted to create a configuration by hand on a computer, saving to file and then import it to the Android Wireguard client. The QR-code generator I used didn't seem to produce a valid code as the Wireguard App on the phone complained about Invalid parameter in config file but loading the file itself did. Bingo!

Trouble-shooting

I had trouble getting my new phone to connect and found that on the server you can enable logging for debugging on the fly with.

snippet.bash
modprobe wireguard 
echo module wireguard +p > /sys/kernel/debug/dynamic_debug/control
dmesg -wH

This showed that when I tried to connect…

snippet.bash
[Feb25 06:54] wireguard: wg0: Invalid MAC of handshake, dropping packet from 88.97.78.71:44542
[  +5.049426] wireguard: wg0: Invalid MAC of handshake, dropping packet from 88.97.78.71:44542

Links

Miscellaneous

linux/security/wireguard.txt · Last modified: 2023/02/25 17:13 by admin
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0