🛠️ ITBlogs.pro

Set Up a WireGuard VPN Server on Ubuntu 24.04

Oct 16, 2026 · Networking · 5 min read

WireGuard is a modern VPN: small, fast and configured with a few lines. This guide builds a server on Ubuntu 24.04 and connects one client, either routing all traffic through the server or just reaching its private network.

How WireGuard thinks

  • Every device has a key pair. You exchange only the public keys.
  • Each peer has an AllowedIPs list that acts as both a routing table (which traffic goes into the tunnel) and an access filter (which source addresses are accepted from that peer).
  • There are no "servers" at the protocol level, only peers. The one with a public IP and a fixed port plays the server.
  • It uses UDP only (default port 51820).

Plan: the VPN network will be 10.8.0.0/24. Server = 10.8.0.1, first client = 10.8.0.2. Choose a range that doesn't overlap your home or office LAN. See subnetting basics.

1. Install and create the server keys

sudo apt update && sudo apt install -y wireguard
sudo sh -c 'umask 077; wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub'
sudo cat /etc/wireguard/server.pub

2. Create a key pair for the client

Run this on the client (so its private key never leaves it). On Linux:

sudo apt install -y wireguard
umask 077; wg genkey | tee client.key | wg pubkey > client.pub
cat client.pub

The Windows, macOS, Android and iOS apps generate keys for you when you add an empty tunnel.

3. Server configuration

Find your public network interface name (eth0 below):

ip -br addr

Create /etc/wireguard/wg0.conf:

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <contents of /etc/wireguard/server.key>

# NAT, so clients can reach the internet through the server (full-tunnel mode)
PostUp   = iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

[Peer]
# my laptop
PublicKey = <contents of client.pub>
AllowedIPs = 10.8.0.2/32
sudo chmod 600 /etc/wireguard/wg0.conf

4. Enable forwarding and open the firewall

echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system

sudo ufw allow 51820/udp
sudo ufw route allow in on wg0 out on eth0

If you use a cloud firewall at your hosting provider, allow UDP 51820 there too. See securing a new server for the basic firewall setup.

5. Start it

sudo systemctl enable --now wg-quick@wg0
sudo wg show

wg show lists the interface and peers. A peer with no latest handshake hasn't connected yet.

6. Client configuration

[Interface]
PrivateKey = <contents of client.key>
Address = 10.8.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <contents of /etc/wireguard/server.pub>
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Choose AllowedIPs according to what you want:

AllowedIPs Effect
0.0.0.0/0 Full tunnel: all IPv4 traffic goes through the server
10.8.0.0/24 Split tunnel: only VPN-network traffic. Normal internet stays direct
10.8.0.0/24, 192.168.50.0/24 VPN network plus a LAN behind the server

Don't add ::/0 for full tunnel unless the server has working IPv6 forwarding. Otherwise all IPv6 traffic on the client disappears into the tunnel and goes nowhere.

On a Linux client save it as /etc/wireguard/wg0.conf and run:

sudo wg-quick up wg0
curl ifconfig.me           # shows the server's IP in full-tunnel mode
sudo wg-quick down wg0

For a phone, show the config as a QR code on the machine that has it:

sudo apt install -y qrencode
qrencode -t ansiutf8 < client.conf

Scan it from the WireGuard app.

Adding more clients

Give each client its own key pair and its own 10.8.0.x/32, and add another [Peer] block on the server. Apply without dropping existing connections:

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

Troubleshooting

Symptom Check
No handshake in wg show UDP 51820 not reachable: server firewall, cloud firewall, wrong Endpoint, wrong public key on either side
Handshake OK, no internet through the VPN ip_forward off, missing MASQUERADE rule, wrong interface name in PostUp, or ufw route missing
Can ping 10.8.0.1 but nothing else Forwarding/NAT again, or AllowedIPs too narrow
Some sites hang MTU too high, so set MTU = 1380 in the client [Interface]
DNS fails once connected Set DNS = on the client, and make sure the resolver is reachable through the tunnel
Works on Wi-Fi, not on mobile data Some carriers block UDP ports, so try another port such as 443

Debug on the server with:

sudo wg show
sudo tcpdump -ni any udp port 51820

If packets arrive but there's no handshake, the keys are mismatched. If nothing arrives, it's a firewall or DNS problem on the way (see diagnosing connectivity).

Cloudflare note: the orange-cloud proxy only handles HTTP(S). A VPN endpoint must use a DNS-only record (grey cloud) or the plain IP address.

Security notes

  • Keep the private keys (*.key, and the PrivateKey line) secret, and never commit them to Git.
  • AllowedIPs on the server restricts what each client can spoof, so use /32 per client.
  • Removing access is simple: delete the peer on the server.
  • You can also add a pre-shared key per peer (wg genpsk), which adds an extra layer of symmetric-key protection on top of the normal key exchange.

Easier alternative

Tailscale is built on WireGuard and handles keys, NAT traversal and DNS for you, with no open ports on the server. It's a good choice if you mostly want to reach your own machines securely. Hand-written WireGuard gives you full control and no third-party coordination server.