WireGuard: A Modern VPN Protocol
WireGuard is a remarkably simple yet fast and modern VPN (Virtual Private Network) that utilizes state-of-the-art cryptography. Designed for ease of implementation and high performance, it aims to be a more efficient and secure alternative to traditional VPN protocols like IPsec and OpenVPN. This guide covers the basic setup of a WireGuard server and a peer configuration.
1. Installation
WireGuard is available in the standard repositories of most modern Linux distributions.
sudo apt update
sudo apt install wireguard2. Key Generation
WireGuard uses public-key cryptography for authentication. Each peer needs a private key and its corresponding public key.
Generate a Private Key
sudo wg genkey | sudo tee /etc/wireguard/server_private.keySet Secure Permissions for the Private Key
The private key should have very restrictive permissions as it grants access to the VPN.
sudo chmod 600 /etc/wireguard/server_private.keyGenerate the Public Key from the Private Key
sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.keyYou will need the public key of the server to configure client peers, and the public key(s) of the client(s) to configure the server.
3. Server Configuration: wg0.conf
Create and edit the server’s WireGuard configuration file, typically located at /etc/wireguard/wg0.conf.
sudo nano /etc/wireguard/wg0.confExample Server Configuration (/etc/wireguard/wg0.conf)
[Interface]
# The private IP address of the WireGuard server within the VPN tunnel
Address = 10.0.0.1/24
# PostUp and PostDown scripts run when the interface comes up/down
# These configure NAT (Masquerading) to allow VPN clients to access the internet via the server
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <external_interface> -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <external_interface> -j MASQUERADE
# The UDP port WireGuard listens on for incoming connections from clients
ListenPort = 51820
# The server's private key (generated above)
PrivateKey = <SERVER_PRIVATE_KEY_HERE>
[Peer]
# This section defines a client peer configuration
# The public key of the client peer (generated on the client machine)
PublicKey = <CLIENT_PUBLIC_KEY_HERE>
# The allowed IP address(es) for this client within the VPN tunnel
AllowedIPs = 10.0.0.2/32
# (Optional) Endpoint for clients with dynamic IPs if server is behind NAT
# Endpoint = <CLIENT_EXTERNAL_IP_OR_HOSTNAME>:<CLIENT_LISTEN_PORT>- Replace
<external_interface>with your server’s public-facing network interface (e.g.,eth0,ens3). - Replace
<SERVER_PRIVATE_KEY_HERE>and<CLIENT_PUBLIC_KEY_HERE>with the actual keys.
4. Enable IP Forwarding
For the WireGuard server to act as a router and forward traffic from VPN clients to the internet (or other networks), IP forwarding must be enabled in the kernel.
sudo sysctl -w net.ipv4.ip_forward=1
# To make this persistent across reboots, add 'net.ipv4.ip_forward = 1' to /etc/sysctl.conf5. System Integration (systemctl)
Manage the WireGuard interface using systemctl and wg-quick.
# Start the wg0 interface
sudo systemctl start [email protected]
# Check the status of the wg0 interface
sudo systemctl status [email protected]
# Enable the wg0 interface to start automatically on boot
sudo systemctl enable [email protected]
# Show the current status and configuration of the wg0 interface
sudo wg show wg06. Client Peer Configuration Example
On the client machine, you would create a wg0.conf file similar to this, using the server’s public key.
[Interface]
# The private IP address of the client within the VPN tunnel
Address = 10.0.0.2/32
# (Optional) DNS server for the client when connected to the VPN
# DNS = 8.8.8.8
# Client's private key
PrivateKey = <CLIENT_PRIVATE_KEY_HERE>
[Peer]
# The public key of the WireGuard server
PublicKey = <SERVER_PUBLIC_KEY_HERE>
# The external IP address and listening port of the WireGuard server
Endpoint = <SERVER_EXTERNAL_IP_OR_HOSTNAME>:51820
# All traffic for the client will be routed through the VPN tunnel
AllowedIPs = 0.0.0.0/0
# Or, to route only internal VPN traffic through the tunnel:
# AllowedIPs = 10.0.0.0/24
# (Optional) KeepAlive sends a packet every 25 seconds to maintain NAT mappings
PersistentKeepalive = 25Install WireGuard on the client and use sudo systemctl start [email protected] to bring up the client interface.
Note on pfSense/Other Firewalls: If your WireGuard server is behind another firewall (like pfSense), ensure that the ListenPort (default 51820/UDP) is open and forwarded to your WireGuard server.