Jan 26, 2025 · Networking / Intermediate · ~3 MIN READ
WireGuard VPN on Linux
Secure your network with WireGuard VPN — covers Raspberry Pi, Ubuntu, key generation, and firewall rules.
Why WireGuard?
WireGuard is simple, fast, and highly secure. Its minimalist codebase means fewer bugs and vulnerabilities compared to legacy VPNs like OpenVPN or IPsec. This guide shows how to stand up a lean VPN with strong defaults.
Think of it like a private tunnel under a busy street. Instead of crossing out in the open where anyone can watch you, you go underground and come out exactly where you meant to, unseen the whole way.
Server prerequisites
1) Choose a Linux server
Pick a VPS with a public IPv4 (and optionally IPv6). Options to consider:
- Oracle Cloud Free Tier (always-free instances)
- AWS Free Tier (time-limited)
- Google Cloud (new-user credits)
2) Install WireGuard
$sudo apt update
$sudo apt install wireguard
For other distros, use the native package manager (e.g., dnf on Fedora/RHEL, pacman on Arch).
3) Generate server keys
$sudo mkdir -p /etc/wireguard/keys
$sudo chmod 700 /etc/wireguard/keys
$cd /etc/wireguard/keys
$sudo wg genkey | sudo tee privatekey | sudo wg pubkey > publickey
- privatekey: keep secret
- publickey: share with clients
4) Configure wg0.conf
$sudo nano /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <contents of /etc/wireguard/keys/privatekey> Address = 10.0.0.1/24 ListenPort = 51820
Enable IP forwarding (runtime) + NAT for egress traffic
NOTE: replace eth0 with your actual NIC (e.g., ens3)
PostUp = sysctl -w net.ipv4.ip_forward=1 PostUp = iptables -A FORWARD -i %i -j ACCEPT PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
Persist forwarding:
$echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf
$sudo sysctl --system
5) Open firewall
$sudo ufw allow 51820/udp
$sudo ufw allow OpenSSH
$sudo ufw enable
6) Start the service
$sudo systemctl enable wg-quick@wg0
$sudo systemctl start wg-quick@wg0
$sudo systemctl status wg-quick@wg0 --no-pager
Client configuration
1) Install client software
- Linux: via package manager
- Windows/macOS: download from wireguard.com
- Mobile: App Store / Google Play
2) Generate client keys
$wg genkey | tee client_privatekey | wg pubkey > client_publickey
3) Create client.conf
[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY> Address = 10.0.0.2/32 DNS = 1.1.1.1
[Peer] PublicKey = <SERVER_PUBLIC_KEY>
Optional extra PSK:
PresharedKey =
Endpoint = <SERVER_PUBLIC_IP>:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25
- AllowedIPs
0.0.0.0/0= full tunnel. For split tunnel, use only needed subnets (e.g.,10.0.0.0/24).
4) Add the client on the server
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY> AllowedIPs = 10.0.0.2/32
$sudo systemctl restart wg-quick@wg0
Verify & connect
- Import
client.confinto the WireGuard app - Activate the tunnel
- Verify:
curl ifconfig.meor ping internal hosts
Extras & best practices
- Multiple clients → unique keypair + /32 IP each (10.0.0.3/32, 10.0.0.4/32, …)
- Keep private keys secret; tight permissions on
/etc/wireguard/keys - Interface name may not be
eth0(check withip a) - Monitor with
sudo wg show(handshake, transfer, peers) - Consider IPv6 if your provider supports it
- Handy mobile import:
qrencode -t ansiutf8 < client.conf
Final thought
Building your own VPN isn’t just about privacy, it’s about control and learning. Verify each step, iterate safely, and you’ll have a fast, reliable tunnel you understand end-to-end.