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


4 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