WireGuard is a modern, high-performance VPN protocol built into the Linux kernel since version 5.6. It uses state-of-the-art cryptography (Curve25519, ChaCha20, Poly1305) and has a dramatically smaller codebase than older solutions like OpenVPN or IPsec, making it easier to audit and less prone to vulnerabilities. On RHEL 9, WireGuard support is available through the kernel modules included in the distribution. This tutorial walks through configuring a WireGuard VPN server on RHEL 9 and connecting a Linux client to it.
Prerequisites
- A RHEL 9 server with a public IP address and root or sudo access
- A second RHEL 9 (or any Linux) machine to act as the client
- Firewalld running on the server (
systemctl status firewalld) - Active Red Hat subscription or access to EPEL for package installation
Step 1 — Install WireGuard Tools
The WireGuard kernel module ships with RHEL 9’s kernel. You only need to install the userspace management tools:
sudo dnf install -y epel-release
sudo dnf install -y wireguard-tools
Confirm the module is available:
modinfo wireguard
Step 2 — Generate Server Key Pair
WireGuard uses static Curve25519 key pairs for authentication. Generate the server keys and store them securely — the private key must remain readable only by root.
cd /etc/wireguard
umask 077
wg genkey | tee server_privatekey | wg pubkey > server_publickey
cat server_privatekey
cat server_publickey
Note down both values — you’ll need the public key when configuring clients, and the private key goes into the server config.
Step 3 — Create the Server Configuration
Create /etc/wireguard/wg0.conf. Replace the key placeholders and the client public key with your actual values. The PostUp and PostDown rules configure NAT masquerade so VPN clients can reach the internet through the server.
sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey =
# NAT: replace eth0 with your public-facing interface name
PostUp = firewall-cmd --zone=public --add-masquerade --permanent; firewall-cmd --reload
PostDown = firewall-cmd --zone=public --remove-masquerade --permanent; firewall-cmd --reload
[Peer]
# Linux client
PublicKey =
AllowedIPs = 10.0.0.2/32
Set strict permissions on the config file:
sudo chmod 600 /etc/wireguard/wg0.conf
Step 4 — Enable IP Forwarding and Open the Firewall Port
For the server to route traffic between the VPN tunnel and the internet, kernel IP forwarding must be enabled persistently:
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
Open the WireGuard UDP port in firewalld:
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
Step 5 — Start and Enable the WireGuard Interface
Use wg-quick as a systemd service to bring up the interface automatically at boot:
sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0
# Verify the interface is up
sudo wg show
Step 6 — Configure the Client
On the client machine, generate a key pair and create a matching configuration file. Install wireguard-tools the same way as on the server.
# On the CLIENT machine
cd /etc/wireguard
umask 077
wg genkey | tee client_privatekey | wg pubkey > client_publickey
cat client_publickey # paste this into the server's [Peer] PublicKey
Create the client config at /etc/wireguard/wg0.conf on the client:
[Interface]
Address = 10.0.0.2/24
PrivateKey =
DNS = 1.1.1.1
[Peer]
PublicKey =
Endpoint = :51820
AllowedIPs = 0.0.0.0/0 # route all traffic through VPN
PersistentKeepalive = 25
Bring up the tunnel and test connectivity:
sudo wg-quick up wg0
ping 10.0.0.1 # ping the server's VPN IP
curl https://ifconfig.me # should show the server's public IP
To make the client connection persistent across reboots:
sudo systemctl enable wg-quick@wg0
Conclusion
WireGuard offers an excellent balance of simplicity, performance, and modern cryptographic security. On RHEL 9, the setup requires only a few configuration files and a handful of commands. Because WireGuard is stateless by design — peers are identified purely by their public keys — adding more clients is as simple as generating a new key pair and adding another [Peer] block to the server config. Remember to reload the interface with sudo wg addconf wg0 <(wg-quick strip wg0) or restart the service after adding peers.
Next steps: How to Harden SSH on RHEL 9, How to Install and Configure OpenVPN on RHEL 9, and How to Configure SELinux on RHEL 9.