A Guide to Creating A Secure WireGuard Tunnel on Ubuntu 24.04
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.
- install wireguard on both computers
sudo apt wireguard
- create private & public keys on server
wg genkey | tee privatekey | wg pubkey > publickey
- copy new server private key to clipboard for use in server config file
tail privatekey (then select and copy output)
- create wireguard config file on server
sudo nano /etc/wireguard/wg0.conf
- 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.
- start server wireguard interface
sudo wg-quick up wg0
- check wireguard is running on server
sudo wg
- create private & public keys on client
wg genkey | tee wgprivatekey | wg pubkey > wgpublickey
- copy client private key
tail wgprivatekey (then select and copy output)
- create wireguard config file on client
sudo nano /etc/wireguard/wg0.conf
- 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.
- start client wireguard interface
sudo wg-quick up wg0
- check wireguard is running on client
sudo wg
- 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.