Configure WireGuard VPN on Ubuntu Server 24.04 (With Clients, Firewall, and Split Tunneling)

Why WireGuard for a Modern VPN?

WireGuard has become a go-to VPN choice because it is fast, lightweight, and easier to maintain than many traditional VPN stacks. It uses modern cryptography, keeps configuration simple (a few keys and IPs), and performs well on cloud servers and home labs. In this tutorial, you will set up a secure WireGuard VPN server on Ubuntu Server 24.04, add clients, lock it down with a firewall, and optionally configure split tunneling so only specific traffic goes through the VPN.

What You Need

Before starting, make sure you have: (1) an Ubuntu Server 24.04 machine with sudo access, (2) a public IP address or a DNS name (for remote access), (3) UDP port 51820 available (or another port you choose), and (4) IP forwarding allowed (we will enable it). These steps work on a VPS and on-prem servers; for home routers you will also need port forwarding.

Step 1: Install WireGuard

Update packages and install WireGuard:

sudo apt update && sudo apt install -y wireguard

Ubuntu 24.04 ships with modern kernels and WireGuard support, so you don’t need extra repositories.

Step 2: Generate Server Keys

Create a secure directory and generate keys:

sudo umask 077
sudo mkdir -p /etc/wireguard
cd /etc/wireguard
sudo wg genkey | sudo tee server_private.key | sudo wg pubkey | sudo tee server_public.key

Your private key must remain secret. The public key will be shared with clients.

Step 3: Create the Server Configuration (wg0)

Decide on a VPN subnet. A common choice is 10.10.0.0/24. Create /etc/wireguard/wg0.conf:

sudo nano /etc/wireguard/wg0.conf

Paste and adjust the following (replace eth0 if your interface name differs):

[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = (paste contents of /etc/wireguard/server_private.key)
PostUp = ufw route allow in on wg0 out on eth0
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

This enables NAT so VPN clients can reach the internet through the server (useful for secure browsing on public Wi-Fi). If you only need access to internal networks, you can skip NAT later and use routing instead.

Step 4: Enable IP Forwarding

Enable forwarding so the server can route traffic:

sudo nano /etc/sysctl.conf

Uncomment or add:

net.ipv4.ip_forward=1

Apply the change:

sudo sysctl -p

Step 5: Configure UFW Firewall

Allow SSH (if needed) and WireGuard’s UDP port:

sudo ufw allow OpenSSH
sudo ufw allow 51820/udp

Enable the firewall:

sudo ufw enable

If you are on a cloud provider, also open the same UDP port in the provider’s security group/firewall.

Step 6: Start WireGuard and Enable Autostart

Bring up the interface and enable it on boot:

sudo systemctl enable --now wg-quick@wg0

Verify status:

sudo wg
ip a show wg0

Step 7: Add a Client (Laptop/Phone)

On the server, generate a client key pair (example: client1):

cd /etc/wireguard
sudo wg genkey | sudo tee client1_private.key | sudo wg pubkey | sudo tee client1_public.key

Now add the client as a peer to the server. Edit /etc/wireguard/wg0.conf and append:

[Peer]
PublicKey = (paste contents of client1_public.key)
AllowedIPs = 10.10.0.2/32

Apply changes without dropping the tunnel:

sudo wg syncconf wg0 <(sudo wg-quick strip wg0)

Step 8: Create the Client Configuration

On your client device (or on the server to copy later), create a config named client1.conf:

[Interface]
PrivateKey = (paste contents of client1_private.key)
Address = 10.10.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = (paste contents of server_public.key)
Endpoint = YOUR_SERVER_IP_OR_DNS:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

The setting AllowedIPs = 0.0.0.0/0 routes all traffic through the VPN (full tunnel). PersistentKeepalive helps devices behind NAT stay connected.

Optional: Split Tunneling (Route Only What You Need)

If you only want access to the VPN subnet (and keep normal internet direct), change the client’s AllowedIPs to:

AllowedIPs = 10.10.0.0/24

If you need access to a private LAN behind the server (for example 192.168.1.0/24), add it:

AllowedIPs = 10.10.0.0/24, 192.168.1.0/24

Troubleshooting Tips

If the handshake does not happen, first confirm UDP port access from the internet and double-check the Endpoint. Run sudo wg on the server to see “latest handshake” timestamps. If clients connect but cannot browse the internet, re-check NAT rules and that IP forwarding is enabled. Also confirm your server interface name (use ip route to find it) and replace eth0 in the config if needed.

Next Steps

Once your first client works, repeat the peer/client steps for additional devices, giving each client a unique VPN IP (10.10.0.3/32, 10.10.0.4/32, and so on). For easier operations at scale, consider keeping a simple IP assignment list and backing up /etc/wireguard. With this setup, you now have a modern VPN that is fast, secure, and straightforward to maintain.

Comments