Stackvora.tech

WireGuard Quick Start

A concise, technical guide to setting up a basic WireGuard VPN tunnel between a server and a client on Linux, covering configuration, key generation, and common issues.

Introduction

WireGuard is a modern, high-performance VPN protocol known for its simplicity, speed, and strong cryptographic primitives. Unlike traditional VPN solutions, its lean codebase (approximately 4,000 lines) simplifies auditing and reduces attack surface. This guide details the essential steps to establish a basic WireGuard tunnel between two Linux machines, one acting as the server and the other as the client.

Prerequisites and Installation

Before proceeding, ensure both your server and client machines are running a recent Linux distribution. WireGuard is integrated into the Linux kernel since version 5.6, meaning modern distributions often have it available directly. For older kernels or specific environments, DKMS modules might be required.

Installation on Debian/Ubuntu

On Debian 10+ or Ubuntu 20.04+ (or later LTS releases), WireGuard can be installed directly from the official repositories:

sudo apt update
sudo apt install wireguard resolvconf

resolvconf is recommended for easy DNS management on the client side.

Installation on RHEL/CentOS/Fedora

For RHEL 8+, CentOS 8+, or Fedora, WireGuard is available via EPEL or COPR:

# For RHEL/CentOS 8+
sudo dnf install epel-release
sudo dnf install wireguard-tools qrencode # qrencode for mobile client QR codes

# For Fedora
sudo dnf install wireguard-tools qrencode

Key Generation

WireGuard relies on public-key cryptography for secure communication. Each peer in the VPN tunnel requires a unique public and private key pair. Generate these pairs on both the server and the client machine. Keep private keys secure and never share them.

# On both server and client

# Generate private key
wg genkey | tee privatekey

# Derive public key from private key
cat privatekey | wg pubkey > publickey

After running these commands, you will have two files: privatekey and publickey in your current directory. Make sure to differentiate between the server's keys and the client's keys.

  • Server: server_privatekey, server_publickey
  • Client: client_privatekey, client_publickey

Server Configuration (wg0.conf)

The WireGuard configuration file is typically located at /etc/wireguard/wg0.conf (where wg0 is the interface name). Create this file on your server machine.

# /etc/wireguard/wg0.conf

[Interface]
# Internal VPN IP address for the server. Choose a private range not in use on your network.
Address = 10.0.0.1/24
# The UDP port WireGuard will listen on. Default is 51820.
ListenPort = 51820
# The server's private key (content of server_privatekey file).
PrivateKey = <SERVER_PRIVATE_KEY>

# Optional: Post-up/down rules for NAT and IP forwarding.
# These rules enable the server to route traffic from clients to the internet.
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -A FORWARD -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -D FORWARD -o wg0 -j ACCEPT

[Peer]
# This section defines a client that can connect to this server.
# The client's public key (content of client_publickey file).
PublicKey = <CLIENT_PUBLIC_KEY>
# The internal VPN IP address assigned to this specific client.
AllowedIPs = 10.0.0.2/32

# You can add more [Peer] sections for additional clients. Each needs a unique PublicKey and AllowedIPs.

Replace <SERVER_PRIVATE_KEY> with the actual content of your server_privatekey file, and <CLIENT_PUBLIC_KEY> with the content of your client_publickey file. Adjust eth0 in the PostUp/PostDown rules to match your server's primary network interface (e.g., ens3, enp0s3).

Enable IP Forwarding on Server

For the server to route traffic between the VPN tunnel and the internet, IP forwarding must be enabled:

# Temporarily enable (until reboot)
sudo sysctl -w net.ipv4.ip_forward=1

# Permanently enable (edit /etc/sysctl.conf)
sudo sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf
sudo sysctl -p

Start WireGuard on Server

After configuring, start and enable the WireGuard service:

sudo systemctl enable --now wg-quick@wg0

Verify the status:

sudo wg show wg0

You should see information about the interface, its public key, listening port, and configured peers (currently just the client).

Client Configuration (wg0.conf)

Create the client's configuration file, typically also at /etc/wireguard/wg0.conf, on the client machine.

# /etc/wireguard/wg0.conf

[Interface]
# Internal VPN IP address for the client.
Address = 10.0.0.2/32
# The client's private key (content of client_privatekey file).
PrivateKey = <CLIENT_PRIVATE_KEY>
# Optional: DNS servers to use when the VPN is active.
# Example for Cloudflare DNS:
DNS = 1.1.1.1, 1.0.0.1

[Peer]
# The server's public key (content of server_publickey file).
PublicKey = <SERVER_PUBLIC_KEY>
# The public IP address and ListenPort of your WireGuard server.
Endpoint = <SERVER_PUBLIC_IP_OR_HOSTNAME>:51820
# The networks to route through the VPN. 0.0.0.0/0 sends all traffic.
AllowedIPs = 0.0.0.0/0
# KeepAlive sends a small packet every 25 seconds to keep NAT mappings open.
# Useful if the server is behind NAT or for mobile clients.
PersistentKeepalive = 25

Replace <CLIENT_PRIVATE_KEY> with the client's private key, <SERVER_PUBLIC_KEY> with the server's public key, and <SERVER_PUBLIC_IP_OR_HOSTNAME> with the server's public IP address or FQDN.

Start WireGuard on Client

Start and enable the WireGuard service on the client:

sudo systemctl enable --now wg-quick@wg0

Verify the status and connectivity:

sudo wg show wg0
ping 10.0.0.1 # Ping the server's VPN IP
curl ifconfig.me # Check your public IP, should be the server's if 0.0.0.0/0 is used

Firewall Configuration

It's crucial to properly configure firewalls on both the server and client. On the server, allow incoming UDP traffic on the WireGuard ListenPort (default 51820). If using PostUp/PostDown rules, ensure the firewall permits forwarded traffic.

UFW (Uncomplicated Firewall - Debian/Ubuntu)

# On server
sudo ufw allow 51820/udp
sudo ufw enable

Firewalld (RHEL/CentOS/Fedora)

# On server
sudo firewall-cmd --add-port=51820/udp --permanent
sudo firewall-cmd --reload

Common Pitfalls and Troubleshooting

  • Incorrect Keys: Double-check that the private and public keys are correctly copied to their respective configuration files. A common error is swapping client and server keys, or private and public keys.
  • Firewall Blocking: The most frequent issue. Ensure UDP port 51820 (or your chosen port) is open on the server and that IP forwarding is allowed by firewall rules.
  • IP Forwarding Disabled: If the client can ping the server's VPN IP (10.0.0.1) but cannot access the internet, IP forwarding (net.ipv4.ip_forward) is likely not enabled on the server.
  • Wrong Interface Name in PostUp/PostDown: If you used eth0 in the PostUp/PostDown rules but your server's public interface is named differently (e.g., ens33), NAT will fail. Use ip a to find the correct interface name.
  • AllowedIPs Mismatch: On the server, ensure AllowedIPs for a peer exactly matches that peer's Address. On the client, AllowedIPs = 0.0.0.0/0 is typical for full tunnel.
  • Log Analysis: Use sudo journalctl -u wg-quick@wg0 on both server and client to inspect logs for errors.
  • WireGuard Version: Ensure both client and server are running reasonably current WireGuard versions (e.g., 1.0.20200520 or newer) for best compatibility and features.

Back to the knowledge base · Ask the AI assistant