Wireguard
Changelog
- Many years ago...: Init
- 2024-02-12: Reupdate WireGuard installation procedure.
After some time playing around with Tailscale, and requiring a reduced feature set for better security features, ...
Also reverse connections are absolutely available! Wireguard sets up a tunnel, which one can forward packets through, see this: https://unix.stackexchange.com/questions/721816/linux-router-with-traffic-forwarding-over-a-wireguard-tunnel
Archived
Preliminary setup instructions on Ubuntu, referenced from DigitalOcean tutorial. Here's an interesting article explaining a bit more in detail about Wireguard parameters.
The basic principle of Wireguard is really simple - it essentially does two things, in a default setup:
- Enable peer-to-peer connection using asymmetric key one-way connections
- Adds rules to iptables dynamically for packet routing
The bare minimum installation + configuration is thus as follows (demonstrated for IPv4, but can be similarly done for IPv6):
Minimal installation
Some parameters:
- Wireguard port: 32415
- Server endpoint: 32.4.150.57
- install_wg.sh
#!/bin/sh # Install wireguard package sudo apt update sudo apt install wireguard # Enable IPv4 packet forwarding, and reload sysctl sudo sed -e "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g" /etc/sysctl.conf sudo sysctl -p # Open firewall for wireguard # Reminder to port forward on router as well sudo ufw allow 32415/udp comment "wireguard" sudo ufw reload # Generate public/private keys for server, with correct permissions wg genkey | sudo tee /etc/wireguard/private.key sudo chmod go= /etc/wireguard/private.key sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key sudo chmod ugo+rx /etc/wireguard
Create another public/private key pair for the client as well, e.g. for Windows WireGuard GUI:
Suppose:
- Server private key:
SERVERPRIVKEY46viLzxybqtnG9cW9NlimHN9KZXVM=
- Server public key:
SERVERPUBKEYAVPP2lc21Odb3YaZthTzGkmXUIc2+zM=
- Client private key:
CLIENTPRIVKEYBwiiLfvT6+IKB3chKS+6bfx5Sxh42U=
- Client public key:
CLIENTPUBKEYFlzrXfUJYqi0H3OpCp1WGztuJdQU/Bc=
First determine the internet-facing device interface for the server, below shown to be eth0
:
> ip route list default default via 203.0.113.1 dev *eth0* proto static
In the Wireguard configuration folder for the server, create wg0.conf
:
- /etc/wireguard/wg0.conf
[Interface] PrivateKey = SERVERPRIVKEY46viLzxybqtnG9cW9NlimHN9KZXVM= Address = 10.0.0.1/24 ListenPort = 32415 PostUp = ufw route allow in on wg0 out on eth0 PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE PreDown = ufw route delete allow in on wg0 out on eth0 PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE [Peer] PublicKey = CLIENTPUBKEYFlzrXfUJYqi0H3OpCp1WGztuJdQU/Bc= AllowedIPs = 10.0.0.2/32
While for the client, create the corresponding configuration (e.g. in WireGuard GUI):
- client_wireguard.conf
[Interface] PrivateKey = CLIENTPRIVKEYBwiiLfvT6+IKB3chKS+6bfx5Sxh42U= Address = 10.0.0.2/32 [Peer] PublicKey = SERVERPUBKEYAVPP2lc21Odb3YaZthTzGkmXUIc2+zM= AllowedIPs = 10.0.0.0/24 Endpoint = 32.4.150.57:32415
Finally, enable Wireguard configurations on each respective end, using the wg-quick helper. For server:
# Enable WireGuard as a service sudo systemctl enable wg-quick@wg0.service sudo systemctl start wg-quick@wg0.service sudo systemctl status wg-quick@wg0.service # Check out active configuration sudo wg show
Same for the client (e.g. for Windows GUI, select Activate).
A quick explanation for some of the parameters seen here:
Side | Section | Param | Remark |
---|---|---|---|
Server | Interface | PrivateKey | - |
Server | Interface | Address | Defines the virtual WG server IP, as well as the local subnet for all connecting clients (if so desired). Not too important in a basic setup. |
Server | Interface | *ListenPort | Static port for WG |
Server | Interface | *PostUp | Commands to run after starting up WG config |
Server | Interface | *PreDown | Commands to run before tearing down WG |
Server | Peer | PublicKey | Note: There can be multiple Peer sections. |
Server | Peer | AllowedIPs | Determines which destination packets are routed through the VPN to the clients. |
Client | Interface | PrivateKey | - |
Client | Interface | Address | IP client chooses to take. |
Client | Peer | PublicKey | - |
Client | Peer | AllowedIPs | Determines which destination packets are routed through the VPN to the server. |
Client | Peer | &Endpoint | The server's endpoint. |
*: Server-specific, to define exposure of subnet. &: Client-specific, to define connection to remote subnet.
To prevent DNS leak (especially when routing most traffic through the WireGuard VPN), can add an additional DNS field under client's [Interface] section.
Synology installation
A personal note: The whole reason I dived into Wireguard is two-fold: (1) OpenVPN implementation on the router is a little finnicky, (2) Need to stop exposing Synology Drive's port 6690, which is currently directly forwarded by the router to the NAS with zero firewall. Given the closed source nature of Synology Drive, I rather trust an exposed Wireguard, and connect to the Drive internally via the VPN network.
Credits to Blackvoid for supplying the DSM 7.X compatible builds for runfalk's implementation of Wireguard's kernel module for Synology NAS. Built using Synobuild17 written by Blackvoid. Configuration on NAS can be accessed by chaining SSH logins.
mkdir -p /etc/wireguard sudo chmod ugo+rx /etc/wireguard cd /etc/wireguard/ wg genkey | sudo tee /etc/wireguard/private.key sudo chmod go= /etc/wireguard/private.key
And then proceed to attach it to the WireGuard server to enable access. Note that keep-alive packets are needed to allow peer to continue listening for incoming packets (there's some interplay with session handshakes).
- /etc/wireguard/wg0.conf
[Interface] PrivateKey = CLIENTPRIVKEYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Address = 10.0.0.3/32 [Peer] PublicKey = SERVERPUBKEYBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB= AllowedIPs = 10.0.0.0/24 Endpoint = 32.4.150.57:32415 PersistentKeepAlive = 60
sudo wg-quick up wg0
The problem now is being unable to connect peer-to-peer, despite ping working. Other than the commonly raised MTU lowering fix, the more likely reason is how the WireGuard server is dealing with packets as the router for the VPN network.
Testing iptables policies can help isolate this problem, credits to SO for suggesting:
> sudo iptables -L > sudo iptables -P INPUT ACCEPT > sudo iptables -P FORWARD ACCEPT > sudo iptables -L
One other possible cause of being unable to connect to the Synology NAS via a different subnet is because of: (1) firewall in the NAS, need to allow for VPN network, (2) multiple gateways will need to be enabled to allow subnet segregation.
Anyway it turns out the solution was in SO all along, i.e. allow forwarding of Wireguard traffic, instead of restricting to a fixed subnet:
iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
This can be directly inserted into the Wireguard configuration, in the following form:
PostUp = iptables -I FORWARD -i %i -o %i -j ACCEPT PreDown = iptables -D FORWARD -i %i -o %i -j ACCEPT
Troubleshooting
When the IP link wg0
is persistently up, and no amount of wg-quick down wg0
will fix it, forcibly removing it works:
sudo ip link delete dev wg0