WireGuard road-warrior setup — laptop and phone access to your VPS network
Road-warrior VPN gives your laptop and phone always-on access to services on your LYLIX VPS — internal admin interfaces, databases, monitoring dashboards — without exposing them to the public Internet. WireGuard is the standard tool now: small config, fast, reliable, native clients on every platform. This article walks you from "fresh VPS" to "phone is connected" in 20 minutes.
Topology
One server (your LYLIX VPS) acts as the VPN gateway. Multiple clients (laptop, phone, tablet) connect to it. Traffic between clients goes through the server. Optionally, clients route ALL their internet traffic through the server (full-tunnel) or just the VPS network traffic (split-tunnel).
Server-side setup (Debian / Ubuntu / AlmaLinux)
apt install wireguard # Debian/Ubuntu
dnf install wireguard-tools # AlmaLinux
# Generate the server keypair
cd /etc/wireguard
umask 0077
wg genkey | tee server-private.key | wg pubkey > server-public.key
# Pick an internal subnet (doesn't conflict with anything)
# 10.99.0.0/24 is a common safe choice
Create /etc/wireguard/wg0.conf:
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = <contents of server-private.key>
# Forward to internet (uncomment if you want full-tunnel; nftables/iptables MASQUERADE needed)
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -A FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -D FORWARD -i wg0 -j ACCEPT
# Per-client peers go below
[Peer]
# laptop
PublicKey = <laptop public key, generated client-side>
AllowedIPs = 10.99.0.2/32
[Peer]
# phone
PublicKey = <phone public key>
AllowedIPs = 10.99.0.3/32
Enable IP forwarding:
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-wireguard.conf
sysctl --system
systemctl enable --now wg-quick@wg0
Open UDP 51820 in your firewall (nftables or iptables — see the firewall articles in this category).
Client setup (laptop — Linux/Mac)
# Linux: same wireguard package, then on the laptop:
wg genkey | tee laptop-private.key | wg pubkey > laptop-public.key
# /etc/wireguard/wg0.conf on the laptop:
[Interface]
Address = 10.99.0.2/32
PrivateKey = <laptop private key>
[Peer]
PublicKey = <server public key>
Endpoint = your-vps.example.com:51820
AllowedIPs = 10.99.0.0/24 # split-tunnel — only VPN subnet via tunnel
# OR
# AllowedIPs = 0.0.0.0/0, ::/0 # full-tunnel — ALL traffic via VPN
PersistentKeepalive = 25
wg-quick up wg0
wg show # verify handshake
On macOS, install WireGuard from the App Store, import the config via the GUI ("Add Tunnel" → "Add Empty Tunnel" or "Import from file"), paste the same config.
Client setup (phone — iOS / Android)
Install the WireGuard app from the App Store / Play Store. Easiest way to add the config is QR code:
# On the server, generate QR for a client config
apt install qrencode
qrencode -t ansiutf8 < phone.conf
Where phone.conf is the client-side config (same format as the laptop's). Scan with the WireGuard app on the phone, toggle on.
Testing
# From client
ping 10.99.0.1 # server's VPN address
wg show # last handshake, transfer counters
"Latest handshake: 30 seconds ago" with transfer counters going up = tunnel is working. If transfer is 0 in either direction, packets aren't flowing — usually a firewall rule or AllowedIPs mismatch.
Adding services behind the tunnel
Any service on the server that listens on 10.99.0.1 (or 0.0.0.0) is reachable from connected clients. To expose a service only to VPN clients:
# Bind PostgreSQL to the VPN address only
# /etc/postgresql/15/main/postgresql.conf
listen_addresses = 'localhost, 10.99.0.1'
# Allow VPN clients in pg_hba.conf
host all all 10.99.0.0/24 scram-sha-256
Same pattern for any other service. Bind to the VPN IP, restrict in the service's own ACL, never open the port on the public interface.
Common pitfalls
- DNS doesn't work after connecting — split-tunnel clients still use their local DNS. To push a custom DNS, add
DNS = 10.99.0.1to the client's[Interface]and run a resolver on the server. - IPv6 woes on mobile — leave IPv6 out of
AllowedIPsif you don't need it; mobile networks have inconsistent IPv6 behavior that can cause odd routing. - Handshake never completes — UDP 51820 isn't reachable. Test with
nc -u -v your-vps 51820from the client; if connection refused, firewall rule. If timeout, the network between client and server blocks UDP (rare but happens on some hotel/airport WiFi). - Battery drain on phones with full-tunnel — every packet round-trips through your VPS. Split-tunnel (AllowedIPs = 10.99.0.0/24 only) is much kinder.
Also Read
Powered by WHMCompleteSolution