How to Set Up WireGuard VPN on RHEL 7

WireGuard is a modern, high-performance VPN protocol built directly into the Linux kernel (from 5.6 onward) and available as a DKMS module on older kernels like those shipped with RHEL 7. Compared to OpenVPN and IPsec, WireGuard has a dramatically smaller codebase, faster handshake times, and simpler configuration — yet delivers strong cryptography based on Curve25519 key exchange, ChaCha20 encryption, and Poly1305 authentication. This guide shows how to install WireGuard on RHEL 7 using ELRepo, generate keys, configure the server and a client, set up IP forwarding, and add firewall NAT masquerade so clients can route all their traffic through the VPN.

Prerequisites

  • RHEL 7 server with root or sudo access
  • A registered RHEL 7 subscription or CentOS 7 equivalent
  • A static public IP address on the server
  • Ports: UDP 51820 allowed through the firewall
  • A client machine (Linux, Windows, or macOS) with WireGuard installed
  • Basic understanding of IP networking and CIDR notation

Step 1: Enable ELRepo and EPEL Repositories

WireGuard for RHEL 7 is distributed via ELRepo as a DKMS (Dynamic Kernel Module Support) package. Install ELRepo first, then EPEL for supporting utilities:

sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
sudo yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
sudo yum install -y epel-release

Verify ELRepo is enabled:

yum repolist | grep elrepo

Step 2: Install the WireGuard Kernel Module and Tools

Install the DKMS module, which builds the kernel module against your running kernel, plus the userspace tools:

sudo yum install -y kmod-wireguard wireguard-tools

If the kmod-wireguard package is not available for your exact kernel version, use the DKMS variant instead:

sudo yum install -y kernel-devel-$(uname -r)
sudo yum install -y wireguard-dkms wireguard-tools

Verify the module loads cleanly:

sudo modprobe wireguard
lsmod | grep wireguard

You should see wireguard listed in the module output.

Step 3: Generate Server Key Pair

WireGuard uses static Curve25519 key pairs. Generate the server’s private and public keys:

wg genkey | sudo tee /etc/wireguard/server_private.key | 
  wg pubkey | sudo tee /etc/wireguard/server_public.key

Protect the private key so only root can read it:

sudo chmod 600 /etc/wireguard/server_private.key

Display the keys so you can copy them into the configuration:

sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key

Step 4: Generate Client Key Pair

Generate a key pair for the first client. Do this on the server (or on the client machine) — the important thing is to keep the private key on the client only:

wg genkey | tee /tmp/client1_private.key | wg pubkey > /tmp/client1_public.key
cat /tmp/client1_private.key
cat /tmp/client1_public.key

Also generate a pre-shared key (PSK) for additional symmetric encryption layer per peer:

wg genpsk | sudo tee /etc/wireguard/client1_psk.key
sudo chmod 600 /etc/wireguard/client1_psk.key

Step 5: Create the Server Configuration

Create the WireGuard server interface configuration at /etc/wireguard/wg0.conf. Replace the placeholder values with your actual keys and IP addresses:

sudo vi /etc/wireguard/wg0.conf
[Interface]
# The VPN IP address of this server
Address = 10.0.0.1/24

# Port WireGuard listens on
ListenPort = 51820

# Server private key (contents of server_private.key)
PrivateKey = <SERVER_PRIVATE_KEY>

# Save config when peers are added dynamically with wg addpeer
SaveConfig = false

# Run iptables NAT rules when interface comes up
PostUp   = iptables -A FORWARD -i wg0 -j ACCEPT; 
           iptables -A FORWARD -o wg0 -j ACCEPT; 
           iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; 
           iptables -D FORWARD -o wg0 -j ACCEPT; 
           iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Client 1
PublicKey  = <CLIENT1_PUBLIC_KEY>
PresharedKey = <CLIENT1_PSK>
# The IP address this client is allowed to use inside the VPN
AllowedIPs = 10.0.0.2/32

Replace eth0 with your actual outbound interface name. Check it with ip route get 8.8.8.8 | awk '{print $5; exit}'.

Secure the configuration file:

sudo chmod 600 /etc/wireguard/wg0.conf

Step 6: Enable IP Forwarding

For the server to route traffic between the VPN clients and the internet, IP forwarding must be enabled. Edit /etc/sysctl.conf or create a drop-in file:

sudo vi /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

Apply immediately without rebooting:

sudo sysctl -p /etc/sysctl.d/99-wireguard.conf

Verify it took effect:

sysctl net.ipv4.ip_forward
# Expected: net.ipv4.ip_forward = 1

Step 7: Open the Firewall Port

Allow UDP 51820 through firewalld:

sudo firewall-cmd --permanent --add-port=51820/udp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports

If you are using raw iptables instead of firewalld:

sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT
sudo service iptables save

Step 8: Bring Up the WireGuard Interface

Use wg-quick to start the interface, which handles IP assignment, routing, and the PostUp/PostDown iptables rules:

sudo wg-quick up wg0

Check the interface status:

sudo wg show wg0
ip addr show wg0

The output of wg show will display the public key, listening port, and any connected peers. Enable WireGuard to start automatically on boot:

sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
sudo systemctl status wg-quick@wg0

Step 9: Create the Client Configuration

Create a .conf file for the client. This file stays on the client machine (never on the server):

[Interface]
# Client's VPN IP
Address = 10.0.0.2/24

# Client private key
PrivateKey = <CLIENT1_PRIVATE_KEY>

# Use a public DNS resolver through the tunnel
DNS = 1.1.1.1

[Peer]
# Server's public key
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <CLIENT1_PSK>

# Server's public IP and port
Endpoint = YOUR_SERVER_PUBLIC_IP:51820

# Route ALL traffic through the VPN (0.0.0.0/0)
# Use 10.0.0.0/24 for split-tunnel (VPN traffic only)
AllowedIPs = 0.0.0.0/0, ::/0

# Keep NAT connections alive
PersistentKeepalive = 25

On a Linux client, bring the tunnel up with:

sudo wg-quick up /path/to/client1.conf

On Windows or macOS, import the .conf file into the official WireGuard GUI app.

Step 10: Verify the Tunnel

From the server, watch for handshakes after the client connects:

sudo watch -n 2 wg show

You should see a latest handshake timestamp and a transfer byte count for the peer. From the client, verify traffic is flowing through the VPN:

ping 10.0.0.1        # Ping the VPN server internal address
curl https://ifconfig.me  # Should return the server's public IP

WireGuard is now operational on your RHEL 7 server. Its minimal configuration surface makes it easy to audit, and its kernel-space implementation delivers excellent performance. To add more clients, generate a new key pair and PSK, add a new [Peer] block to wg0.conf, and run sudo wg addconf wg0 <(wg-quick strip wg0) to reload the config live without dropping existing tunnels. Keep the server’s wg0.conf and all private key files readable only by root, and rotate pre-shared keys periodically for additional long-term security.