Low Orbit Flux Logo 2 F

WireGuard Setup

WireGuard is a modern VPN protocol built into the Linux kernel since 5.6. It uses state-of-the-art cryptography (Curve25519, ChaCha20, Poly1305), has a tiny attack surface compared to OpenVPN or IPsec, and is significantly faster in benchmarks. Configuration is done through simple key pairs and interface files — there’s no certificate authority, no complex PKI.

This guide sets up a WireGuard server on Ubuntu/Debian and connects a Linux client to it. The server needs a public IP address. The client can be anywhere.


Install WireGuard

On both server and client:


sudo apt update
sudo apt install -y wireguard

Generate key pairs

WireGuard uses asymmetric key pairs. Each peer has a private key and a public key. Generate them on each machine — never share private keys.

On the server:


wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
sudo chmod 600 /etc/wireguard/server_private.key

On the client:


wg genkey | sudo tee /etc/wireguard/client_private.key | wg pubkey | sudo tee /etc/wireguard/client_public.key
sudo chmod 600 /etc/wireguard/client_private.key

View the keys so you can copy them into configs:


sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key
sudo cat /etc/wireguard/client_private.key
sudo cat /etc/wireguard/client_public.key

Enable IP forwarding on the server

The server needs to forward packets between the VPN interface and the internet. Add this to /etc/sysctl.conf:


sudo nano /etc/sysctl.conf

Add or uncomment this line:


net.ipv4.ip_forward=1

Apply it immediately without rebooting:


sudo sysctl -p

Server configuration

Create /etc/wireguard/wg0.conf on the server. Replace the placeholder values with your actual keys and your server’s public IP address.


sudo nano /etc/wireguard/wg0.conf

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY

# Replace eth0 with your actual network interface (check with: ip link show)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32

Set correct permissions:


sudo chmod 600 /etc/wireguard/wg0.conf

Client configuration

Create /etc/wireguard/wg0.conf on the client. Replace SERVER_PUBLIC_IP with the actual IP address of your server.


sudo nano /etc/wireguard/wg0.conf

[Interface]
Address = 10.0.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

AllowedIPs = 0.0.0.0/0 routes all traffic through the VPN. To route only the VPN subnet (split tunnel), use 10.0.0.0/24 instead.

PersistentKeepalive = 25 sends a keepalive packet every 25 seconds to maintain the connection through NAT.


Start and enable WireGuard

On both server and client:


sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

Check status:


sudo wg show

Open the firewall port

On the server, allow UDP traffic on port 51820:


sudo ufw allow 51820/udp
sudo ufw reload

Test the connection

From the client, ping the server’s WireGuard interface:


ping 10.0.0.1

Check your public IP to confirm traffic is going through the VPN:


curl ifconfig.me

It should return the server’s public IP if AllowedIPs = 0.0.0.0/0 is set.


Adding more clients

For each additional client, generate a new key pair on that client, then add a new [Peer] block to the server config with a unique AllowedIPs address (e.g. 10.0.0.3/32). Reload the server config without dropping existing connections:


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

Useful commands


sudo wg show              # show interface status and peer info
sudo wg showconf wg0      # show the running config
sudo systemctl restart wg-quick@wg0
sudo journalctl -u wg-quick@wg0 -f   # live logs