All guides
Getting started
VPS
- VPS operating systems
- VPS snapshots and
off-site backups - How to host your own VPN on a VPS with WireGuard
- How to run a Tor relay, bridge or onion service on a VPS
- How to
self-host BTCPay Server on a VPS - How to run a Bitcoin or Monero node on a VPS
Dedicated servers
- Using IPMI and the KVM console on a dedicated server
- Choosing a RAID layout for your dedicated server
Windows RDP
Windows Server 2019 , 2022 or 2025 vsWindows 10 and 11 for RDP- How to connect to a Windows RDP server from any device
GPU servers
Security
On this page
- Before you start: what your WireGuard VPS needs
- Install WireGuard on Ubuntu or Debian
- Generate the server and client keys
- Write the WireGuard server configuration
- Enable IP forwarding
- Open the firewall
- Start the tunnel and enable it at boot
- Add a client
- Add IPv6 (optional)
- Check for leaks
- Keep your WireGuard VPS updated and add more clients
- Troubleshooting
- Frequently asked questions
To host your own VPN on a VPS with WireGuard, install the wireguard/etc/wireguard/wg0.confwg-quick@wg0
These steps set up a WireGuard VPS on an Offshore VPS running SERVER_IPeth0
Before you start: what your WireGuard VPS needs
- A VPS with a public IPv4 address. Every plan includes a dedicated IPv4 address and a /64 IPv6 block.
- Root access over SSH.
- The WireGuard app on each device. The WireGuard install page lists official apps for Windows, macOS, iOS and Android; Linux computers use the
package.wireguard-tools
The smallest plan is enough. WireGuard runs inside the Linux kernel and needs little memory, so the Dinghy plan (
A location close to you keeps browsing fast; one in another country changes which law applies to the server. Compare latency on the network page and read our guide to an offshore VPS for a VPN before you choose. As for any
Our acceptable use policy lists VPNs among the welcome uses. Your devices' traffic leaves with your server's IP address, so abuse sent through the tunnel counts as coming from your server: give access only to people you trust. Outbound
Install WireGuard on Ubuntu or Debian
To set up WireGuard on
apt update
apt install -y wireguard ufw qrencode
wg --version
The wireguardwgwg-quickufwiptablesqrencode
Generate the server and client keys
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee laptop.key | wg pubkey > laptop.pub
umask 077/etc/wireguardwg genkeywg pubkey
Use one key pair per device, named after it, so you can revoke one device without touching the others. You can also generate a device's keys on the device itself and copy only its public key to the server.
Write the WireGuard server configuration
The whole WireGuard server setup lives in one file. First find the interface that carries the server's internet traffic:
ip route show default
The word after deveth0ens3enp1s0$(cat ...)
cat > /etc/wireguard/wg0.conf <<EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = $(cat /etc/wireguard/server.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 = $(cat /etc/wireguard/laptop.pub)
AllowedIPs = 10.8.0.2/32
EOF
chmod 600 /etc/wireguard/wg0.conf
- Address
- The server's address inside the tunnel. The private range
leaves room for 253 devices.10.8.0.0/24 - ListenPort
- The UDP port that devices connect to; 51820 is the one in WireGuard's own examples.
- PrivateKey
- The server's private key, which is why the file stays readable by root only.
- PostUp and PostDown
- Commands that
runs with bash when the tunnel starts and stops, as its manual page describes. Here they add and remove NAT, so devices go online with the server's IPv4 address.wg-quick - [Peer]
- One block per device. WireGuard drops any packet from a device whose source address is outside its
, a design it calls cryptokey routing.AllowedIPs
Enable IP forwarding
Linux passes packets between interfaces only when forwarding is on, and the kernel documentation lists it as off by default. Turn it on now and at every boot:
echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-wireguard.conf
sysctl --system
sysctl net.ipv4.ip_forward
The last command must print net.ipv4.ip_forward = 1sysctl --system/etc/sysctl.d
Open the firewall
Allow SSH first, so that enabling UFW cannot cut you off, then the WireGuard port and the tunnel's route out:
ufw allow 22/tcp
ufw allow 51820/udp
ufw route allow in on wg0 out on eth0
ufw enable
ufw status verbose
Allow your own SSH port instead of 22 if you changed it with the hardening guide. ufw enableydeny (routed)routeeth0
With nftables instead of UFW
If you keep your own /etc/nftables.confPostUpPostDownwg0.confudp dport 51820 acceptinput
table inet wg-nat {
chain postrouting {
type nat hook postrouting priority srcnat;
ip saddr 10.8.0.0/24 oifname "eth0" masquerade
}
}
Check the file, then load it:
nft -c -f /etc/nftables.conf
nft -f /etc/nftables.conf
Written in the file, the NAT rule survives reloads. Added by PostUpflush ruleset
Start the tunnel and enable it at boot
systemctl enable --now wg-quick@wg0
wg show
wg-quick@wg0wg0.confwg0PostUpwg showlistening port: 51820journalctl -u wg-quick@wg0 -b
Add a client
A laptop or desktop: a configuration file
Write the laptop's file on the server, with your server's IPv4 address in place of SERVER_IP
umask 077
cat > /etc/wireguard/laptop.conf <<EOF
[Interface]
PrivateKey = $(cat /etc/wireguard/laptop.key)
Address = 10.8.0.2/32
DNS = 9.9.9.9
[Peer]
PublicKey = $(cat /etc/wireguard/server.pub)
Endpoint = SERVER_IP:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF
- AllowedIPs = 0.0.0.0/0, ::/0
- All traffic goes through the tunnel. Keep
even without IPv6 on the server: IPv6 then enters the tunnel and is dropped there, instead of leaking around it.::/0 - DNS
- 9.9.9.9 is Quad9, which blocks malware domains and validates DNSSEC; any resolver you trust works. Queries travel inside the tunnel.
- PersistentKeepalive = 25
- Stops home routers and mobile networks from closing the connection. WireGuard's quick start calls
25 seconds "a sensible interval that works with a wide variety of firewalls".
Copy the file from the laptop (if root logins are off after hardening, copy it through your sudo user), then delete the laptop's private key and file from the server, which needs only the public key:
scp root@SERVER_IP:/etc/wireguard/laptop.conf .
rm /etc/wireguard/laptop.key /etc/wireguard/laptop.conf
On Windows and macOS, import the file in the WireGuard app. On Linux, copy it to /etc/wireguard/wg-quick up laptopDNSopenresolv
A phone: scan a QR code
A phone needs its own keys, address and [Peer]
cd /etc/wireguard
umask 077
wg genkey | tee phone.key | wg pubkey > phone.pub
cat >> /etc/wireguard/wg0.conf <<EOF
[Peer]
# phone
PublicKey = $(cat /etc/wireguard/phone.pub)
AllowedIPs = 10.8.0.3/32
EOF
systemctl reload wg-quick@wg0
Write phone.conflaptop.confphone.key10.8.0.3/32
qrencode -t ansiutf8 < /etc/wireguard/phone.conf
Scan it with the WireGuard app's QR code option, then delete phone.keyphone.conf
Add IPv6 (optional)
The simplest way to give devices IPv6 is a private range inside the tunnel, translated to the server's public IPv6 address as with IPv4; devices then share that address. Private ranges start with fdfd8c:5e2a:91b4::/64systemctl stop wg-quick@wg0wg0.confAddress
Address = 10.8.0.1/24, fd8c:5e2a:91b4::1/64
PostUp = ip6tables -t nat -A POSTROUTING -s fd8c:5e2a:91b4::/64 -o eth0 -j MASQUERADE
PostDown = ip6tables -t nat -D POSTROUTING -s fd8c:5e2a:91b4::/64 -o eth0 -j MASQUERADE
Give each device an IPv6 address on both sides, for example AllowedIPs = 10.8.0.2/32, fd8c:5e2a:91b4::2/128 in its [Peer]Address = 10.8.0.2/32, fd8c:5e2a:91b4::2/128 in its own file. Then enable IPv6 forwarding and start the tunnel again:
echo 'net.ipv6.conf.all.forwarding = 1' >> /etc/sysctl.d/99-wireguard.conf
sysctl --system
systemctl start wg-quick@wg0
With nftables, add ip6 saddr fd8c:5e2a:91b4::/64 oifname "eth0" masquerade to the wg-nat
Check for leaks
From a connected device, not from the server, check three things:
- Public IP. A what-is-my-IP website must show your server's IPv4 address, plus its IPv6 address if you added IPv6, and never your home address.
- DNS. A DNS leak test must list only resolvers of the service in your
line, not your internet provider's.DNS - IPv6. Without IPv6 in the tunnel, no IPv6 address should appear at all. If your home IPv6 address shows, check that the device's
containsAllowedIPs .::/0
On the server, wg showlatest handshaketransfer
Keep your WireGuard VPS updated and add more clients
WireGuard updates arrive with the kernel and wireguard-toolswg-quick@wg0/etc/wireguard
- Another device: repeat the phone steps with the next free address,
and so on.10.8.0.4/32 - Apply peer changes:
runssystemctl reload wg-quick@wg0 , which, says the wg manual, "has the benefit of not disrupting current peer sessions".wg syncconf - Remove a device: delete its
block and reload. Its key stops working at once.[Peer] - Optional: a
fromPresharedKey , set on both sides of a peer, addswg genpsksymmetric-key cryptography "forpost-quantum resistance".
Troubleshooting
No handshake
No latest handshakewg show
- the service runs:
;systemctl status wg-quick@wg0 - UFW allows
. Some networks block UDP, and WireGuard has no TCP mode, so also test from mobile data;51820/udp - the device's
has the right address and port;Endpoint - the keys are crossed: the device's file holds the server's public key, and the server's
block holds the device's.[Peer]
Handshake but no traffic
A handshake without working websites means the server does not forward or translate the traffic. Check that:
prints 1;sysctl net.ipv4.ip_forward- the NAT rule names the interface from
. A wrong name gives exactly this symptom, and the counters inip route show defaultiptables -t nat -L POSTROUTING -n -vshow whether the rule matches. Fix it with the tunnel stopped, as described above; - UFW has the
rule;route allow - the device's
matches itsAddress on the server;AllowedIPs - names resolve. If
works but websites do not, fix theping 9.9.9.9 line.DNS
Some sites load, others hang: the MTU
wg-quickMTU = 1380[Interface]
Frequently asked questions
Is it legal to host your own VPN on a VPS?
Running a VPN for yourself is an ordinary use of a server, and our acceptable use policy lists VPNs among the welcome uses on every plan. What you may do through it depends on the law where you are and where the server runs, so check your own jurisdiction. Traffic from the tunnel leaves with your server's IP address.
How many devices can one WireGuard server handle?
The 10.8.0.0/24top
Does WireGuard keep logs?
WireGuard writes no connection logs. While the tunnel runs, it keeps each device's last IP address and port in memory, which wg showwg-quick
Which port does WireGuard use?
Whichever UDP port you set with ListenPortListenPortEndpoint
Dedicated and GPU customers can open a ticket from the client area with the server’s IP address and what they tried. First reply target: under