How to set up your own VPN on a VPS with WireGuard
A personal VPN you run yourself is one of the most useful things to put on a VPS: it encrypts your traffic on untrusted networks, hides your browsing from your local network and ISP, and lets you reach your own servers as if you were at home โ all on infrastructure only you control. WireGuard makes it fast and simple. This guide takes you from a fresh server to a working VPN in about fifteen minutes.
Contents
Why run your own VPN
With a commercial VPN you trust a company with all of your traffic. With your own WireGuard server, the only party in the middle is you. That means no shared logging, no mystery about retention policies, and a setup you can audit end to end. It's ideal for encrypting traffic on hotel or cafรฉ Wi-Fi, keeping your browsing private from your ISP, reaching a home lab or private services securely, and having a stable IP you control. WireGuard itself is modern, tiny, and fast โ it lives in the Linux kernel and outperforms older protocols like OpenVPN with a fraction of the configuration.
What you need
- A small VPS (the cheapest plan is plenty โ WireGuard barely uses resources).
- Root or sudo access to the server.
- A client device (laptop or phone) with the WireGuard app installed.
- About 15 minutes.
Need a server for it?
Deploy a VPS in minutes โ pay with Bitcoin, Monero or USDT. From $9/mo.
๐ Deploy a VPSStep 1 โ Deploy a VPS and install WireGuard
Deploy a Linux VPS (Ubuntu or Debian is easiest here) and, ideally, run through the basics in our VPS hardening checklist first. Then install WireGuard:
# Debian / Ubuntu sudo apt update && sudo apt install wireguard qrencode -y
Enable IP forwarding so the server can route your traffic to the internet:
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-wireguard.conf echo "net.ipv6.conf.all.forwarding = 1" | sudo tee -a /etc/sysctl.d/99-wireguard.conf sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
Step 2 โ Generate server keys
Create the server's private and public keys. The umask 077 keeps the private key readable only by root:
cd /etc/wireguard umask 077 wg genkey | sudo tee server_private.key | wg pubkey | sudo tee server_public.key
The command prints the public key; the private key is saved to server_private.key. You'll paste the private key into the config next.
Step 3 โ Configure the server
Find your server's main network interface โ on most cloud VPSes it's eth0, but check:
ip route show default # note the device after "dev", e.g. eth0
Create /etc/wireguard/wg0.conf. Replace SERVER_PRIVATE_KEY with the contents of server_private.key, and eth0 with your interface if different:
[Interface] Address = 10.8.0.1/24 ListenPort = 51820 PrivateKey = SERVER_PRIVATE_KEY 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
Open the WireGuard port in your firewall and start the service so it comes back after reboots:
sudo ufw allow 51820/udp sudo systemctl enable --now wg-quick@wg0 sudo wg # should show interface wg0 listening
Step 4 โ Add a client
Generate a key pair for your first device:
cd /etc/wireguard umask 077 wg genkey | sudo tee client1_private.key | wg pubkey | sudo tee client1_public.key
Create a client config โ call it client1.conf. Use the client private key, the server public key, and your server's public IP:
[Interface] PrivateKey = CLIENT1_PRIVATE_KEY Address = 10.8.0.2/32 DNS = 1.1.1.1 [Peer] PublicKey = SERVER_PUBLIC_KEY Endpoint = YOUR_SERVER_IP:51820 AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0, ::/0 routes all of the client's traffic through the VPN. Now register this client on the server by adding a [Peer] block to wg0.conf with the client's public key:
[Peer] PublicKey = CLIENT1_PUBLIC_KEY AllowedIPs = 10.8.0.2/32
Reload so the new peer is picked up without dropping the interface:
sudo systemctl restart wg-quick@wg0
Step 5 โ Connect and verify
On a laptop, copy client1.conf to your machine and import it into the WireGuard app (or run wg-quick up ./client1.conf). On a phone, turn the config into a QR code on the server and scan it with the WireGuard app:
qrencode -t ansiutf8 < client1.conf
Activate the tunnel, then confirm your public IP now matches the server:
curl https://ifconfig.me # should print your VPS's IP sudo wg # "latest handshake" confirms the tunnel is live
If the IP matches your server and you see a recent handshake, your VPN is working.
Tips and hardening
- One config per device. Give every device its own key pair and [Peer] with a unique address (10.8.0.3, 10.8.0.4, โฆ). Never share a single config across devices.
- Lock the firewall down. You only need UDP 51820 (WireGuard) and your SSH port open to the world. Everything else can stay closed โ see the hardening checklist.
- Pick a DNS you trust. The DNS = line decides who resolves your queries; use a resolver you're comfortable with, or run your own.
- Keep keys secret. Private keys never leave the device they belong to. If a device is lost, remove its [Peer] from the server to revoke access instantly.
- Mind the threat model. This protects the link between you and your server; it doesn't make you anonymous. For payment privacy on the server itself, see our coin comparison.
FAQ
Is a self-hosted WireGuard VPN more private than a commercial VPN?
How much does it cost to run my own VPN?
Does WireGuard work on phones?
Which port does WireGuard use?
GhostVPS is an anonymous, no-KYC VPS host on real DigitalOcean infrastructure. Pay with Bitcoin, Monero or USDT (TRC20); deploy in minutes from $9/mo. See pricing or open the panel.