I learned this recently to help a local organization with their web presence. I present it here, for those tired of watching mediocre video tutorials. I hope you find it useful.

  1. install wireguard on both computers

sudo apt wireguard

  1. create private & public keys on server

wg genkey | tee privatekey | wg pubkey > publickey

  1. copy new server private key to clipboard for use in server config file

tail privatekey (then select and copy output)

  1. create wireguard config file on server

sudo nano /etc/wireguard/wg0.conf

  1. populate server config file
[Interface]
PrivateKey=
Address=10.0.0.1/24
SaveConfig=true
PostUp=iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o <public-interface> -j MASQUERADE;
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o <public-interface> -j MASQUERADE;
ListenPort = 51820

PrivateKey should be copied from tail privatekey and pasted after the = sign.

Address should be on a subnet no interface is using (ip link show) and should end in /24 so that we only listen for and send traffic going to the 10.0.0.xxx IP range.

<public-interface> in both lines above is likely eth0.

  1. start server wireguard interface

sudo wg-quick up wg0

  1. check wireguard is running on server

sudo wg

  1. create private & public keys on client

wg genkey | tee wgprivatekey | wg pubkey > wgpublickey

  1. copy client private key

tail wgprivatekey (then select and copy output)

  1. create wireguard config file on client

sudo nano /etc/wireguard/wg0.conf

  1. populate config file
[Interface]
PrivateKey = <client-private-key>
Address = 10.0.0.5/24
SaveConfig = true
ListenPort = 51820

[Peer]
PublicKey = <server-public-key>
Endpoint = <server-public-ip-address>:51820
AllowedIPs = 10.0.0.1/32
PersistentKeepalive=30

PrivateKey should be copied from tail wgprivatekey and pasted after the = sign.

Address should be a new address (10.0.0.5 instead of 10.0.0.1) on the same unused subnet specified in the server config, and should also end in /24 so we only listen and send to 10.0.0.xxx IP addresses.

PublicKey should be set with the copied output from the server's sudo wg command and pasted after the = sign.

Endpoint is the public IP address of the server, followed by its listening port set in the server conf, 51820.

AllowedIPs must be the subnet set in the server and client Address lines. If we only want to use WireGuard for very specific traffic or requests from a single address, like our server, we'll use /32 to limit traffic to and from the single IP address, in our example 10.0.0.1. If we want to allow requests from all clients in the 10.0.0.xxx range, use 24.

PersistentKeepalive=30 sets the connection to send a packet every 30 seconds to keep the connection alive.

  1. start client wireguard interface

sudo wg-quick up wg0

  1. check wireguard is running on client

sudo wg

  1. add client info to server wireguard interface

sudo wg set wg0 peer <client-public-key> allowed-ips <client-ip-address>/32

<client-public-key> will be copied from the client's sudo wg output and pasted at the appropriate point. <client-ip-address> will be the address we set in our client config file's Address line, with /32 so that the server is only accepting peer connections from our single client. We can't use /24 to automatically create peers for the whole 10.0.0.xxx range, because each needs a corresponding public key. The public key of our client should only attach to our client's IP; we use /32 to specify that our one public key belongs to our one client IP address.

A final note: The tunnel should only be taken down with the command sudo wg-quick down. This command can be used on either client or server, and is necessary for a graceful shutdown of the WireGuard tunnel.