How to set up a WireGuard VPN on a VPS
Set up a WireGuard VPN on a VPS in about ten minutes: install the package, generate keys, write wg0.conf, open UDP 51820, and connect your client. Step-by-step on a no-KYC, crypto-paid server.

WireGuard is the fastest, leanest way to run your own VPN. It lives in the Linux kernel, uses modern cryptography, and a working tunnel is a single short config file on each side. Hosting it yourself on a VPS means you control the exit point end to end: there is no shared commercial server logging your traffic, and the only party who sees your real IP is the host you chose.
This guide walks through a complete server in roughly ten minutes, with real commands you can copy. We assume a fresh Debian or Ubuntu LTS box with root access. If you have not deployed one yet, a no-KYC VPS paid in crypto pairs naturally with a self-hosted VPN, and our entry tier is more than enough. By the end you will have a tunnel that comes back up on every reboot and a client config you can scan as a QR code on your phone.
Why self-host WireGuard instead of buying a VPN
A commercial VPN gives you convenience and a large pool of exit IPs, but you are trusting a third party not to log and to mean what their privacy policy says. A self-hosted WireGuard endpoint inverts that: you own the box, you write the config, and you decide whether anything is logged at all. There is no shared exit address with thousands of strangers, which also means none of their abuse history lands on you.
The trade-off is honest: the VPS provider can still see that an IP exists and routes traffic, so self-hosting moves trust from a VPN brand to your host. That is exactly why it pays to run it on an offshore no-KYC VPS in a privacy-minded jurisdiction, paid for without handing over your identity. This is also why we say private, not anonymous: a self-hosted tunnel improves your posture, but real anonymity still depends on your own payment and network hygiene. For the broader case, see our overview of running a VPS for a VPN.
Which tier to pick for a personal VPN
WireGuard is remarkably light on resources. A single CPU core and 1 GB of RAM will saturate most home connections, and the encryption work happens in the kernel rather than in a heavy userspace daemon. For one person or a couple of devices, the Pup tier (1 vCPU, 1 GB RAM, 25 GB NVMe) is plenty, and like every tier it ships with unlimited traffic so a VPN does not burn through a metered cap.
Step up only if you are adding load. A handful of family members on the same tunnel are fine on Pup or Cub; if you want to co-host other services, run a few containers, or serve several simultaneous heavy streams, move to Scout or Runner for the extra cores and RAM. Location matters as much as size for a VPN: pick by latency and jurisdiction, which we cover further down. You can pay in Monero or any supported coin, and a server deploys in about sixty seconds with no setup fee.
Step 1 — Install WireGuard
WireGuard ships in the kernel of modern Linux, so installation is just the userspace tooling. On Debian or Ubuntu LTS, refresh the package index and install the package as root:
apt update && apt install -y wireguard
This pulls in wg and wg-quick, the two commands you will use to manage the tunnel. On AlmaLinux, Rocky or Fedora the equivalent is dnf install -y wireguard-tools. Verify it is present with wg --version before continuing.
Step 2 — Generate server and client keys
WireGuard authenticates peers with Curve25519 keypairs, not passwords. Lock down the directory first, then generate one keypair for the server and one for each client device. Run as root:
umask 077; cd /etc/wireguard
wg genkey | tee server_private.key | wg pubkey > server_public.key
wg genkey | tee client_private.key | wg pubkey > client_public.key
You now have four files. The two public keys are exchanged between peers; the two private keys never leave the machine they belong to. Print them with cat server_private.key and so on when you fill in the config in the next step. Generate a fresh client keypair per device rather than reusing one across phone and laptop.
Step 3 — Write /etc/wireguard/wg0.conf
Create the server interface config at /etc/wireguard/wg0.conf. This defines the tunnel subnet (10.0.0.0/24 here), the listen port, and a NAT rule so client traffic is masqueraded out the server's public interface. Replace SERVER_PRIVATE_KEY and CLIENT_PUBLIC_KEY with the values from step 2, and confirm your public NIC name with ip route get 1.1.1.1 (often eth0 or ens3):
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32The server is 10.0.0.1; the first client will be 10.0.0.2. Each additional device gets its own [Peer] block and the next address in the range.
Step 4 — Enable IP forwarding and open the firewall
For the server to route client traffic to the internet, the kernel must forward packets. Enable it permanently and apply it now:
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf && sysctl -p
Then open the WireGuard port. WireGuard listens on UDP 51820 by default. If you use UFW:
ufw allow 51820/udp && ufw allow OpenSSH
Always allow your SSH port in the same breath so you do not lock yourself out when you enable the firewall. Every VPSCrypto VPS arrives with a dedicated clean IPv4 and an IPv6 /64, so this single UDP rule is all the inbound exposure your VPN needs.
Step 5 — Bring the tunnel up and enable it on boot
Start the interface with the helper that reads your config, then enable the systemd unit so it survives reboots:
wg-quick up wg0
systemctl enable wg-quick@wg0
Confirm the interface is live and listening with wg show, which prints the interface, its public key and the listening port. At this point the server side is finished; the only thing left is to point a client at it. If you change wg0.conf later, apply it cleanly with wg-quick down wg0 && wg-quick up wg0.
Step 6 — Configure your client device
On your laptop or phone, install the official WireGuard app or package and create a tunnel from this config. Use the client private key from step 2 and the server's public key. The client Endpoint is simply your server's public IP followed by the WireGuard UDP port, for example 203.0.113.10:51820:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.0.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = 203.0.113.10:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25Setting AllowedIPs to 0.0.0.0/0, ::/0 routes all traffic through the tunnel. On mobile, generate a QR code from this file with qrencode -t ansiutf8 < client.conf on the server and scan it in the app. Activate the tunnel, then check your visible IP — it should now be the server's. The PersistentKeepalive line keeps the connection alive behind NAT.
Hardening tips
A working tunnel is the start, not the finish. Rotate keys periodically by regenerating a client keypair and swapping the public key in the server's [Peer] block. Keep a separate keypair per device so you can revoke one without disturbing the others — to revoke, simply delete that peer's block and re-apply the config.
- Disable logging you do not need. WireGuard itself is quiet by default; review your SSH and system logs and trim retention if a minimal footprint matters to you.
- Lock down SSH with key-only authentication and consider moving it off port 22; keep that port allowed in UFW before you enable the firewall.
- Choose the jurisdiction deliberately. The server's location is now your VPN's privacy posture. Switzerland under the FADP and Iceland with its free-press tradition are strong choices; the Netherlands and France trade some of that for lower EU latency.
For ongoing operations and credential handling, our documentation covers reverse DNS, IPv6 and panel features in detail.
VPS vs commercial VPN — when self-hosting makes sense
Self-hosting wins when you want a dedicated IP, full control over logging, and a tunnel that no provider markets to thousands of users. It is ideal for accessing your own services, getting a stable address for allowlists, or simply not trusting a VPN company's no-logs claim. The cost is that you maintain it, and a single self-hosted exit IP is not designed for blending into a crowd the way a commercial VPN's shared pool is.
Commercial VPNs win on convenience, country-hopping and shared-IP plausible deniability. For most privacy-conscious users who want one trusted endpoint they actually own, a small VPS running WireGuard is the better answer — and paying for it through a crypto, no-KYC checkout keeps the setup consistent end to end. If you are still weighing the approach, our VPS-for-VPN overview compares the two in more depth.
- Install WireGuard
On a fresh Debian or Ubuntu LTS server, update the package index and install the WireGuard tooling as root:
apt update && apt install -y wireguard. On AlmaLinux, Rocky or Fedora usednf install -y wireguard-tools. Confirm withwg --version. - Generate server and client keys
Lock down the directory and create a keypair for the server and one per client:
umask 077; cd /etc/wireguard, thenwg genkey | tee server_private.key | wg pubkey > server_public.keyandwg genkey | tee client_private.key | wg pubkey > client_public.key. Private keys stay on their own machine; only public keys are exchanged. - Write the server config at /etc/wireguard/wg0.conf
Create
wg0.confwithAddress = 10.0.0.1/24,ListenPort = 51820, yourPrivateKey, aPostUp/PostDowniptables ... MASQUERADErule on your public NIC (find it withip route get 1.1.1.1), and a[Peer]block with the client's public key andAllowedIPs = 10.0.0.2/32. - Enable IP forwarding and open the firewall
Turn on packet forwarding:
echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf && sysctl -p. Then open WireGuard's default UDP port and keep SSH reachable:ufw allow 51820/udp && ufw allow OpenSSH. Allowing SSH first prevents locking yourself out. - Bring the tunnel up and enable it on boot
Start the interface with
wg-quick up wg0and make it persistent withsystemctl enable wg-quick@wg0. Verify it is listening withwg show. After any config change, reapply withwg-quick down wg0 && wg-quick up wg0. - Configure and connect your client
On your device, create a tunnel with the client private key,
Address = 10.0.0.2/32, the server's public key,Endpoint = 203.0.113.10:51820(your server's public IP and the WireGuard UDP port),AllowedIPs = 0.0.0.0/0, ::/0to route everything, andPersistentKeepalive = 25. For mobile, generate a QR code withqrencode -t ansiutf8 < client.confand scan it. Activate, then confirm your public IP is now the server's.
Frequently asked questions
How much VPS do I need for a personal WireGuard VPN?
Very little. WireGuard runs in the kernel and is light on CPU and memory, so our Pup tier (1 vCPU, 1 GB RAM, 25 GB NVMe) with unlimited traffic handles a personal VPN comfortably. Step up to Scout or Runner only if you are adding multiple users or co-hosting other services.
Which port does WireGuard use?
By default it listens on UDP 51820. Open it in your firewall with ufw allow 51820/udp and you are set. You can change ListenPort in wg0.conf if you prefer a different port, but remember to open the matching rule and update the client's Endpoint.
Is a self-hosted WireGuard VPN more private than a commercial VPN?
It can be, because you alone control the endpoint and whether anything is logged — there is no shared exit and no vendor no-logs claim to take on faith. The trade-off is that your VPS host sees the IP, so the privacy gain depends on choosing a no-KYC host in a strong jurisdiction and paying privately. It is a real improvement, not a guarantee of anonymity.
Can I run WireGuard and other services on the same VPS?
Yes. WireGuard is lightweight and coexists happily with other workloads. For a personal VPN plus a small site or a couple of containers, Pup or Cub is fine; for heavier services running alongside the tunnel, step up to the Scout or Runner tier for extra cores and RAM.
Which location is best for a VPN VPS?
Pick by latency and jurisdiction. The Netherlands or France give low EU latency from a well-connected hub; Switzerland under the FADP and Iceland's free-press tradition give a stronger privacy posture at a small premium. Since you control the endpoint, the server's jurisdiction effectively becomes your VPN's.
کاوش بیشتر.
Deploy an offshore VPS in about a minute
No-KYC, crypto-paid, all-NVMe. Pick a tier, pay in Monero or any major coin, and get root in roughly 60 seconds.
