A WireGuard VPS is the simplest way to run a VPN that only you and your team use. WireGuard is small, fast to set up and built into the Linux kernel, so a modest server can carry several devices without effort. This guide builds one on an Amsterdam server from scratch: install, keys, server and client configuration, NAT, firewall and the mistakes that usually cause "connected but no internet". It ends with an honest look at when a self-built VPN is the wrong choice.
Why Amsterdam for a WireGuard VPS
Amsterdam is one of Western Europe's major internet hubs, which makes it a balanced exit point if your devices move between countries in the EU or you need a European IP for work. Cloudj's Amsterdam servers include 5 TB of traffic on monthly plans, which matters for a VPN because every page, video and download on your devices passes through the server. For more on the location, read best VPS in the Netherlands; the Europe VPS guide compares it with Frankfurt, London and the other European cities.
A VPN for a handful of devices is light work. The smallest size, 1 vCPU and 1 GB RAM, is enough for personal use; shared CPU is fine. If several people stream or move large files through it at once, add a vCPU.
A note on rules before you start
Running your own VPN is legal in most places, but what you do through it is still governed by local law and by each service's terms. Use it to secure your traffic on public Wi-Fi, reach your own servers or work from a fixed European IP. Do not use it to get around a platform's rules or to hide abuse; the IP is registered to your server and your account.
Step 1: install WireGuard
Deploy an Ubuntu 24.04 server (check the OS list for your location in the console), log in over SSH and install the tools:
sudo apt update && sudo apt install -y wireguard qrencode
Step 2: generate keys
Each side has a private key that never leaves the device and a public key you share. Generate the server's pair and one for your first client:
sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee laptop.key | wg pubkey > laptop.pub
Stay in this root shell for the next steps (type exit when you are done); cat server.key and the other files print the keys you will paste below.
Generating client keys on the server is convenient for phones that you will set up with a QR code. For laptops you can generate the key on the laptop instead, so the private key never exists anywhere else.
Step 3: find the public interface
NAT rules need the name of the interface that faces the internet:
ip route show default
The name after dev (often eth0 or ens3) is the one to use below.
Step 4: write the server configuration
Create /etc/wireguard/wg0.conf, replacing the keys with the contents of server.key and laptop.pub, and eth0 with your interface:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
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]
# laptop
PublicKey = LAPTOP_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
AllowedIPs on the server side says which tunnel address belongs to this peer. Each new device gets the next address: 10.8.0.3/32, 10.8.0.4/32 and so on.
Step 5: enable forwarding and the firewall
The server must forward packets between the tunnel and the internet:
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system
Open SSH and WireGuard's UDP port, allow routed traffic from the tunnel out to the internet, then enable UFW:
sudo ufw allow OpenSSH
sudo ufw allow 51820/udp
sudo ufw route allow in on wg0 out on eth0
sudo ufw enable
UFW blocks forwarded traffic by default, so the route allow rule is what makes browsing work. Replies come back through UFW's built-in rule for established connections. The UFW firewall guide explains the rule types in more depth.
Step 6: start the tunnel
sudo systemctl enable --now wg-quick@wg0
sudo wg show
wg show lists the interface, the listening port and each peer. A peer shows a "latest handshake" once it has connected.
Step 7: configure the client
Create laptop.conf with the laptop's private key and the server's public key and IP:
[Interface]
PrivateKey = LAPTOP_PRIVATE_KEY
Address = 10.8.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = 203.0.113.20:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0, ::/0 sends all traffic through the tunnel. Including ::/0 keeps IPv6 traffic from leaking around the VPN even when the tunnel carries only IPv4. If you only want to reach your servers, list their addresses instead (split tunnel).
Import the file into the official WireGuard app on Windows or macOS, or on Linux run sudo wg-quick up ./laptop.conf. For a phone, show a QR code in the terminal and scan it from the WireGuard app:
qrencode -t ansiutf8 < phone.conf
Delete client private keys from the server once the devices are set up. Official clients for every platform are listed on wireguard.com.
Adding more devices without a restart
Add a new [Peer] block to wg0.conf, then apply the change without dropping existing connections:
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'
When it connects but nothing loads
Work through these in order:
- No handshake in
wg show. UDP 51820 is blocked, the endpoint IP is wrong, or the keys are swapped. Check that the client has the server's public key and vice versa. - Handshake, but no internet. Forwarding is off (
sysctl net.ipv4.ip_forwardshould print 1), the interface name in the NAT rule is wrong, or the UFW route rule is missing. - Some sites fail, others work. Usually a packet-size problem on certain networks. Add
MTU = 1380to the client's[Interface]and reconnect. - Names do not resolve. The
DNSline is missing from the client config, or the client's operating system ignores it.
When to choose something else
A self-built VPN gives you one IP in one city, which you maintain yourself: updates, keys, and the occasional broken handshake. If you would rather not run a server, Cloudj also offers a VPN service. If what you actually need is a fixed IP for browser profiles or scraping tools rather than an encrypted tunnel for whole devices, a dedicated proxy is usually the better fit. And if the same server should also host other things, such as a self-hosted Git server or a game server like in the Minecraft on a German VPS guide, WireGuard is a good way to keep their admin panels off the public internet.
FAQ
Which port does WireGuard use?
Any UDP port you choose; 51820 is the convention. It does not use TCP, so open the UDP port in the firewall.
How many devices can one small VPS handle?
A personal VPN with a few phones and laptops runs well on the smallest size. Watch CPU and network graphs in the console and resize if several people use it heavily at the same time.
Is WireGuard better than OpenVPN?
WireGuard has a much smaller codebase and simpler configuration, and it is built into the Linux kernel. OpenVPN can run over TCP, which sometimes helps on networks that block UDP.
Does traffic through the VPN count toward my allowance?
Yes. VPN traffic is ordinary server traffic. Monthly plans in Amsterdam include 5 TB; on hourly billing traffic is charged per GB used, and the console graphs show how much you move.
Set up your Amsterdam VPN
A small Amsterdam server and twenty minutes of setup give you a private WireGuard VPN under your own control. See live prices on the pricing page or deploy from the Cloudj console.