KnowledgebaseNetworking & DNS › WireGuard road-warrior setup — laptop and phone access to your VPS network

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.1 to the client's [Interface] and run a resolver on the server.
  • IPv6 woes on mobile — leave IPv6 out of AllowedIPs if 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 51820 from 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

« « Back

Powered by WHMCompleteSolution