I've created a private x509 pki structure with openssl that consists of a self signed Root CA, an Intermediate CA and two Signing CA's. The signing CA's are used to separate the signing of certificates for OpenVPN servers and clients as suggested at the bottom of the Security notes section of the OpenVPN HOWTO.

Sign server certificates with one CA and client certificates with a different CA. The client configuration ca directive should reference the server-signing CA file, while the server configuration ca directive should reference the client-signing CA file.

This is all configured and working correctly working correctly. However, I have two separate OpenVPN servers for which I'd like to have separation of access. At the moment a client certificate I've issued for one server will work to access the other server as they're both validated through the same CA certification chain.

How do I separate the usage of the client certificates without creating a separate signing CA for each VPN server?

1 Answer 1


Using hooks

On each server, configure a client-connect hook:

client-connect /etc/openvpn/hooks/client-connect

In the client-connect script, check if the user common name is in a list of common named dedicated for this server instance:


from sys import exit
from os import environ

# Load the list of allowed common-names from file.
# One common name per line.
with open("/etc/openvpn/allowed", "rt") as f:
  allowed = f.read().split("\n")

# Allow if the common name is in the list:     
if environ["common_name"] in allowed:

You can devise any other scheme for deciding if a user is allowed on a given server (naming convention, looking it up in a postgres database, looking if up in a LDAP, etc.)

Using CCD

Alternatively, this list can be defined without hook with client-config-dir:

client-config-dir  /etc/openvpn/ccd

You should only need to touch a file for each allowed common name:

# Add a user to this service:
touch /etc/openvpn/ccd/john.doe
  • 1
    Worth noting that the default script-security behaviour will prevent running an external script with the client-connect option. So if you get a strange error, try adding script-security 2 to the configuration file as well. Oct 27, 2021 at 18:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .