There was a note on reddit/r/debian which states that Wireguard is fully integrated into the Linux Kernel as of kernel v5.10. I suppose I could have saved a bunch of drama with upgrading to Bookworm which has kernel v6.1 natively, by instead using Bullseye-Backports, but I decided to go all the way. Hindsight is 20/20. A few other machines were already running Bookworm so I thought I had no problems.
It is nice to see that wireguard-tools references nftables. And there are a number of examples as reference for various scenarios.
So, with Wireguard in the kernel, no dkms installation is required. Just the installation of the tools (assumes root or sudo). Use the --no-install-recommends, otherwise your kernel will be replaced with a real-time kernel.
# apt install --not-install-recommends wireguard-tools # cd /etc/wireguard
Create the keys for a peer to peer session:
# wg genkey | tee key_server_private | wg pubkey > key_server_public # wg genkey | tee key_client_private | wg pubkey > key_client_public # chmod -v 600 key* # ls -al /etc/wireguard/ total 20 drwx------ 1 root root 54 Jul 18 04:30 . drwxr-xr-x 1 root root 2348 Jul 19 01:29 .. -rw------- 1 root root 45 Jul 19 02:49 key_client_private -rw------- 1 root root 45 Jul 19 02:49 key_client_public -rw------- 1 root root 45 Jul 19 02:49 key_server_private -rw------- 1 root root 45 Jul 19 02:49 key_server_public
A sample edge interface for server side termination of VPN (file name: wg0.conf):
[Interface] Address = 10.20.10.1/24 #SaveConfig = true ListenPort = 51820 PrivateKey = <server private key> [Peer] PublicKey = <client public key> AllowedIPs = 10.20.10.0/24
A sample client interface, say on an Android for connection back to the server side (flie name: wg0-client.conf):
[Interface] Address = 10.20.10.11/24 PrivateKey = <client private key> DNS = 10.10.30.100 [Peer] PublicKey = <server public key> Endpoint = <server outside address>:51820 AllowedIPs = 10.20.10.0/24, 10.10.0.0/16 PersistentKeepalive = 21
If the allowed address is '0.0.0.0/0', then all traffic goes through the VPN. Use ipv6-test.com or ipleak.net to verify that traffic is going trough the VPN, or use something like WhatIsMyIpAddress.
Impressively, someone has created a QR generator which will generate a code to the terminal window (not a graphic file, but an ansii thingy in a terminal window). This can then be scanned by Android WireGuard to load the configuration.
$ qrencode -t ansiutf8 < wg-android.conf
I use a saltstack script to build a zone based firewall composed of nftable rules. Basically two rules are needed: a) burn a port through the firewall, and b) allow access to the interior network sections for one or all ports.
To turn on the interface and start it automatically:
# chmod -v 600 /etc/wireguard/wg0.conf # wg-quick up wg0 # systemctl enable wg-quick@wg0.service
To turn off the interface and keep it off:
# wg-quick down wg0 # systemctl disable wg-quick@wg0.service
To show connections and status:
# wg show interface: wg0 public key: <server public key> private key: (hidden) listening port: 51820 peer:endpoint: :4496 allowed ips: 10.20.10.0/24 latest handshake: 44 minutes, 26 seconds ago transfer: 2.50 MiB received, 33.47 MiB sent
With the SaveConfig enabled, more clients can be added and saved:
# wg genkey | tee key_mac_private | wg pubkey > key_mac_public # wg set wg0 peer <mac public key> allowed-ips 10.20.10.12/32
Stan's Blog mentioned terminating the server side VPN on UDP port 53. Many/Most networks allow this out, so would/could be a way out of a heavily protected network to the destination.
Note: this config was added to a privileged lxc container, nothing special was required for building the wireguard interface.