← All articles

Setting Up WireGuard: The Modern Self-Hosted VPN

2026-02-08 · Networking wireguard vpn networking privacy

Commercial VPN services cost $5-12/month and require you to trust that they actually don't log your traffic (spoiler: some do). A self-hosted VPN gives you genuine privacy and secure access to your home network — and WireGuard makes it surprisingly simple.

WireGuard is a modern VPN protocol that's faster, simpler, and more secure than OpenVPN or IPsec. It's built into the Linux kernel, uses state-of-the-art cryptography, and the entire codebase is about 4,000 lines (compared to OpenVPN's 100,000+).

Why WireGuard Over Alternatives?

Feature WireGuard OpenVPN Commercial VPN
Setup complexity Low Medium-High None
Performance Excellent Good Varies
Codebase size ~4,000 lines ~100,000 lines Unknown
Protocol UDP TCP or UDP Varies
Reconnection Instant (roaming) Seconds Seconds
Linux kernel support Built-in Userspace N/A
Monthly cost $0 (+ VPS if needed) $0 (+ VPS) $5-12

WireGuard is not a complete replacement for commercial VPNs if your goal is to appear to be in a different country or to obscure your IP from websites. For that, the VPN provider's network of exit points is the product. But for secure remote access and privacy from your ISP, WireGuard is superior.

Common Use Cases

1. Secure access to your home network

Access your self-hosted services (Nextcloud, Home Assistant, media servers) from anywhere without exposing them to the internet.

2. Privacy on public WiFi

Encrypt all traffic from your laptop or phone when on coffee shop or hotel WiFi.

3. Site-to-site connections

Connect multiple locations (home, office, VPS) into a single encrypted network.

4. Bypass ISP throttling

Some ISPs throttle specific services. A VPN tunnel prevents them from inspecting your traffic.

Server Setup

Prerequisites

Install WireGuard

On Ubuntu/Debian:

sudo apt install wireguard

On Fedora:

sudo dnf install wireguard-tools

Generate server keys

wg genkey | tee /etc/wireguard/server_private.key | wg pubkey > /etc/wireguard/server_public.key
chmod 600 /etc/wireguard/server_private.key

Server configuration

Create /etc/wireguard/wg0.conf:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server_private_key>

# Enable IP forwarding and NAT for internet access through the VPN
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# Peer: Laptop
[Peer]
PublicKey = <client_public_key>
AllowedIPs = 10.0.0.2/32

# Peer: Phone
[Peer]
PublicKey = <phone_public_key>
AllowedIPs = 10.0.0.3/32

Replace eth0 with your server's actual network interface name (check with ip route | grep default).

Enable IP forwarding

echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf

Start WireGuard

sudo systemctl enable --now wg-quick@wg0

Client Setup

Generate client keys

wg genkey | tee client_private.key | wg pubkey > client_public.key

Client configuration

Create wg0.conf on your client device:

[Interface]
Address = 10.0.0.2/24
PrivateKey = <client_private_key>
DNS = 1.1.1.1

[Peer]
PublicKey = <server_public_key>
Endpoint = your.server.ip:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

AllowedIPs explained:

Mobile clients

WireGuard has official apps for iOS and Android. You can import the configuration as a file or scan a QR code:

# Generate QR code for mobile (install qrencode first)
qrencode -t ansiutf8 < client-phone.conf

This displays a QR code in your terminal that the mobile app can scan directly.

Management with wg-easy

If you want a web interface for managing peers, wg-easy provides a clean dashboard:

# docker-compose.yml
services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy
    restart: unless-stopped
    ports:
      - "51820:51820/udp"
      - "51821:51821/tcp"  # Web UI
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    sysctls:
      - net.ipv4.ip_forward=1
    volumes:
      - wg_data:/etc/wireguard
    environment:
      WG_HOST: your.server.ip
      PASSWORD_HASH: ${WG_PASSWORD_HASH}

volumes:
  wg_data:

The web UI lets you create, disable, and delete clients with one click, and generates QR codes automatically.

Performance

WireGuard's kernel-level implementation means it's significantly faster than userspace VPNs:

Scenario WireGuard OpenVPN
Throughput (1 Gbps link) ~900 Mbps ~400 Mbps
Latency overhead ~0.5 ms ~2-5 ms
CPU usage Minimal Moderate
Handshake time ~100 ms ~1-2 seconds
Roaming (network change) Seamless Reconnects

The roaming feature is particularly useful on phones — WireGuard maintains the connection as you switch between WiFi and cellular without any reconnection delay.

Security Considerations

WireGuard uses modern, conservative cryptography:

There are no cipher suite negotiations or configuration options that could be misconfigured. The cryptography is fixed and well-audited.

One important caveat: WireGuard does not provide traffic obfuscation. Your ISP can detect that you're using WireGuard (though they can't see the contents). If you need to hide VPN usage itself (e.g., in countries that block VPNs), you'll need an additional obfuscation layer.

When to Use a Commercial VPN Instead

Self-hosted WireGuard doesn't help with:

The Bottom Line

WireGuard is the best option for secure remote access to your network and private browsing on untrusted WiFi. It's fast, simple to set up, and virtually maintenance-free once running. The initial setup takes about 15 minutes, and then it just works.

For accessing your self-hosted services from anywhere, WireGuard should be the first thing you set up — it secures everything else.