How to Set Up a WireGuard VPN on a VPS (Ubuntu, Windows, Mac, Phones)

To set up WireGuard on a VPS: install the wireguard package, generate a key pair for the server and each device, write /etc/wireguard/wg0.conf, enable IP forwarding and NAT, open UDP port 51820 in the firewall, start wg-quick@wg0, then import a small client config on each laptop or phone. On Ubuntu 22.04 or 24.04 the whole job takes about twenty minutes, and WireGuard is part of the Linux kernel, so there is nothing to compile.
What a private VPN on your own server is good for
This guide is about legitimate, business-style uses:
Secure access to company systems. Database ports, admin panels, staging sites and SSH stay closed to the internet and open only inside the VPN.
A fixed IP for allow-listing. Many payment gateways, bank portals, cloud consoles and client firewalls accept connections only from known IPs. A home or mobile connection changes IP often; your VPS IP does not.
Safer public Wi-Fi. In a café or hotel, all traffic leaves your device encrypted to a server you control.
Linking a small team. Remote staff and branch PCs reach each other on private 10.x addresses.
Use a VPN according to the laws where you and the server are located and the provider's terms of service. This is general information, not legal advice.
Choose the server location first
Every packet goes through the VPN server, so its distance adds directly to latency. As a rule of thumb, pick the location closest to the people using the VPN and the systems they reach. A team in Egypt reaching servers in Egypt is best served from Cairo; a team reaching services in Europe may do better from Berlin, Warsaw or London. Our article on server location and latency for users in Egypt explains how distance turns into milliseconds. IM HOST has locations in New York, Warsaw, Berlin, London and Cairo; availability depends on stock, and we confirm your location before activation.
WireGuard needs very little CPU. A small VPS handles a team's VPN easily; bandwidth and location matter far more than cores.
Step 1: Install WireGuard
Start from a hardened server (SSH keys, UFW on); our guide to securing a Linux VPS with SSH keys, UFW and fail2ban covers that in under an hour.
sudo apt update
sudo apt install -y wireguard qrencodeqrencode is optional; it lets phones import a config by scanning a QR code.
Step 2: Generate keys
sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
wg genkey | tee laptop.key | wg pubkey > laptop.pub
wg genkey | tee phone.key | wg pubkey > phone.pub
ls -lumask 077 makes the new files readable only by root. Each device gets its own key pair, so you can revoke one device without touching the others. Generating client keys on the server is convenient; the stricter option is to create the key pair inside the client app and copy only its public key to the server. Use cat server.key and the other files to copy values into the configs below.
Step 3: Write the server config
Find the name of the public network interface. It is the word after dev in this output, often eth0 or ens3 (our list of Linux commands for VPS beginners explains ip and its friends):
ip route show defaultCreate /etc/wireguard/wg0.conf, replacing the uppercase placeholders with your keys and eth0 with your interface name:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_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 = LAPTOP_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
[Peer]
# phone
PublicKey = PHONE_PUBLIC_KEY
AllowedIPs = 10.8.0.3/3210.8.0.0/24 is a private range used only inside the tunnel; pick another if it clashes with your office network. Each peer's AllowedIPs is the single address that device is allowed to use. The PostUp line masquerades VPN traffic behind the server's public IP, which is what gives every device the same fixed outgoing IP.
Step 4: Enable forwarding and open the firewall
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system
sudo ufw allow 51820/udp
sudo ufw route allow in on wg0 out on eth0
sudo ufw reloadUFW drops forwarded traffic by default, so the route allow rule is required for traffic to leave the tunnel. Without it, clients connect but cannot reach anything beyond the server.
Step 5: Start the tunnel
sudo systemctl enable --now wg-quick@wg0
sudo wg showwg show lists the interface, its listening port and each peer. After a client connects, latest handshake appears with a recent time and transfer counters start moving.
Step 6: Client configs
Create one file per device, for example laptop.conf. Replace 203.0.113.10 with your server's IP. The phone's file is the same, with the phone's private key and 10.8.0.3/32:
[Interface]
PrivateKey = LAPTOP_PRIVATE_KEY
Address = 10.8.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = 203.0.113.10:51820
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25The AllowedIPs line on the client decides what goes through the tunnel:
Split tunnel (
10.8.0.0/24, as above): only traffic to the VPN network uses the tunnel. Best for reaching company servers while normal browsing stays local and fast.Full tunnel: replace the line with the one below so all IPv4 traffic leaves through the server's IP. Use this for allow-listing and public Wi-Fi.
AllowedIPs = 0.0.0.0/0This setup tunnels IPv4. Adding IPv6 inside the tunnel is possible but needs extra addressing and firewall rules, so treat it as a later step. PersistentKeepalive = 25 keeps the connection alive through home routers and mobile networks.
Windows and macOS
Install the official WireGuard app, choose Import tunnel(s) from file, select the .conf file and click Activate. The app's "Add empty tunnel" option generates a key pair locally if you prefer keys that never leave the laptop.
Android and iPhone
Install WireGuard from Google Play or the App Store, tap + and choose to scan a QR code. On the server, after saving the phone's config as /etc/wireguard/phone.conf, display it:
qrencode -t ansiutf8 < /etc/wireguard/phone.confDelete the client config files from the server once all devices are imported. They contain private keys.
Step 7: Add or remove devices without dropping others
Add a new [Peer] block (or delete one) in wg0.conf, then apply it live:
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'Connected devices stay connected. Removing a peer's block and syncing immediately revokes that device, which is how you offboard an employee or a lost phone.
Step 8: Lock admin services to the VPN
Once the tunnel works, close sensitive ports to the public and allow them only through wg0:
sudo ufw allow in on wg0 to any port 22 proto tcp
sudo ufw allow in on wg0 to any port 5432 proto tcpTest from a VPN client with ssh [email protected] before deleting the public SSH rule, and keep a second session open while you change it. For allow-listing on other systems, add your VPN server's public IP to their lists.
Troubleshooting
No handshake: UDP 51820 is blocked (check
sudo ufw statusand the client's network), the endpoint IP is wrong, or a public key is pasted on the wrong side. The server needs each client's public key; each client needs the server's public key.Handshake but no internet: IP forwarding is off, the interface name in
PostUpis wrong, or theufw routerule is missing.Sites resolve slowly or not at all: check the
DNSline in the client config.Some sites hang while others load: an MTU problem on the path. Add
MTU = 1380under[Interface]on the client and reconnect.
Frequently asked questions
Is WireGuard better than OpenVPN?
For most new setups it is simpler and faster: a much smaller codebase, modern cryptography, quick reconnects on mobile networks, and it runs inside the Linux kernel. OpenVPN still fits cases that need TCP on port 443 or existing OpenVPN infrastructure.
Which port does WireGuard use?
Any UDP port you set with ListenPort; 51820 is the common default. WireGuard does not use TCP.
How many devices can connect to one WireGuard server?
There is no small built-in limit. Each device needs its own peer entry and IP. A /24 range gives you over 250 addresses, and a small VPS handles a typical team without strain.
Does a VPS VPN give me a fixed IP?
Yes. In full-tunnel mode every connected device leaves through the VPS's dedicated public IPv4, so you can add that one address to allow-lists.
WireGuard needs root access and a server with its own kernel (see why KVM matters for kernel modules), which every IM HOST Linux VPS provides, along with a dedicated IPv4. Pick the location nearest your team, and if a step above does not behave as described, our engineers are available 24/7.
More from our blog
Discover more practical guides and product insights from the IM Host team.
View all articles