OpenVPN is a mature, battle-tested VPN solution that uses TLS for control-channel encryption and supports both UDP and TCP transports, making it highly adaptable to restrictive network environments. On RHEL 8 it is available from the EPEL repository, and the Easy-RSA toolkit simplifies the PKI management needed to issue server and client certificates. This guide covers building a full certificate authority, generating all required keys and certificates, configuring the OpenVPN server, enabling IP forwarding with NAT, and producing a portable client .ovpn profile. Following these steps results in a production-ready OpenVPN server with certificate-based mutual authentication.
Prerequisites
- RHEL 8 server with a public IP and a non-root sudo user
- EPEL 8 repository enabled (
dnf install -y epel-release) - firewalld active and SELinux in enforcing mode
- Outbound internet access from the server for package downloads
- An OpenVPN client installed on your local machine
Step 1 — Install OpenVPN and Easy-RSA
Install both packages from EPEL and copy the Easy-RSA template directory to a working location.
sudo dnf install -y openvpn easy-rsa
# Copy Easy-RSA to a working directory
mkdir -p ~/easy-rsa
cp -r /usr/share/easy-rsa/3/* ~/easy-rsa/
cd ~/easy-rsa
Step 2 — Initialize the PKI and Build the Certificate Authority
Easy-RSA manages all certificate operations through its easyrsa script. Initialize the PKI directory, then create a root CA. The CA private key should never leave this machine.
cd ~/easy-rsa
# Initialize the PKI directory
./easyrsa init-pki
# Build the CA (you will be prompted for a passphrase and Common Name)
./easyrsa build-ca
# Generate the server certificate request and sign it
./easyrsa gen-req server nopass
./easyrsa sign-req server server
# Generate Diffie-Hellman parameters (may take several minutes)
./easyrsa gen-dh
# Generate a TLS auth key for additional HMAC protection
openvpn --genkey secret ~/easy-rsa/pki/ta.key
Step 3 — Copy PKI Files to the OpenVPN Directory
Collect all required server-side files into /etc/openvpn/server/ and set restrictive permissions.
sudo cp ~/easy-rsa/pki/ca.crt /etc/openvpn/server/
sudo cp ~/easy-rsa/pki/issued/server.crt /etc/openvpn/server/
sudo cp ~/easy-rsa/pki/private/server.key /etc/openvpn/server/
sudo cp ~/easy-rsa/pki/dh.pem /etc/openvpn/server/
sudo cp ~/easy-rsa/pki/ta.key /etc/openvpn/server/
sudo chmod 600 /etc/openvpn/server/server.key /etc/openvpn/server/ta.key
Step 4 — Create the Server Configuration File
Write the main server configuration to /etc/openvpn/server/server.conf. This example uses UDP on port 1194, the tun device, and pushes a default route so all client traffic is tunneled through the server.
sudo bash -c 'cat > /etc/openvpn/server/server.conf << "EOF"
port 1194
proto udp
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
tls-auth /etc/openvpn/server/ta.key 0
cipher AES-256-GCM
auth SHA256
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
keepalive 10 120
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
verb 3
EOF'
sudo mkdir -p /var/log/openvpn
Step 5 — Enable IP Forwarding, NAT, and Start OpenVPN
Enable kernel IP forwarding, configure firewalld masquerading so VPN clients can reach the internet, open the OpenVPN port, and start the service.
# Persist IP forwarding
echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-openvpn.conf
sudo sysctl -p /etc/sysctl.d/99-openvpn.conf
# Firewall rules
sudo firewall-cmd --permanent --add-service=openvpn
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --reload
# Start and enable the server
sudo systemctl enable --now openvpn-server@server
# Check status
sudo systemctl status openvpn-server@server
Step 6 — Generate a Client Certificate and .ovpn Profile
Generate a certificate for the first client, then assemble all keys and certificates into a single inline .ovpn file for easy distribution.
cd ~/easy-rsa
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1
# Inline all PKI material into one .ovpn file
cat > ~/client1.ovpn << EOF
client
dev tun
proto udp
remote 1194
resolv-retry infinite
nobind
persist-key
persist-tun
cipher AES-256-GCM
auth SHA256
verb 3
key-direction 1
$(cat ~/easy-rsa/pki/ca.crt)
$(cat ~/easy-rsa/pki/issued/client1.crt)
$(cat ~/easy-rsa/pki/private/client1.key)
$(cat ~/easy-rsa/pki/ta.key)
EOF
Conclusion
You now have a fully functional OpenVPN server on RHEL 8 backed by a custom certificate authority, DH parameters, TLS-auth HMAC protection, and AES-256-GCM encryption. The generated client1.ovpn file contains all required PKI material and can be imported directly into any OpenVPN-compatible client. Revoke certificates at any time using ./easyrsa revoke clientN followed by ./easyrsa gen-crl and referencing the CRL in your server configuration.
Next steps: How to Set Up WireGuard VPN on RHEL 8, How to Install ClamAV Antivirus on RHEL 8, and How to Harden SSH on RHEL 8.