How to Set Up Wireguard on a Raspberry Pi 3
Tagged: networking raspberry-pi hacking
It's simpler than I thought it would be, although I haven't yet tried to tackle the NAT issue. Two resources that will prove helpful in debugging should you encounter problems are the unofficial documentation and the ArchLinux wiki page on using Wireguard
1. Installing Wireguard on Raspbian Buster
# install dependencies apt install raspberrypi-kernel-headers libelf-dev libmnl-dev build-essential git # add apt key and allow apt to install unstable packages sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' | sudo tee --append /etc/apt/preferences.d/limit-unstable # update the apt database apt-get update apt-get install wireguard
2. Configuring the Server and Client
First, generate the private and public keys:
# set restricted permissions for all created files umask 077 # generate the key pair wg genkey | tee privatekey | wg pubkey > publickey
Create a new directory under
/etc/wireguard to store the configuration and keys. I went with
Create the server configuration file:
[Interface] # Note that you're copying and pasting the keys into the conf file. They key files generated earlier only store the keys and aren't actually used by wireguard. PrivateKey = <server private key> # Address of server in the vpn network segment Address = 10.24.1.1/24 ListenPort = 51820 DNS = 18.104.22.168 # Allow server to forward traffic (in/out) and enable nat masquerade PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE # For every peer, add a [Peer] section with its public key and VPN IP. [Peer] PublicKey = <client public key> # VPN network segment address of the client. Note the tight, /32 CIDR AllowedIPs = 10.24.1.10/32
Setting up clients follows the same process: first generate the public and private keys, then create a configuration file:
[Interface] # Client's address on vpn network segment Address = 10.24.1.10/24 PrivateKey = <client private key> [Peer] PublicKey = <server public key> # Server address on physical network segment Endpoint = 192.168.1.134:51820 # Here you can decide which traffic to send over the VPN. For example: # Redirect all traffic to vpn AllowedIPs = 0.0.0.0/0 # Only send traffic to a specific peer. In this case, the VPN server and one other peer AllowedIPs = 10.24.1.1/32,10.24.1.11/32 # Note that you can have only one "AllowedIPs" attribute!
3. Running everything
To get everything running, use wg-quick to start the server and client wireguard interfaces:
# I created the same directory structures and named the config files the same way on both client and server. wg-quick up /etc/wireguard/wg0/wg0.conf
You can use
wg show and
ifconfig to see if the interface came up fine. Now, use ping and traceroute to verify that everything connects fine:
# From client, ping server: ping -DO 10.24.1.1 64 bytes from 10.24.1.1: icmp_seq=1 ttl=64 time=13.8 ms ... # Server, ping client: ping -DO 10.24.1.10 64 bytes from 10.24.1.0: icmp_seq=1 ttl=64 time=11.2 ms ...
traceroute is useful at seeing how peers connect to each other through the server:
# traceroute from first client to second client traceroute -n 10.24.1.11 traceroute to 10.24.1.11 (10.24.1.11), 30 hops max, 60 byte packets 1 10.24.1.1. 4.178 ms 4.094 ms 4.024 ms 1 10.24.1.11 6.023 ms 6.009 ms 5.980 ms
As a final tip, remember that you can use the
wg CLI tool to add/remove peers dynamically. All you need then are the public/private key pair and a config file with the
[Interface] block portion. Once you set up the interface with
wg-quick, you can add a peer dynamically, eg.
wg set wg0 peer <public key> allowed-ips 10.24.1.10/32 (server) and
wg set wg0 peer <public key> allowed-ips 10.24.1.1/32 endpoint 192.168.1.134:51820 (client) and you're all set!