Skip to content

WireGuard VPN — Server Setup

WireGuard is a modern VPN that is faster and simpler than OpenVPN or IPsec. It uses a minimal codebase, contemporary cryptography (Curve25519, ChaCha20, Poly1305), and is built into the Linux kernel since 5.6.


How WireGuard Works

Crypto Key Routing: Every peer has a public/private key pair. The server maintains a list of peer public keys and their allowed IP addresses. Incoming packets are accepted only if the sender's public key matches an entry and the source IP is within the allowed range.

Allowed IPs serve a dual purpose: - Inbound: act as an ACL — only packets from these IPs are accepted from this peer - Outbound: act as a routing table — packets destined for these IPs are sent to this peer

Static IPs: Every client requires a fixed IP within the WireGuard subnet, defined in the config. Roaming between networks (mobile → Wi-Fi) works seamlessly — WireGuard re-establishes the tunnel automatically.


Pre-requisites

  • Ubuntu 22.04+ or Debian 11+ server with a public IP
  • sudo or root access
  • Kernel 5.6+ (default on Ubuntu 22.04+); older kernels need wireguard-dkms

Install via Nyr Installer Script

The Nyr wireguard-install script sets up a WireGuard server and generates the first client config in one step.

wget https://raw.githubusercontent.com/Nyr/wireguard-install/master/wireguard-install.sh
bash wireguard-install.sh

Review scripts before running

Always read a script before executing it as root. Inspect the current version at the link above before downloading.

The installer prompts for port (default 51820) and a DNS server for clients:

What port should WireGuard listen to?
Port [51820]:

Enter a name for the first client:
Name [client]: laptop

Select a DNS server for the client:
   1) Current system resolvers
   2) Google
   3) 1.1.1.1
   4) OpenDNS
   5) Quad9
   6) AdGuard
DNS server [1]:

When finished, the client config is saved as /root/<name>.conf and a QR code is displayed for mobile devices.


Manage Clients

Re-run the script to add or remove clients:

bash wireguard-install.sh
WireGuard is already installed.

Select an option:
   1) Add a new client
   2) Remove an existing client
   3) Remove WireGuard
   4) Exit

Each new client gets its own .conf file — transfer it to the device or scan the QR code.


Connect a Client

On any device with a WireGuard client (Windows, macOS, Linux, iOS, Android):

  1. Import the .conf file or scan the QR code
  2. Activate the tunnel

All traffic (or a split-tunnel subset, depending on AllowedIPs in the client config) routes through the VPN.


WireGuard Inside a Proxmox LXC Container

WireGuard requires access to a TUN device, which is not available inside LXC containers by default. Add these two lines to the container config on the Proxmox host (container must be stopped first):

nano /etc/pve/lxc/123.conf
lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net dev/net none bind,create=dir

Replace 123 with your container ID. Then set the correct ownership on the TUN device:

chown 100000:100000 /dev/net/tun

Verify:

ls -l /dev/net/tun
# crw-rw-rw- 1 100000 100000 10, 200 ...

Start the container and run the installer as normal.


Common Issues

Symptom Cause Fix
RTNETLINK answers: Operation not supported Kernel module not loaded sudo modprobe wireguard; on older kernels install wireguard-dkms
Client connects but no internet Missing MASQUERADE iptables rule The Nyr script adds this automatically; check with iptables -t nat -L
Client connects but cannot reach LAN AllowedIPs too restrictive in client config Set AllowedIPs = 0.0.0.0/0 for full tunnel or add the LAN subnet
Operation not permitted inside LXC TUN device not accessible Apply the cgroup2 and mount.entry changes above