Blog / Tutorials

How to set up a personal VPN on a $10 VPS (WireGuard guide)

By the NoctHost TeamMay 6, 20268 min read

A personal VPN gives you an encrypted tunnel out to the internet from a server you control. No shared exit IPs, no logging policy to trust, no monthly subscription to a third party. WireGuard makes this surprisingly simple: it is a few hundred lines of kernel code, it is fast, and the whole config fits on one screen.

In this guide you will stand up a WireGuard server on a fresh Ubuntu VPS, generate keys, write the server and client configs, open the right firewall ports, and connect a laptop or phone. Budget about 20 minutes.

What you'll need

  • A VPS running Ubuntu 22.04 or 24.04 with root SSH access.
  • A dedicated IPv4 address (any NoctHost box has one).
  • A WireGuard client on the device you want to protect (Windows, macOS, Linux, iOS, Android).

Everything below runs as root. If you are on a sudo user, prefix commands with sudo.

Step 1: Install WireGuard

  1. Update the package index.
  2. Install the WireGuard tools.
  3. Confirm the kernel module loads.
apt update && apt upgrade -y
apt install -y wireguard
modprobe wireguard && echo ok

Step 2: Generate the server keys

WireGuard authenticates peers with public/private key pairs. Generate the server pair and lock down permissions so only root can read the private key.

cd /etc/wireguard
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key
cat server_private.key server_public.key
Tip — umask 077 is not optional. A WireGuard private key that other users can read is a full compromise of your tunnel.

Step 3: Write the server config

Create /etc/wireguard/wg0.conf. Paste the server private key into PrivateKey. The 10.8.0.0/24 range is the internal VPN subnet; the server is 10.8.0.1. Replace eth0 with your real public interface if it differs (check with ip route).

/etc/wireguard/wg0.conf (server)
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY_HERE

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

# One [Peer] block per client. Filled in at Step 5.
ip route | grep default   # confirm your egress interface name

Step 4: Enable IP forwarding and the firewall

The server has to route packets between the tunnel and the internet, which the kernel disables by default. Turn it on persistently, then open the WireGuard UDP port.

echo 'net.ipv4.ip_forward=1' > /etc/sysctl.d/99-wireguard.conf
sysctl -p /etc/sysctl.d/99-wireguard.conf
ufw allow 22/tcp
ufw allow 51820/udp
ufw enable
Tip — Open port 22 BEFORE running ufw enable, or you will lock yourself out of SSH. WireGuard itself listens on 51820/udp.

Step 5: Add a client

Generate a key pair for the client (you can do this on the server for convenience), then add a [Peer] to wg0.conf with the client public key.

wg genkey | tee client_private.key | wg pubkey > client_public.key

Append a peer block to the server config, pasting the client public key:

append to /etc/wireguard/wg0.conf
[Peer]
PublicKey = CLIENT_PUBLIC_KEY_HERE
AllowedIPs = 10.8.0.2/32

Now write the client config. AllowedIPs = 0.0.0.0/0 routes all traffic through the VPN. Endpoint is your VPS public IP. Use a public DNS resolver so lookups also go through the tunnel.

client wg0.conf (laptop/phone)
[Interface]
Address = 10.8.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY_HERE
DNS = 1.1.1.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY_HERE
Endpoint = YOUR_SERVER_IP:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Step 6: Bring the tunnel up

Start the interface and enable it so it survives reboots. wg show confirms the peer is registered.

wg-quick up wg0
systemctl enable wg-quick@wg0
wg show

On the client, import the config file into the WireGuard app (or run wg-quick up on Linux) and toggle it on. Visit any what-is-my-ip page; you should see the VPS address.

Keep it running and teardown

  • After editing wg0.conf, reload with: wg syncconf wg0 <(wg-quick strip wg0).
  • Add more devices by repeating Step 5 with a new IP (10.8.0.3, 10.8.0.4...) and a fresh key pair.
  • Phones can scan a QR code: qrencode -t ansiutf8 < client.conf prints one in the terminal (apt install qrencode).

Because billing is hourly from one balance, a VPN box like this costs only a few dollars a month, and you can spin one up in about 60 seconds to test a location, then destroy it the moment you are done and charges stop that hour. Your traffic exits a dedicated IP with clean reputation that nobody else shares.

Spin one up in about a minute

Email signup, pay with crypto, hourly billing. Trying a box costs cents — destroy it when you are done.

Deploy a server

Frequently asked

Is WireGuard faster than OpenVPN?
In practice, yes. WireGuard runs in the kernel with modern crypto and a tiny codebase, so it has lower latency and higher throughput than OpenVPN on the same hardware, especially on phones where it also drains less battery.
Does a self-hosted VPN make me anonymous?
No. It hides your traffic from your local network and ISP and gives you a dedicated exit IP, but the VPS is registered to you. It is about privacy and control, not anonymity. Combine it with good browser hygiene if anonymity is the goal.
How many devices can one server handle?
A single $5-10 VPS can comfortably serve a household of a dozen devices. WireGuard's overhead is minimal; you are far more likely to be limited by the server's bandwidth than its CPU.

Keep reading