Loading...

Lab 104: Installing, Configuring, and Managing OpenVPN

Stand up a basic OpenVPN server using TLS certificates generated by Easy-RSA, then validate service state and issue an initial client certificate. Focus on PKI workflow, secure key placement, and systemd service management on a RHEL-style host.

networking security vpn

Scenario

You are configuring a secure VPN tunnel for remote workers using OpenVPN with TLS-based authentication and encryption. Your goal is to bootstrap a Certificate Authority (CA), issue server credentials, start the OpenVPN instance, and confirm the server reaches an “Initialization Sequence Completed” state.

Operator context

VPN is security infrastructure. Treat keys as secrets, apply least privilege to key files, and validate service behavior before distributing client configs.

Objective

  • Install OpenVPN and Easy-RSA.
  • Initialize PKI and build a local CA.
  • Generate and sign a server certificate.
  • Generate Diffie-Hellman parameters.
  • Stage server keys and certs in /etc/openvpn/.
  • Generate a baseline server config and start the service.
  • Verify service state and generate a client certificate.

Concepts

  • PKI components: CA certificate, CA private key, server cert/key, and client cert/key.
  • Easy-RSA workflow for initializing PKI and signing requests.
  • Secure key placement and permissions under /etc/openvpn/.
  • systemd instance units for OpenVPN: openvpn@server targets /etc/openvpn/server.conf.
  • Service validation signals in systemctl status output and logs.

Walkthrough

Step 1 : Install OpenVPN and Easy-RSA.
Command
sudo dnf install openvpn easy-rsa -y

Install the VPN service and the PKI tooling used to generate and sign certificates. On RHEL-like systems, Easy-RSA may come from an additional repository depending on your build.

Step 2 : Create a working directory for PKI operations.
Command
make-cadir ~/openvpn-ca && cd ~/openvpn-ca
Operator note

Easy-RSA packaging differs across distros. Some provide make-cadir while others expect you to copy the working tree from /usr/share/easy-rsa/ into a writable directory.

Step 3 : Initialize PKI and build the Certificate Authority.
Command
./easyrsa init-pki && ./easyrsa build-ca

The CA is the trust anchor for all certificates in this VPN. Protect pki/private/ca.key like a production secret and keep it off shared paths.

# Confirm CA artifacts:
ls -la pki/ca.crt pki/private/ca.key
Step 4 : Generate and sign the server certificate.
Command
./easyrsa gen-req server nopass && ./easyrsa sign-req server server

This creates the server key and request, then signs it with your CA to produce the server certificate. Use a name that maps cleanly to the OpenVPN instance you are running.

# Confirm server artifacts:
ls -la pki/private/server.key pki/issued/server.crt
Step 5 : Generate Diffie-Hellman parameters.
Command
./easyrsa gen-dh

DH parameters may take time to generate. When complete, you should have pki/dh.pem available for the server configuration.

Step 6 : Stage certificates and keys under /etc/openvpn/.
Command
sudo cp pki/ca.crt pki/private/server.key pki/issued/server.crt pki/dh.pem /etc/openvpn/
Security note

Lock down private keys immediately. Ensure root ownership and restrict permissions for /etc/openvpn/server.key before running a production workload.

# Example hardening:
sudo chown root:root /etc/openvpn/server.key
sudo chmod 600 /etc/openvpn/server.key
Step 7 : Generate a baseline server configuration.
Command
sudo gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf > /dev/null

This gives you a starting config from the upstream sample. In production, explicitly review certificate paths, cipher negotiation, networking rules, and routing behavior before onboarding users.

# Spot-check key directives:
sudo grep -E '^(ca|cert|key|dh) ' /etc/openvpn/server.conf
Step 8 : Enable and start the OpenVPN instance.
Command
sudo systemctl enable --now openvpn@server

The instance name server maps to /etc/openvpn/server.conf for the unit openvpn@server .

Step 9 : Verify service state and confirm initialization.
Command
sudo systemctl status openvpn@server

The key confirmation is Initialization Sequence Completed in the unit status or logs. That indicates OpenVPN parsed config, loaded crypto material, and brought the tunnel interface up successfully.

# Optional log view:
sudo journalctl -u openvpn@server --no-pager
Step 10 : Issue an initial client certificate.
Command
./easyrsa gen-req client1 nopass && ./easyrsa sign-req client client1

You now have CA, server cert/key, and a client cert/key. In a real deployment, the next step is to generate a client configuration file and securely distribute client credentials.

# Confirm client artifacts:
ls -la pki/private/client1.key pki/issued/client1.crt

Common breakpoints

make-cadir not found

Easy-RSA packaging differs. Locate the Easy-RSA working tree under /usr/share/easy-rsa/ and copy it into a writable directory, then run PKI commands from there.

OpenVPN service fails to start

Validate certificate and key paths in /etc/openvpn/server.conf and confirm the files exist with the expected names under /etc/openvpn/ . Then inspect unit logs via journalctl -u openvpn@server .

Initialization Sequence Completed never appears

This typically points to configuration parsing errors, missing crypto material, or networking issues. Confirm the instance name matches the config file and validate the tunnel interface creation from the logs.

Key file permissions warning

Treat this as a real security defect. Restrict permissions on private keys and ensure only root can read them before distributing any client material.

Cleanup checklist

This lab stages keys and configuration on the host and creates a PKI working directory in your home folder. If this is a disposable lab host, stop the service and remove generated artifacts.

Commands
sudo systemctl disable --now openvpn@server
sudo rm -f /etc/openvpn/ca.crt /etc/openvpn/server.crt /etc/openvpn/server.key /etc/openvpn/dh.pem /etc/openvpn/server.conf
rm -rf ~/openvpn-ca
Success signal

The OpenVPN unit is stopped and disabled, PKI artifacts are removed, and no private keys remain on disk in lab paths.

Reference

  • dnf install openvpn easy-rsa -y : Installs OpenVPN and Easy-RSA tooling.
    • -y : Automatically answers yes to prompts.
  • make-cadir <path> : Creates an Easy-RSA working directory (packaging dependent).
  • ./easyrsa init-pki : Initializes the PKI directory structure under pki/.
  • ./easyrsa build-ca : Builds the Certificate Authority certificate and private key.
  • ./easyrsa gen-req <name> [nopass] : Generates a private key and certificate request for a named entity.
    • nopass : Creates the private key without a passphrase.
  • ./easyrsa sign-req <type> <name> : Signs a certificate request with the CA.
    • <type> : Request type such as server or client.
  • ./easyrsa gen-dh : Generates Diffie-Hellman parameters (outputs pki/dh.pem).
  • cp <src...> <dest> : Copies certificate and key files into the OpenVPN configuration directory.
  • chmod 600 <file> : Restricts a private key file to root-only read/write permissions.
    • 600 : Owner read/write only.
  • gunzip -c <file.gz> | tee <file> : Expands a gzipped sample config and writes it to a destination file.
    • -c : Writes decompressed content to stdout.
    • | : Pipes output from the left command into the right command.
  • systemctl enable --now openvpn@server : Enables and starts the OpenVPN instance for server.conf.
    • --now : Starts the unit immediately in addition to enabling it.
    • openvpn@server : Instance unit mapped to /etc/openvpn/server.conf.
  • systemctl status openvpn@server : Shows OpenVPN unit state and recent status output.
  • journalctl -u openvpn@server : Shows logs for the OpenVPN instance unit.
    • -u : Filters by unit name.
  • rm -rf <path> : Removes a directory tree (use with caution).
    • -r : Recursively removes directories and contents.
    • -f : Forces removal and suppresses prompts/errors for missing files.