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.