The Rub


OpenVPN Whitelist on Common Name (CN)

Due to a variety of circumstances out of my control, I found it necessary to control access to an OpenVPN server without depending on a certificate revocation list. After some effort, I discovered a way to execute a script that can check the common name of the client certificate and use the return code to authorize the connection.

First, create a whitelist file. One CN per line. For example, let’s say you have three openvpn clients:

# cat CN_whitelist

Second, create a verify-cn script. Here’s mine:

# original from

# verify-cn -- whitelist based on common name of client certificates
# Return 0 if cn matches the common name component of
# X509_NAME_oneline, 1 otherwise.
# In OpenVPN, enable like this:
#   tls-verify "./verify-cn whitelist_file"
# This would cause the connection to be dropped unless
# the client common name is in whitelist_file.
# Format of whitelist_file is simple one CN per line.

import re, sys

if len(sys.argv) < 4:
    sys.exit("Usage: %s whitelist_file depth x509_subject" % sys.argv[0])

whitelist_file = sys.argv[1]
depth = int(sys.argv[2])
x509 = sys.argv[3]

## If depth is nonzero, tell OpenVPN to continue processing
## the certificate chain.
if depth!=0:

m ='\/CN=([^\/]+)', x509)
if m and
    # read whitelist
    f = open(whitelist_file, 'r')
    for line in f:
        if ( == line.rstrip()):

sys.exit(1) # reject

Then add the following to openvpn.conf:

tls-verify "./verify-cn CN_whitelist"

I’m not sure this should be a primary means of security. However, it could be useful in cases like mine where the crl was not sufficient.

It is useful in addition to a crl because a crl is a blacklist, while this is a whitelist. If it’s possible that some keys have been created that you may not be aware of, this might prevent them from slipping through.