WireGuard setup

21 May 2026

Notes on setting up WireGuard

#WireGuard

WireGuard is, lightweight, fast, open-source VPN that uses public/private key cryptography to securely connect devices over the internet. I've used WireGuard for accessing my home network and have setup WireGuard VPNs for clients. This page has some notes I've taken when setting up WireGuard.

#Server Configuration

In Wireguard, every computer involved is technically a peer. My typical setup is a "roaming-access" configuration with a public-facing peer for access over the internet. I'll refer the public peer as the server. It has a stable public IP/DNS name and listens for incoming traffic from the internet.

#Wireguard Server Configuration (Ubuntu)

  1. Install WireGuard
sudo apt update 
sudo apt install -y wireguard wireguard-tools
  1. Use wg to generate public and private keys.
 umask 077
 wg genkey > srv_private.key 
 wg pubkey < srv_private.key  > srv_public.key

You'll need to copy these keys into WireGuard config files. The key files are just text files and you can look at them with any text editor (or just cat them on a terminal). Most guides put the keys in /etc/wireguard. This isn't necessary, but You should make sure the private key is not readable by everyone.

  1. Choose a local subnet.

Peers in your private network will need IP addresses. There are three standard private IPv4 address blocks:

For this example I'm using 10.20.30.XXX for my PCs.

  1. Create your configuration file. This is /etc/wireguard/wg0.conf
[Interface]
Address = 10.20.30.1/24
ListenPort = 51820
PrivateKey = <YOUR PRIVATE KEY FROM STEP 2>
SaveConfig = true

#[Peer]

Important SaveConfig is set to true here. You should not manually add computers to the [Peer] section. If you do, they'll get erased when the server is restarted.

  1. Enable IP forwarding. This is optional if peers only talk to the server and don't need to reach the internet or other peers through the server. I want peers to have access to each other. For this to work I need to:

To enable IP forwarding, open /etc/sysctl.conf with an editor and uncomment the line with net.ipv4.ip_forward=1

Next update your system with sysctl

sudo sysctl -p

Some other things to add are

 iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT
iptables -t nat -I POSTROUTING -s 10.20.30.0/24 -o eth0 -j MASQUERADE

This lets you hide peer IP addresses behind the server IP address. I generally don't use this but have included it in the configuration for completeness.

So update /etc/wireguard/wg0.conf to look like:

[Interface]
Address = 10.20.30.1/24
ListenPort = 51820
PrivateKey = <YOUR PRIVATE KEY FROM STEP 2>
SaveConfig = true

PostUp = ufw route allow in on wg0 out on eth0
PostUp = iptables -t nat -I POSTROUTING -s 10.20.30.0/24 -o eth0 -j MASQUERADE
PostUp = iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT

PreDown = ufw route delete allow in on wg0 out on eth0
PreDown = iptables -t nat -D POSTROUTING -s 10.20.30.0/24 -o eth0 -j MASQUERADE
PreDown = iptables -D FORWARD -i wg0 -o wg0 -j ACCEPT

Note The network device here is eth0. You may have a different device, you can list devices with ip link show.

  1. Allow UDP traffic on port 51820 through the firewall
sudo ufw allow 51820/udp
  1. Enable the wireguard service
sudo systemctl enable wg-quick@wg0.service
sudo systemctl start wg-quick@wg0.service

You can check for errors with systemctl status

sudo systemctl status wg-quick@wg0.service
  1. To add peers to server, use the wg set command.
sudo wg set wg0 peer <PEER_PUBLIC_KEY> allowed-ips <PEER_IP/32>

you can also remove peers with wg set

sudo wg set wg0 peer <PEER_PUBLIC_KEY> remove

#Some useful commands

 journalctl -u wg-quick@wg0 -e # View logs for WireGuard. 
 sudo wg showconf wg0          # View current wg0 configuration
 sudo wg show                  # SHow status of WireGuard interfaces (shows peers)
 ip addr show wg0              # Display network properties of wg0 interface
 ip route show dev wg0         # Display routes associated with wg0 interface

#Wireguard Server Configuration (Fedora)

Fedora uses firewalld by default. firewalld is zone-based, so instead of adding iptables rules to wg0.conf, we assign interfaces to zones like public or internal and let the firewall handle the rest.

  1. Install WireGuard
sudo dnf install wireguard-tools

use wg to generate public and private keys

 umask 077
 wg genkey > srv_private.key 
 wg pubkey < srv_private.key  > srv_public.key

You'll need to put these keys into WireGuard config files. The key files are text files and you can look at them with any text editor (or just cat them on a terminal)

  1. Choose a local subnet.
    Peers in your private network will need IP addresses. There are three standard private IPv4 address blocks:

For this example I'm using 10.20.30.XXX for my PCs.

  1. Create your configuration file. This is /etc/wireguard/wg0.conf
[Interface]
Address = 10.20.30.1/24
ListenPort = 51820
PrivateKey = <YOUR PRIVATE KEY FROM STEP 2>
SaveConfig = true

#[Peer]

Important SaveConfig is set to true here. You should not manually add computers to the [Peer] section. IF you do, they'll get erased when the server is restarted.

  1. Enable IP forwarding.
sudo vim /etc/sysctl.d/99-sysctl.conf

and add net.ipv4.ip_forward=1

then apply it

sudo sysctl --system

check with

sysctl net.ipv4.ip_forward

should see

# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

IMP instead of using PostUp and PostDown in wg0.conf for routing, masquerade, and peer traffic I'll use zones in firewalld with firewall-cmd.

figure out your zone

sudo firewall-cmd --get-active-zones

which shows me

sudo firewall-cmd --get-active-zones
FedoraServer (default)
  interfaces: eth0

we also have several predefined zones

sudo firewall-cmd --get-zones
FedoraServer FedoraWorkstation block dmz drop external home internal nm-shared public trusted work
sudo firewall-cmd --zone=internal --add-interface=wg0 --permanent
sudo firewall-cmd --reload

firewall-cmd --get-active-zones
FedoraServer (default)
  interfaces: eth0
internal
  interfaces: wg0

firewall-cmd --get-zone-of-interface=wg0

(you may want to make a custom wireguard zone for a more locked-down setup)

sudo firewall-cmd --zone=external --add-masquerade --permanent
sudo firewall-cmd --permanent --zone=FedoraServer --add-port=51820/udp

inspect

sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=FedoraServer --list-all
sudo firewall-cmd --zone=internal --list-all

add clients with

sudo wg set wg0 peer <PEER_PUBLIC_KEY> allowed-ips <PEER_IP_ADDRESS>/32

#Client Configuration

WireGuard runs on many platforms. I've helped customers configure clients on various systems, including Linux, Windows and macOS.

#Linux Clients

Ubuntu and Fedora configuration is largely the same. The only real difference is using apt or dnf

  1. Install WireGuard

On Ubuntu

sudo apt install wireguard

On Fedora use wireguard-tools

sudo dnf install wireguard-tools
  1. Once again, we generate public/private key pairs.
 umask 077
 wg genkey > private.key 
 wg pubkey < private.key  > public.key
  1. Setup both the [Interface] and [Peer] sections in /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <YOUR CLIENT PRIVATE KEY>
Address = 10.20.30.100/32

[Peer]
PublicKey = <THE SERVER PUBLIC KEY>
AllowedIPs = 10.20.30.0/24
Endpoint = XXX.XXX.XXX.XXX:51820 
PersistentKeepalive = 25
  1. Add your new peer's public key on the server.
sudo wg set wg0 peer <PEER_PUBLIC_KEY> allowed-ips <PEER_IP_ADDRESS>/32

Make sure the <PEER_IP_ADDRESS> matches the address you used in step 3.

  1. Enable and start the service on the client
sudo wg-quick up wg0

or

sudo systemctl start wg-quick@wg0.service

#Windows Client

Windows installers can be obtained from WireGuard.

  1. Go to https://www.wireguard.com/install/, download the Windows installer.

  2. Run the installer.

  3. Once installed it should appear in the system tray. It'll be a red circle with a dragon symbol in it. Left click it to open the WireGuard window.

System Tray

  1. In the WireGuard window, use the "Add Tunnel" drop down to "Add empty tunnel". Add empty tunnel

  2. In the "Create new tunnel" dialog box give the tunnel a name and make note of the public key.

Create new tunnel

  1. add your client address to [interface]
[Interface]
PrivateKey = <YOUR CLIENT PRIVATE KEY>
Address = 10.20.30.102/24
  1. Add a peer section to the new tunnel with the server public key
[Peer]
PublicKey = FD+EO4rr6KWg3LBnHRATi1I6qoAk7J9rk0a2XDbpCD0=
AllowedIPs = 10.20.30.0/24
Endpoint = XXX.XXX.XXX.XXX:51820
PersistentKeepalive = 25

Press Save to save the tunnel configuration.

  1. ON THE SERVER ADD AN ENTRY FOR THIS
sudo wg set wg0 peer <PEER_PUBLIC_KEY> allowed-ips <PEER_IP_ADDRESS>/32

You can activate and deactivate the tunnel from the WireGuard window.

Create new tunnel

#macOS

  1. Get wireguard from the App store

App Store

  1. Once it's installed it'll automatically start. You can also launch it from Applications

  2. In the wireguard window, use the "Add Tunnel" drop down to "Add empty tunnel".

Add empty tunnel

  1. In the dialog box, give the new tunnel a name and note the public key.

I've checked OnDemand for WiFi to automatically activate the VPN when I'm on WiFi Dialog

  1. Add your client address to [interface]
[Interface]
PrivateKey = <YOUR CLIENT PRIVATE KEY>
Address = 10.20.30.103/24
  1. Add a peer section to the new tunnel with the server public key
[Peer]
PublicKey = FD+EO4rr6KWg3LBnHRATi1I6qoAk7J9rk0a2XDbpCD0=
AllowedIPs = 10.20.30.0/24
Endpoint = XXX.XXX.XXX.XXX:51820
PersistentKeepalive = 25
  1. Press save to save it. When you press save macOS will ask you if you'd like to add the VPN config. Press Allow.

ALlow

#Masquerading Wireguard Traffic

Sometimes you may want to route client traffic through the WireGuard server. I've enabled masquerading in the server configuration sections above. To complete this you need to do a few things to the client configuration.

#Setup DNS to go through the server.

You can get set DNS to a well known DNS server if you like, or try getting the dns used by your server. ON my linux server I use resolvectl dns eth0 to find its DNS servers.

$ resolvectl dns eth0
Link 2 (eth0): 172.232.0.13 172.232.0.22 172.232.0.9 172.232.0.19
        172.232.0.20 172.232.0.15 172.232.0.18 172.232.0.17
        172.232.0.16 172.232.0.21

I add a DNS line to the [Interface] section of the client configuration.

[Interface]
PrivateKey = <PRIVATE_KEY>
Address = 10.20.30.102/32

DNS = 172.232.0.13, 172.232.0.22

#Route all traffic through the VPN

Change the AllowedIPs to 0.0.0.0/0 (or add it)

[Peer]
PublicKey = FD+EO4rr6KWg3LBnHRATi1I6qoAk7J9rk0a2XDbpCD0=
AllowedIPs = 10.20.30.0/24, 0.0.0.0/0
Endpoint = 172.236.98.153:51820
PersistentKeepalive = 25