// Engineering Log

OpenVPN: Part 2 — How It Works: PKI, Certificates, and Basic Setup

Published on 2026-09-22

// Fast route

This article belongs to the topic Networking and routing.

This section explains what an OpenVPN Community installation consists of and how to assemble a minimal working configuration: a certificate authority, server and client certificates, a tls-crypt key, and the server.conf and client.ovpn files. Examples target OpenVPN 2.6 and 2.7 on Linux.

How clients and the server trust each other

OpenVPN uses a public key infrastructure (PKI):

  • certificate authority (CA) — a key pair that signs all other certificates. The CA private key is the most valuable secret in the installation and is best kept off the VPN server;
  • server certificate — signed by the CA and marked as a server certificate. The client verifies that it is connecting to a server, not to another client with a similar certificate;
  • client certificates — one per user or device;
  • certificate revocation list (CRL) — for revoked certificates of dismissed employees and lost devices.

On connection, the sides exchange certificates and verify that both are signed by the same CA. A user password is not required in this scheme but can be added as a second factor.

Certificate authority using easy-rsa

Easy-RSA is a utility from the OpenVPN project for managing a PKI. On Debian and Ubuntu it is provided by the easy-rsa package. Minimal set of commands:

bash
./easyrsa init-pki
./easyrsa build-ca
./easyrsa build-server-full server nopass
./easyrsa build-client-full ivanov
  • init-pki creates the pki directory;
  • build-ca creates the certificate authority and asks for a password for its key — choose a strong one;
  • build-server-full server nopass issues the server key and certificate without a password; otherwise the service cannot start unattended;
  • build-client-full ivanov issues a client key and certificate; with a password — if the user will enter it when connecting, with nopass — if not.

Results are in these directories: pki/ca.crt — CA certificate, pki/issued/ — certificates, pki/private/ — private keys.

Generating Diffie–Hellman parameters (gen-dh) is not necessary. OpenVPN documentation recommends dh none: then ephemeral key exchange uses elliptic curves (ECDH), which is faster and more modern.

tls-crypt key

The tls-crypt option encrypts and signs the entire control channel with a shared key. This provides three benefits: the server does not respond to packets without the key, so scanners do not see OpenVPN on the port; certificates are not transmitted in plaintext; and attacks on the TLS stack by third parties are impossible.

Create the key with:

bash
openvpn --genkey tls-crypt tc.key

The tc.key file is copied to the server and into all client profiles.

UDP or TCP

By default, choose UDP. Inside the tunnel there are already application TCP connections, and when the transport is also TCP, retransmissions overlap and the connection becomes much slower.

TCP (usually on port 443) is justified when UDP is blocked: hotel and corporate networks sometimes allow only web traffic. A convenient scheme is two server instances: a primary on UDP and a fallback on TCP.

Minimal server configuration

File /etc/openvpn/server/server.conf:

port 1194
proto udp
dev tun
topology subnet
server 10.8.0.0 255.255.255.0

ca ca.crt
cert server.crt
key server.key
dh none
tls-crypt tc.key

keepalive 10 120
persist-tun
user nobody
group nogroup

verb 3
explicit-exit-notify 1
  • server 10.8.0.0 255.255.255.0 — tunnel subnet; the server gets 10.8.0.1, clients get the remaining addresses;
  • keepalive 10 120 — connection check every 10 seconds, consider the connection down after 120 seconds of silence;
  • user and group — after startup the service runs without root privileges (on RHEL-compatible systems the group is named nobody);
  • explicit-exit-notify 1 — the server notifies clients about a restart, and they reconnect immediately.

The cipher is intentionally not specified in the configuration: versions 2.6 and 2.7 will negotiate the best common cipher from the data-ciphers list.

To let clients see the office network, add a route, for example push "route 192.168.1.0 255.255.255.0", and enable IP forwarding on the server (net.ipv4.ip_forward = 1). Redirect all client Internet traffic through the VPN with push "redirect-gateway def1", but that also requires NAT on the server.

Start the service like this: systemctl enable --now openvpn-server@server (the name after @ is the configuration file name). On Debian and Ubuntu this service maintains the status file with connected clients itself, so specifying status separately is not necessary.

Client profile

File ivanov.ovpn:

client
dev tun
proto udp
remote vpn.example.ru 1194
resolv-retry infinite
nobind
persist-tun
remote-cert-tls server
verb 3

<ca>
...contents of ca.crt...
</ca>
<cert>
...contents of pki/issued/ivanov.crt...
</cert>
<key>
...contents of pki/private/ivanov.key...
</key>
<tls-crypt>
...contents of tc.key...
</tls-crypt>

remote-cert-tls server is mandatory: it requires that the certificate on the other side be a server certificate. Without it any client with a certificate from the same CA could impersonate the server.

Certificate revocation

When an employee leaves, revoke their certificate:

bash
./easyrsa revoke ivanov
./easyrsa gen-crl

Copy pki/crl.pem to the server and add crl-verify crl.pem to server.conf. The CRL has a validity period, so gen-crl must be repeated before it expires — otherwise the server will stop accepting all clients.

Common mistakes

  • CA private key on the VPN server. If the server is compromised, an attacker can issue their own certificates. Keep the CA on a separate machine and copy only ca.crt to the server.
  • Missing remote-cert-tls server in the profile. The client will trust any certificate from the same CA.
  • Using TCP “just in case”. Unnecessary TCP transport only slows the tunnel.
  • Expired CRL. Clients suddenly stop connecting, and the server log shows a CRL verification error.
  • No IP forwarding. The client connects but cannot see the office network: ip_forward is not enabled or the office gateway has no return route to the tunnel subnet.

Ready step-by-step examples: server on MikroTik — “Setting up an OpenVPN server on MikroTik RouterOS”, server on Ubuntu and client on Keenetic — “OpenVPN: setting up an Ubuntu server and a Keenetic client”. You can order a turnkey VPN deployment on the “VPN setup” page.

// Similar task

If you are dealing with something similar

This article belongs to one of the main working topics. You can keep reading on the topic, go to the homepage to understand what I do, or open the service pages directly.

Article topic

Networking and routing

MikroTik, VPN, routing, DNS, BGP, connectivity, and access troubleshooting.

Typical tasks behind this topic

  • Set up VPN and secure access to office or cloud
  • Fix routing, DNS, or unstable connectivity
  • Configure MikroTik, firewall, and external links

// Next step

If you need help with this topic, not just another article, it is better to go straight to the service page. The homepage and topic collection stay available as secondary routes.

Open services

// Contact

Need help?

Get in touch with me and I'll help solve the problem

I reply within one business day (03:00-13:00 GMT)

Или оставьте заявку здесь:

Confirm that you are not a bot.

Write and get a quick reply