6.5.28 OpenVPN
Run the agent on the OpenVPN host, update client trust once, and point it at the right config
CertKit has three OpenVPN templates. Each one runs on the OpenVPN host itself, so install the CertKit Agent there.
| Template | Agent | What it replaces |
|---|---|---|
| OpenVPN Community Edition Server | Linux | The server certificate and key in the OpenVPN server config. Restarts the systemd unit. |
| OpenVPN Community Edition Server | Windows | The server certificate and key in the .ovpn server profile. Restarts the OpenVPN Windows service. |
| OpenVPN Access Server: Web Services Certificate | Linux | The web certificate for the Admin Web UI, the Client Web UI, and profile downloads. The VPN tunnel isn’t changed. |
All three accept either PEM format: the certificate with its chain plus a key file, or a separate chain file.
OpenVPN Community Edition
Requirements
- OpenVPN Community Edition running as a server on the agent host.
- On Linux, the agent runs as root. On Windows, it needs administrator rights. The template edits the server config and restarts the service.
- The config must use separate
certandkeydirectives or inline<cert>and<key>blocks. A config that usespkcs12is refused. - On Linux,
opensslshould be installed. Without it, the template can’t check that the key matches the certificate. - On Linux, systemd is expected. Without it, the template restarts with
service openvpn restartand can’t confirm that OpenVPN started.
Update client trust before the first deployment
The template replaces only the server certificate and key. The server’s ca (which checks client certificates), tls-auth or tls-crypt key, and every other directive stay as they are, so client certificates keep working.
The clients are what change. An OpenVPN client trusts only the CA in its profile’s ca file or <ca> block, usually the Easy-RSA CA that signed the original server certificate. It ignores the operating system’s trust store. If the new certificate comes from a different CA, clients fail verification and can’t connect.
Before the first deployment:
- Add the root of the new certificate to every client profile’s
ca. You can keep the old CA in the same file during the switch, sincecaaccepts several certificates. - If client profiles use
verify-x509-namewith the old name (for exampleserver), change it to the name on the new certificate. - If you add a public root, also add
verify-x509-namewith your server’s name. OpenVPN doesn’t check the hostname, andremote-cert-tls serveraccepts any server certificate that root has signed. A CertKit private CA that signs only your VPN servers avoids this.
Renewals after the switch come from the same root, so the clients need no further changes.
Variables
Both variables default to auto and are hidden in easy mode. Set them in the Advanced view when you run more than one server instance or use a custom layout.
| Agent | Variable | What to enter |
|---|---|---|
| Linux | OpenVPN server config file | Full path to the server config, for example /etc/openvpn/server/server.conf, or a bare instance name such as server. |
| Linux | systemd unit to restart | The unit that runs that config, for example openvpn-server@server. |
| Windows | OpenVPN server profile (.ovpn) | Full path to the server profile, for example C:\Program Files\OpenVPN\config-auto\server.ovpn, or a bare profile name. |
| Windows | OpenVPN Windows service | OpenVPNService for profiles in config-auto, or OpenVPNServiceLegacy for profiles in config. |
With auto on Linux, the template looks at the active openvpn systemd units. openvpn-server@<name> maps to /etc/openvpn/server/<name>.conf and openvpn@<name> maps to /etc/openvpn/<name>.conf. Other units are read from the --config argument in their ExecStart. Client units (openvpn-client@) are skipped. If no unit is running, it looks for .conf files in /etc/openvpn/server and /etc/openvpn.
With auto on Windows, the template reads the install locations from HKLM\SOFTWARE\OpenVPN and uses the single profile in the automatic-start folder, normally C:\Program Files\OpenVPN\config-auto.
If auto finds more than one server config, the deployment stops and lists them. Set the config variable to the right one.
What happens on each deployment
- Find the config and service. The template resolves the config path and the systemd unit or Windows service, and checks that the unit or service exists.
- Check the new certificate. It confirms the files hold a PEM certificate and an unencrypted PEM key. On Linux it also checks that the key matches the certificate. It warns when the certificate isn’t marked for TLS server use, because clients with
remote-cert-tls serverreject it. - Write the files. The server certificate and every distinct intermediate go into one file,
certkit-<config name>.crt, next to the config. The key goes intocertkit-<config name>.key. OpenVPN sends every certificate after the first as the chain, soextra-certsisn’t needed. On Linux, the certificate file is mode 644, the key is mode 600, and both keep the owner of the files the config used before. - Update the config. The
certandkeydirectives are pointed at the new files. Inline<cert>and<key>blocks are replaced with directives,<extra-certs>blocks are removed, andextra-certsandcryptoapicertlines are commented out with a# certkit:prefix. The original config is saved as<config>.certkit-bak. Nothing is written when the config already points at the CertKit files. - Restart and confirm. If nothing changed, the restart is skipped. Otherwise the template restarts OpenVPN and watches for startup.
- On Linux, it watches the unit and its journal for up to 20 seconds. “Initialization Sequence Completed” is success. “Exiting due to fatal error” or a stopped unit is failure. A unit that is still running after 20 seconds is accepted.
- On Windows, it restarts the service (or starts it if it was stopped), then reads the profile’s log in the OpenVPN log folder for up to 60 seconds. “Initialization Sequence Completed” is success. Errors such as “Cannot load certificate file” or “Private key does not match” are failure.
The Easy-RSA certificate and key the config used before stay on disk, unreferenced.
Rollback
When OpenVPN fails to start on the new certificate, the template restores the config from the backup, puts back the previous certkit- files (or deletes them on a first deployment), and restarts OpenVPN again. The job then fails with “Deployment rolled back; OpenVPN is running the previous certificate.”
On Windows, if the log shows neither success nor a known error within 60 seconds, the template doesn’t roll back. The new files stay in place and the job fails with the path to the backup. Check the log, and copy <profile>.certkit-bak back over the profile if you need to undo the change.
Restarts and disconnects
Restarting OpenVPN disconnects every connected client. Clients reconnect on their own. On Windows, restarting OpenVPNService restarts every profile in config-auto, not only the one this template changed. Use a deploy window to keep restarts outside working hours.
OpenVPN Access Server
Requirements
- OpenVPN Access Server on Linux, with
sacliat/usr/local/openvpn_as/scripts/sacli. - The agent runs as root on the Access Server host.
python3must be available to read the current configuration. Access Server 3 runs on the systempython3. Without it, a rollback can only return to Access Server’s self-signed certificate.opensslmust be installed to confirm the web port serves the new certificate. Without it, the template applies the certificate but can’t verify it.- If you turned on Access Server’s built-in ACME client, turn it off by setting
acme.enabletofalse. Otherwise it replaces the CertKit certificate at its next renewal.
The template has been tested on a standalone Access Server. It changes only the node it runs on. Access Server clusters haven’t been tested.
What it replaces
The template sets the web services certificate, stored in the cs.cert, cs.priv_key, and cs.ca_bundle keys of the Access Server configuration. That certificate serves the Admin Web UI, the Client Web UI, and profile downloads on the web port (cs.https.port, 943 by default).
The VPN tunnel uses Access Server’s internal CA, and every connection profile it issues trusts that CA. The template doesn’t touch it, so existing client profiles keep working.
What happens on each deployment
- Find Access Server. The template locates
sacliand reads the version and web port. - Check the new certificate. It splits the certificate into the server certificate and an intermediate bundle, then runs Access Server’s own
sacli TestWebCertscheck. The template prints the findings but never the raw output, which echoes the private key. - Compare with what’s installed. It reads the current
cs.cert,cs.priv_key, andcs.ca_bundleand keeps them for rollback. If they already match, it stops without changing anything. - Store the new certificate.
sacli ConfigPutwrites the key, the certificate, and the bundle. With no intermediates,cs.ca_bundleis removed. - Apply and verify.
sacli startrestarts the web service. The VPN daemons keep running, so connected VPN sessions stay up. The template then connects to127.0.0.1on the web port for up to 30 seconds and checks that it serves the new certificate’s SHA-1 fingerprint.
Rollback
If sacli start fails or the web port doesn’t serve the new certificate within 30 seconds, the template restores the previous values (or removes them, which returns Access Server to its self-signed certificate) and runs sacli start again.
Common problems
Community Edition
- “No OpenVPN server config found”: no active OpenVPN unit and no
.conffile in the standard folders. Set OpenVPN server config file to the config path. - “Found more than one OpenVPN server config” or “Found more than one profile”: set OpenVPN server config file or OpenVPN server profile (.ovpn) to the one this certificate is for.
- “Could not derive the systemd unit” or “systemd unit ‘…’ is not loaded”: set systemd unit to restart to the unit that runs the config.
- “Windows service ‘…’ was not found”: set OpenVPN Windows service to
OpenVPNServiceorOpenVPNServiceLegacy, whichever runs the profile. - “… uses a pkcs12 bundle for its CA, certificate and key”: split the PKCS#12 file into separate
ca,cert, andkeydirectives, then deploy again. - “The private key in … does not match the certificate”: the deployed files don’t belong together. Reissue the certificate in CertKit.
- “Could not read the private key in … (is it encrypted?)” or “is password-protected; OpenVPN needs an unencrypted key file”: the template only installs unencrypted keys. CertKit writes the key without a password, so check that the deployment uses the CertKit key file.
- “WARNING: the certificate is not marked for TLS server use”: the certificate lacks the TLS server usage, and clients with
remote-cert-tls serverwill reject it. Issue a server certificate. - “Deployment rolled back; OpenVPN is running the previous certificate”: OpenVPN wouldn’t start on the new certificate. The log lines printed above the error show why.
- “Could not confirm ‘Initialization Sequence Completed’ … within 60 seconds” (Windows): the template couldn’t find the success line in the profile’s log. Check that log, and check the
log_dirvalue underHKLM\SOFTWARE\OpenVPN. - Clients fail with
VERIFY ERRORafter a successful deployment: their profiles don’t trust the new certificate’s root, orverify-x509-namestill names the old certificate. See Update client trust before the first deployment.
Access Server
- “OpenVPN Access Server not found”:
sacliis missing. Use the Community Edition template for a plainopenvpninstall. - “Access Server rejected the certificate (TestWebCerts failed)”: the findings printed above the error say why, for example a key that doesn’t match or a chain that doesn’t link up. Nothing was changed.
- “sacli ConfigPut … failed”: Access Server couldn’t store the value. Run
sacli ConfigQueryas root to confirm the configuration database is reachable. - “Deployment rolled back; the web service did not pick up the new certificate”: the web port kept serving a different certificate for 30 seconds. Check
cs.https.port, and check that nothing else on the host answers on that port. - The certificate changes back on its own later: Access Server’s ACME client is turned on. Set
acme.enabletofalse.
For a product overview, see certificate automation for OpenVPN.