WireGuard is a small, modern VPN protocol implemented in the Linux kernel. A WireGuard VPS gives laptops and phones an encrypted route to a fixed public IPv4 address, useful on untrusted Wi-Fi or for reaching services that allowlist one address. It does not make a user anonymous, inspect malicious traffic, or replace endpoint security. LayerOne can see the VPS's network usage, and the sites you visit see the VPS address.
This guide creates an IPv4 full-tunnel exit node with native Ubuntu packages. There is no web administration panel, database, Docker socket, or reverse proxy to expose.
WireGuard VPS requirements and LayerOne cost
| Item | Practical starting point |
|---|---|
| Minimum RAM | 512 MB for a minimal Ubuntu or Debian WireGuard gateway |
| Recommended RAM | 1 GB for package updates, logging, and several personal peers |
| Expected CPU usage | Essentially zero when idle; often 5–30% of one vCPU during light personal use, with sustained high throughput capable of using the full core |
| Storage requirement | About 4 GB minimum for the OS; 10 GB is comfortable when logs are controlled |
| Exact LayerOne SKU | gc.nano — catalog slug layerone-nano, 1 vCPU, 1 GB RAM, 20 GB disk |
| Expected monthly cost | $3.00/month equivalent, metered at $0.0041/hour while the VPS exists |
Encryption speed depends on packet size, peer count, CPU scheduling, client
hardware, and the route between client and VPS. The figures above are workload
estimates, not a throughput promise. Measure with top, wg show, and a test
appropriate to your real traffic. Upgrade when the single vCPU remains busy or
latency rises under load.
LayerOne charges hourly and transfer usage can vary. Check the current plan and bandwidth terms on Pricing. The 20 GB disk is far more than WireGuard itself needs; the recommended SKU is for RAM and operational headroom.
Before you install
The commands below assume Ubuntu 24.04 LTS and a public IPv4 address. Complete
Your first hour on a new server, restrict SSH to a
trusted source, and optionally point vpn.example.com to the VPS. These
examples use:
- WireGuard network
10.8.0.0/24; - server tunnel address
10.8.0.1; - first client address
10.8.0.2; and - UDP port
51820.
Choose a different private range if 10.8.0.0/24 overlaps the client's home,
office, or another VPN network. LayerOne does not currently provide IPv6, so
this guide deliberately configures an IPv4 tunnel only.
1. Install WireGuard and identify the WAN interface
WireGuard is in the Ubuntu package repository:
sudo apt update
sudo apt install -y wireguard qrencode ufw
ip route show default
The last command normally shows a line containing dev ens18, dev eth0, or a
similar name. Record that interface. The examples below use ens18; replace it
everywhere if your server reports a different name.
2. Generate the server key and a client key
Restrictive umask permissions matter because a WireGuard private key is the
peer's identity:
sudo install -d -m 700 /etc/wireguard/keys
sudo sh -c 'umask 077; wg genkey | tee /etc/wireguard/keys/server.key | wg pubkey > /etc/wireguard/keys/server.pub'
sudo chmod 600 /etc/wireguard/keys/*.key
sudo chmod 644 /etc/wireguard/keys/*.pub
Generate each client key on that client whenever possible, so its private key
never crosses the VPS. On a Linux client with wireguard-tools installed:
umask 077
wg genkey | tee client-laptop.key | wg pubkey > client-laptop.pub
cat client-laptop.pub
The final command prints a public key. Mobile and desktop WireGuard apps can also generate a key pair and show the public key. Keep every private-key file on its device; never paste it into a ticket, chat, or public terminal recording.
3. Enable IPv4 forwarding
sudo tee /etc/sysctl.d/99-wireguard-forwarding.conf >/dev/null <<'EOF'
net.ipv4.ip_forward=1
EOF
sudo sysctl --system
sysctl net.ipv4.ip_forward
The final value must be 1.
4. Create the server configuration
Build /etc/wireguard/wg0.conf while reading the generated keys directly. This
avoids copying a private key through an editor:
SERVER_PRIVATE_KEY=$(sudo cat /etc/wireguard/keys/server.key)
read -r -p "Paste the client's public key: " CLIENT_PUBLIC_KEY
sudo tee /etc/wireguard/wg0.conf >/dev/null <<EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = $SERVER_PRIVATE_KEY
PostUp = iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
[Peer]
# laptop
PublicKey = $CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
EOF
unset SERVER_PRIVATE_KEY CLIENT_PUBLIC_KEY
sudo chmod 600 /etc/wireguard/wg0.conf
sudo wg-quick strip wg0 >/dev/null
Replace both occurrences of ens18 first if the default-route interface has a
different name. The peer receives a single /32; do not give two clients the
same tunnel address.
5. Configure the cloud firewall and UFW
In LayerOne's Networking tab, use inbound DROP, outbound ACCEPT, allow
TCP 22 from your administration address, and allow UDP 51820 from
0.0.0.0/0. If every peer has a stable address, narrow the UDP rule to those
sources. Do not open TCP 51820: WireGuard uses UDP. See
The cloud firewall.
Mirror the policy in UFW and explicitly allow forwarded tunnel traffic:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from YOUR.ADMIN.IP.ADDRESS to any port 22 proto tcp
sudo ufw allow 51820/udp
sudo ufw route allow in on wg0 out on ens18
sudo ufw enable
sudo ufw status verbose
Again, substitute the real WAN interface for ens18. If the VPN should reach
only specific private services rather than become an internet exit node, omit
the MASQUERADE rules, use narrower AllowedIPs, and create only the forwarding
rules that design requires.
6. Start WireGuard and enable it at boot
sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0 --no-pager
sudo wg show
sudo ss -lunp | grep ':51820'
wg show lists configuration immediately, but a peer gets a latest handshake
only after that client sends valid traffic.
7. Create the client profile
Read the server's public key:
sudo cat /etc/wireguard/keys/server.pub
Create this profile on the client that generated client-laptop.key,
substituting that local private key, the server's public key, and your hostname:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.8.0.2/32
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0 makes this a full IPv4 tunnel. For split tunneling,
list only networks that should traverse the VPN. PersistentKeepalive = 25 is
useful for clients behind NAT; it is not normally needed on the server peer.
Import the configuration into the official WireGuard client. If you deliberately
create a QR code from client.conf on a trusted local machine, it displays the
private key to anyone who can see or record the terminal. Use it only in a
private session and clear the screen:
qrencode -t ansiutf8 < client.conf
clear
8. Verify routing, DNS, and leaks
Bring the tunnel up on the client, then run:
ping -c 3 10.8.0.1
curl -4 https://icanhazip.com
The second command should return the VPS public IPv4. On the server:
sudo wg show
sudo journalctl -u wg-quick@wg0 -n 50 --no-pager
sudo iptables -t nat -S POSTROUTING
Confirm a recent handshake and increasing transfer counters. Also test DNS, ordinary HTTPS, and reconnect after moving the client between Wi-Fi and mobile data. Because this is IPv4-only, configure the client not to leak IPv6 through another interface or disable IPv6 for the tunnel session when its client platform requires that explicit choice.
Add or revoke peers
Generate a unique key pair and tunnel /32 for every device. Add a new [Peer]
block to wg0.conf, validate, and reload without dropping active sessions:
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'
sudo wg show
The syncconf command uses Bash process substitution and updates peers without
taking the interface down. To revoke a lost device, remove its peer block and
sync the configuration immediately. A shared key cannot identify or revoke one
device independently.
Back up, restore, and update
Back up /etc/wireguard/wg0.conf and the server key to encrypted off-server
storage. Client private keys should normally stay with their clients. Protect
the archive as a live credential:
sudo tar -C /etc -czf "/root/wireguard-$(date -u +%Y%m%dT%H%M%SZ).tar.gz" wireguard
On restore, install WireGuard, restore the protected directory with mode 600 on
private material, re-enable IP forwarding and firewall/NAT rules, then start
wg-quick@wg0. If the endpoint IP or hostname changes, update every client.
Read Backups and snapshots; LayerOne does not preserve
this configuration for you.
WireGuard updates arrive through normal Ubuntu security updates:
sudo apt update
sudo apt full-upgrade -y
sudo wg show
Reboot if Ubuntu reports a required kernel restart, then confirm a fresh client handshake and public IP.
Security pitfalls
- Never reuse a private key between clients or publish a client profile.
- Restrict each server peer's
AllowedIPsto its assigned/32unless the peer is deliberately a router for another network. - Do not expose management dashboards or DNS resolvers merely because the VPN port is open.
- A full tunnel can make the VPS address responsible for every client's abuse complaints and rate limits. Control who receives a profile.
- WireGuard is quiet when a peer is idle. Absence of a continuous connection is normal; use the latest handshake and transfer counters for diagnosis.