Installing WireGuard VPN on CentOS Stream 9: Superior Speed, 5-Minute Setup

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

Why I Switched from OpenVPN to WireGuard on CentOS Stream 9

A few years ago, OpenVPN was my “go-to” whenever I needed to set up internal access for a team on CentOS 7. But honestly, wrestling with dozens of CA certificates, certs, and keys was never a pleasant experience. Not to mention, OpenVPN runs in user-space, so speeds often bottleneck on low-end VPS instances.

When I moved to CentOS Stream 9, I experimented with WireGuard and was truly impressed. The biggest selling point is its source code—only about 4,000 lines, compared to OpenVPN’s bloated 100,000+ lines. This doesn’t just make the system lighter; it also allows security experts to audit for vulnerabilities more easily. In real-world testing, WireGuard provides about 15-20% higher throughput and significantly lower latency than older protocols.

If you want a “set and forget” VPN system on CentOS Stream 9, WireGuard is an essential choice.

Real-world Comparison: WireGuard vs. Legacy Solutions

Don’t choose WireGuard just because it’s new. Choose it because it solves the painful issues of traditional protocols.

  • OpenVPN: Supports both TCP/UDP, making it flexible for bypassing firewalls. However, the configuration is extremely bulky and CPU-intensive during encryption processing.
  • IPsec: High security but a sysadmin’s nightmare for manual configuration. One tiny mistake in phase 1 or phase 2 and the connection fails immediately.
  • WireGuard: Runs directly in the Linux kernel-space, utilizing modern encryption like ChaCha20. Setting it up is as simple as adding a public key for SSH.

Quick Comparison Table

Criteria WireGuard OpenVPN
Performance Extremely fast, low battery consumption on mobile devices. Average, resource-intensive.
Encryption ChaCha20, Poly1305 (Modern). Based on OpenSSL (Lots of legacy code).
Configuration Under 10 lines of basic config. Configuration files pages long.

My experience shows: unless you are being blocked by a firewall on UDP ports, WireGuard wins in every category.

Steps to Deploy WireGuard on CentOS Stream 9

Before starting, ensure you have root or sudo privileges. Don’t forget to run dnf update to ensure the system is in its most stable state.

Step 1: Install Repository and Packages

CentOS Stream 9 requires the EPEL repo and sometimes ELRepo to get the latest kernel module builds.

sudo dnf install epel-release elrepo-release -y
sudo dnf install kmod-wireguard wireguard-tools -y

Step 2: Generate Security Key Pairs

WireGuard uses a key-pair mechanism similar to SSH. Each side (Server and Client) needs its own key pair to identify each other.

mkdir -p /etc/wireguard
cd /etc/wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey

At this point, the privatekey file is an invaluable asset; you must never expose it. The publickey file will be used to register client devices.

Step 3: Set Up Server Configuration

Create the file /etc/wireguard/wg0.conf. This is where you define the VPN’s internal IP and the listening port.

[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = <Server_Private_Key_Content>

# Automate port opening and NAT using Firewall-cmd
PostUp = firewall-cmd --add-port=51820/udp; firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" masquerade';
PostDown = firewall-cmd --remove-port=51820/udp; firewall-cmd --remove-rich-rule='rule family="ipv4" source address="10.0.0.0/24" masquerade';

Step 4: Enable IP Forwarding

For the server to forward data from the VPN to the internet, you must enable IP Forwarding in the Linux kernel. Without this step, you will connect to the VPN but won’t be able to access the web.

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

# Permanent Firewall configuration
sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --reload

Step 5: Enable the Service

Start the wg0 interface and enable it to run automatically on every server reboot with the following commands:

sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

Step 6: Connect from a Client

On your personal machine (Windows/macOS), create a similar config file. The crucial part is that the Endpoint must point correctly to the server’s IP and port 51820.

[Interface]
PrivateKey = <Client_Private_Key>
Address = 10.0.0.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = <Server_Public_Key>
Endpoint = <Your_Server_IP>:51820
AllowedIPs = 0.0.0.0/0

Afterward, don’t forget to return to the server to register this client: sudo wg set wg0 peer <Client_Public_Key> allowed-ips 10.0.0.2.

3 “Hard-won” Tips for Real-world Deployment

After several “painful” lessons while deploying for clients, I’ve gathered a few tips to help you save hours of debugging:

  1. MTU Issues: If you see the VPN connecting well but Facebook or YouTube just keeps spinning, try lowering the MTU to 1380 or 1420 in the client config. This is a common error where packets exceed the size allowed by the ISP.
  2. Connection Persistence (Keepalive): If the client is behind a router with a strict firewall, the connection often drops after a few minutes of idle time. Add PersistentKeepalive = 25 to the client config to keep the tunnel open.
  3. SELinux: On CentOS Stream 9, SELinux sometimes blocks WireGuard from reading key files. If you encounter a Permission denied error even when running sudo, check the context of the /etc/wireguard directory.

WireGuard is truly a revolution in VPNs. Installing it on CentOS Stream 9 is now very smooth thanks to excellent support from the new Linux kernel. Good luck setting up your own secure connection system!

Share: