WireGuard VPN server setup
Updated
To set up a WireGuard VPN server, install wireguard, generate a key pair for the server and for each client, write /etc/wireguard/wg0.conf with a private subnet, enable IP forwarding and NAT, open one UDP port and start wg-quick@wg0. On Ubuntu 24.04 or Debian 12 it takes about ten minutes.
WireGuard is small, fast and built into the Linux kernel. It is a good fit for a personal VPN with a German exit, for remote access to a company network, or for linking servers.
What you need
- A VPS with a public IPv4 address (IPv6 is a bonus). A 1 vCPU / 1 GB plan is plenty. A Frankfurt VPS gives low latency across Europe.
- Root or sudo access.
- The WireGuard app on each client: Windows, macOS, Linux, Android or iOS.
In the examples:
| Item | Example value |
|---|---|
| Server public address | 203.0.113.10 |
| VPN subnet | 10.8.0.0/24 |
| Server tunnel address | 10.8.0.1 |
| First client | 10.8.0.2 |
| UDP port | 51820 |
Replace them with your own. Prefer a shortcut? On Wolkra, choose the WireGuard one-click app when you create the server and skip to step 7.
1. Install WireGuard
sudo apt update
sudo apt install -y wireguard qrencode
qrencode lets you show client configs as QR codes for phones.
2. Generate the server keys
sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
umask 077 makes sure the private key is readable only by root.
3. Find the public network interface
ip route show default
The word after dev is your public interface, usually eth0 or ens3. The examples use eth0.
4. Write the server config
Create /etc/wireguard/wg0.conf:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <contents of server.key>
# NAT for VPN clients going out to the internet
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
Paste the key with:
sed -i "s|<contents of server.key>|$(cat server.key)|" wg0.conf
chmod 600 wg0.conf
Debian 12 and Ubuntu 24.04 use nftables underneath, and the iptables command works through the nftables backend, so the rules above work on both.
5. Enable IP forwarding
echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-wireguard.conf
sysctl --system
6. Open the firewall and start the tunnel
With UFW:
ufw allow 51820/udp
ufw route allow in on wg0 out on eth0
ufw reload
ufw route allow lets forwarded traffic from the tunnel out to the internet. Without it, clients connect but have no internet.
If you use a Wolkra firewall, add an inbound rule for UDP 51820 there too.
Start WireGuard and enable it at boot:
systemctl enable --now wg-quick@wg0
wg show
wg show should list the wg0 interface and its listening port.
7. Add a client
Generate keys for the client on the server (or on the client device, which is slightly safer because the private key never leaves it):
cd /etc/wireguard
wg genkey | tee laptop.key | wg pubkey > laptop.pub
Add the client as a peer to the running server and save the config:
wg set wg0 peer "$(cat laptop.pub)" allowed-ips 10.8.0.2/32
wg-quick save wg0
wg-quick save writes the live state back into wg0.conf, so the peer survives a restart.
8. Write the client config
Create laptop.conf:
[Interface]
PrivateKey = <contents of laptop.key>
Address = 10.8.0.2/32
DNS = <your resolver>
[Peer]
PublicKey = <contents of server.pub>
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0, ::/0sends all traffic through the VPN (a full tunnel).- For a split tunnel that only reaches your private network, use for example
AllowedIPs = 10.8.0.0/24, 10.0.0.0/24. PersistentKeepalivekeeps the tunnel open behind home routers and mobile networks.DNSis the address of a resolver you trust, for example a public resolver or one you run on the server.
Import on a phone
qrencode -t ansiutf8 < laptop.conf
Open the WireGuard app, choose Scan from QR code and point it at the terminal.
Import on a computer
Copy laptop.conf to the device securely (for example with scp) and import it into the WireGuard app, or on Linux:
sudo cp laptop.conf /etc/wireguard/wg0.conf
sudo wg-quick up wg0
On a Linux client, wg-quick sets DNS through resolvconf. If it complains that the command is missing, install openresolv (Debian) or remove the DNS line and configure DNS yourself.
Delete the client's private key from the server afterwards if you generated it there.
9. Test the tunnel
On the client, connect and check the public address:
curl -4 https://ifconfig.me
It should show the server's address. On the server:
wg show
A recent "latest handshake" and growing transfer counters mean the peer is connected.
Adding IPv6 to the tunnel
If your server has an IPv6 address, you can give clients IPv6 too. Add a private IPv6 range (a unique local address such as fd42:42:42::1/64) to the server's Address, a matching address per client, enable net.ipv6.conf.all.forwarding=1, and add an ip6tables masquerade rule like the IPv4 one. Without that, keep ::/0 out of the client's AllowedIPs or IPv6 traffic will be dropped rather than leak.
Troubleshooting
| Symptom | Check |
|---|---|
| No handshake | UDP port open in UFW and the cloud firewall? Correct endpoint and public key? |
| Handshake but no internet | ip_forward set? NAT rule on the right interface? ufw route allow added? |
| Websites load slowly | Try lowering MTU: add MTU = 1380 to the client [Interface] |
| Works on Wi-Fi, not mobile | Add PersistentKeepalive = 25 |
journalctl -u wg-quick@wg0 shows errors from start-up.
Traffic and cost
A VPN doubles the traffic on the server: data comes in from the internet and goes out to the client. On metered plans that adds up quickly. Wolkra servers have unmetered bandwidth with no per-GB fees, on shared ports up to 10 Gbit/s under fair use. Note that the acceptable use policy still applies to everything that passes through your VPN.
For more on why people run their own, see VPN server use cases. To harden the host itself, follow how to secure an Ubuntu server, but skip the sysctl redirect settings that conflict with routing.
Frequently asked questions
How much server do I need for WireGuard?
Very little. WireGuard runs in the kernel and a 1 vCPU, 1 GB server easily handles a household or small team.
Which port does WireGuard use?
Any UDP port you choose. 51820 is the common default; open it in both the server firewall and any cloud firewall.
Does a VPN server use a lot of traffic?
Yes, every byte a client uses passes through the server in and out. An unmetered plan avoids per-GB fees for that.
Is there an easier way than configuring WireGuard by hand?
On Wolkra you can pick the WireGuard one-click app when you create a server. It is ready a few minutes after boot.
Can I use WireGuard to reach private servers?
Yes. Route your private network range through the tunnel instead of all traffic, and clients can reach servers that have no public IP.