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.