How to List All Active OpenVPN Certificates with Common Names on Ubuntu Server


12 views

When managing an OpenVPN server on Ubuntu, you often need to monitor currently connected clients. The easiest way is to check the OpenVPN status file:

cat /etc/openvpn/openvpn-status.log

This will display output similar to:

OpenVPN CLIENT LIST
Updated,Thu Oct 12 15:30:45 2023
Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
client1,192.168.1.100:12345,1.2MB,3.4MB,Thu Oct 12 14:15:30 2023
client2,192.168.1.101:54321,5.6MB,7.8MB,Thu Oct 12 13:30:15 2023
ROUTING TABLE
Virtual Address,Common Name,Real Address,Last Ref
10.8.0.2,client1,192.168.1.100:12345,Thu Oct 12 15:30:40 2023
10.8.0.3,client2,192.168.1.101:54321,Thu Oct 12 15:29:55 2023
GLOBAL STATS
Max bcast/mcast queue length,0
END

To get more detailed certificate information, you can parse the OpenVPN server log:

grep "certificate" /var/log/openvpn.log | awk '{print $NF}' | sort | uniq

For a more comprehensive view including expiry dates:

cd /etc/openvpn/easy-rsa/keys/
for cert in *.crt; do
  openssl x509 -in $cert -noout -subject -enddate
done

Here's a Python script to list active certificates with their common names and connection details:

import re
from datetime import datetime

def parse_openvpn_status():
    with open('/etc/openvpn/openvpn-status.log', 'r') as f:
        data = f.read()
    
    clients = re.findall(r'^(\w+),\d+\.\d+\.\d+\.\d+:\d+.*?(\d{4}-\d{2}-\d{2})', data, re.M)
    return clients

active_certs = parse_openvpn_status()
for cn, expiry in active_certs:
    print(f"Common Name: {cn}, Expiry Date: {expiry}")

To manage certificates effectively, consider these commands:

# List all issued certificates
cat /etc/openvpn/easy-rsa/keys/index.txt

# Revoke a specific certificate
cd /etc/openvpn/easy-rsa/
source vars
./revoke-full client_name

Remember to restart OpenVPN after making changes:

systemctl restart openvpn@server

When managing an OpenVPN server with multiple client connections, tracking active certificates becomes crucial for security audits and connection management. Unlike some VPN solutions, OpenVPN doesn't maintain a built-in certificate status database - it relies on the underlying PKI infrastructure.

The most reliable method leverages the easy-rsa tools that typically come with OpenVPN installations. Navigate to your easy-rsa directory (usually /etc/openvpn/easy-rsa/) and run:

cd /etc/openvpn/easy-rsa/
source vars
./list-crl

This generates a Certificate Revocation List (CRL) that indirectly shows active certificates - any certificate not on this list is considered active.

For a more detailed view including Common Names, process the index.txt file:

cat /etc/openvpn/easy-rsa/keys/index.txt | awk -F '/' '{print $1,$6,$7,$8}'

Output columns represent: certificate status (V=valid, R=revoked), expiration date, revocation date (if applicable), and serial number with Common Name.

Create a Python script for better formatting:

#!/usr/bin/python3
import os, datetime

vpn_path = "/etc/openvpn/easy-rsa/keys/"
with open(vpn_path + "index.txt") as f:
    for line in f:
        if line.startswith("V"):
            parts = line.split('\t')
            expiry = datetime.datetime.strptime(parts[1], '%Y%m%d%H%M%SZ')
            print(f"CN: {parts[-1].strip()} | Expires: {expiry} | Serial: {parts[3]}")

Combine certificate data with current connections using OpenVPN's management interface. First enable it in server.conf:

management 127.0.0.1 7505

Then query active connections:

echo "status 2" | nc 127.0.0.1 7505

Proactively track expiring certificates with this bash one-liner:

grep "^V" /etc/openvpn/easy-rsa/keys/index.txt | awk '{print $2,$5}' | while read exp cn; do
    exp_date=$(date -d "${exp:0:8} ${exp:8:4}" +%s)
    now=$(date +%s)
    diff=$(( (exp_date - now) / 86400 ))
    echo "$cn expires in $diff days"
done