- WireGuard is a VPN protocol built into the Linux kernel since 5.6: on an Ubuntu or Debian VPS it installs with
sudo apt install wireguardand is configured in a single file,/etc/wireguard/wg0.conf. - A WireGuard server listens on UDP port 51820 by default; that is the only port to open in the firewall -
sudo ufw allow 51820/udp. - To route all of a client's traffic through the VPS, the server enables
net.ipv4.ip_forward=1and NAT (iptables MASQUERADE), and the client config setsAllowedIPs = 0.0.0.0/0. - A WireGuard config moves to a phone as a QR code:
qrencode -t ansiutf8 < phone.confdraws it right in the terminal for the official WireGuard app to scan. - A personal VPN for one or two people fits a VPS with 1 vCPU and 2 GB of RAM - on Tihost such a server costs $4.00 a month.
Why run your own VPN on a VPS?
- A secure connection on public Wi-Fi - in a cafe, hotel or airport all your traffic travels to your own server inside an encrypted tunnel;
- access to your own services - admin panels, databases and monitoring can be closed to the internet and opened only to the VPN network
10.8.0.0/24; - access to your home network - a home router or mini server joins the same VPS as one more client, and you reach it from anywhere;
- a fixed IP - work systems, panels and firewalls only need one public IPv4 address, the server's, in their allowlists.
WireGuard is simpler than OpenVPN and IPsec: the config is a dozen lines, keys are short strings much like SSH keys, and the connection recovers on its own when the network changes, for example when you move from Wi-Fi to mobile data. Protocol details are at wireguard.com.
What server does WireGuard need?
WireGuard runs in the kernel and barely touches the CPU, so the smallest Starter configuration - 1 vCPU and 2 GB of RAM for $4.00 a month - is enough for one or two people. What matters is that the VPS uses full KVM virtualization with its own kernel - on Tihost it does. Pick a location close to you: the lower the latency to the server, the less noticeable the VPN. Comparing Germany, Finland and Poland is covered in the guide to choosing a VPS location.
Step 1. Install WireGuard
The wireguard package installs the wg and wg-quick tools, qrencode is needed for the QR code, and iptables for NAT (a minimal Debian 12 install may not have it):
sudo apt update
sudo apt install -y wireguard qrencode iptablesStep 2. Generate server and client keys
Each side of the tunnel has a key pair: the private key stays with its owner, and the public key goes to the other side. umask 077 makes new files readable by root only. The last command prints the keys - you will need them in the configs:
sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee phone.key | wg pubkey > phone.pub
cat server.key server.pub phone.key phone.pubStep 3. Create the server config wg0.conf
First find the name of the external network interface - it follows the word dev in the default route. It is often eth0 or ens3:
ip route list default
# default via 203.0.113.1 dev eth0 proto staticCreate /etc/wireguard/wg0.conf and fill in the keys. If the interface is not called eth0, replace it in the PostUp and PostDown lines. PostUp allows packet forwarding and enables NAT (MASQUERADE) when the tunnel starts, so clients reach the internet with the server's IP; PostDown removes those rules when it stops:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <contents of server.key>
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# phone
PublicKey = <contents of phone.pub>
AllowedIPs = 10.8.0.2/32Step 4. Enable packet forwarding
By default Linux does not forward packets between interfaces, so client traffic would stop at the server. net.ipv4.ip_forward=1 turns forwarding on, and the file in /etc/sysctl.d/ keeps it after a reboot:
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.confStep 5. Open port 51820/udp
WireGuard runs over UDP, and the server only needs the ListenPort port open to the outside. WireGuard does not answer packets without a valid key, so a port scanner cannot tell a VPN is running on the server:
sudo ufw allow 51820/udp
sudo ufw statusStep 6. Start the tunnel
wg-quick@wg0 is a systemd service that brings up the wg0 interface from the config and starts at boot. wg show should list the interface, port 51820 and one peer - the phone:
sudo systemctl enable --now wg-quick@wg0
sudo wg showStep 7. Prepare the client config
The client config mirrors the server's: its own private key, the server's public key and the server address in Endpoint (put in your VPS IP). AllowedIPs = 0.0.0.0/0 sends all IPv4 traffic into the tunnel, DNS sets the DNS server while connected, and PersistentKeepalive = 25 sends a packet every 25 seconds so the connection survives the NAT of a home router or mobile carrier:
[Interface]
PrivateKey = <contents of phone.key>
Address = 10.8.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = <contents of server.pub>
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25If the VPN is only for reaching your own services rather than all traffic, set AllowedIPs = 10.8.0.0/24 - then only VPN network addresses go through the tunnel.
Step 8. Move the config to your phone with a QR code
Save the client config on the server as /etc/wireguard/phone.conf and print it as a QR code right in the terminal. In the WireGuard app for Android or iOS tap the + button and choose to scan a QR code; on a computer, import the config as a file:
sudo nano /etc/wireguard/phone.conf
sudo qrencode -t ansiutf8 < /etc/wireguard/phone.confStep 9. Check the connection
Turn the tunnel on in the app and run wg show on the server: the peer should now show a latest handshake line with the time of the last handshake and a transfer line with the traffic volume. Any IP-check service on the phone should show your VPS address:
sudo wg showIf there is no handshake, check that port 51820/udp is open in UFW and that Endpoint has the right IP. If there is a handshake but websites do not load, check ip_forward and the interface name in PostUp.
How to add another device
Generate a separate key pair for each device, add a new [Peer] block to wg0.conf with the next address (10.8.0.3/32, 10.8.0.4/32 and so on) and restart the tunnel. Do not share one config between devices: two clients with the same key keep knocking each other off.
sudo nano /etc/wireguard/wg0.conf
sudo systemctl restart wg-quick@wg0AMD Ryzen 9, NVMe and DDoS protection in Germany, Finland and Poland. Pay with crypto or card.
FAQ
Which port does WireGuard use?
WireGuard uses UDP port 51820 by default - it is set by ListenPort in the server config. That is the only port to open in the firewall: sudo ufw allow 51820/udp.
How many resources does a VPS need for WireGuard?
WireGuard runs in the Linux kernel and puts almost no load on the server: a personal VPN for several devices fits a VPS with 1 vCPU and 2 GB of RAM. On Tihost that configuration costs $4.00 a month.
How is WireGuard different from OpenVPN?
WireGuard is simpler to set up - a dozen-line config and SSH-style keys - runs in the Linux kernel and quickly recovers when the network changes. OpenVPN is older, runs in user space and is more flexible, but more complex.
Why does WireGuard connect but the internet does not work?
Most often packet forwarding is off on the server (net.ipv4.ip_forward=1) or the MASQUERADE rule names the wrong network interface. ip route list default shows the interface name - it follows the word dev.
How do I connect a phone to WireGuard?
Save the client config on the server and run qrencode -t ansiutf8 < phone.conf - a QR code appears in the terminal. In the WireGuard app for Android or iOS choose to add a tunnel by scanning a QR code.
Can WireGuard carry only part of my traffic?
Yes. Set AllowedIPs = 10.8.0.0/24 instead of 0.0.0.0/0 in the WireGuard client config - then only VPN network addresses go through the tunnel and everything else goes direct.