How to Discover and List All Connected Clients in an OpenVPN Server Network


2 views

When deploying an OpenVPN server with multiple clients in a private subnet (e.g., 10.8.0.0/24), clients often need to discover other connected peers. This is particularly useful for:

  • Peer-to-peer applications
  • Internal service discovery
  • Network monitoring
  • Distributed computing

OpenVPN provides several native mechanisms for client discovery:

1. Using client-config-dir Files

Create individual client config files in your server's client-config-dir:


# In server.conf
client-config-dir /etc/openvpn/ccd

# Example CCD file for client1
ifconfig-push 10.8.0.10 255.255.255.0

2. Status File Parsing

Enable the status file in your server configuration:


# In server.conf
status /var/log/openvpn-status.log
status-version 2

Then parse it with a simple script:


#!/bin/bash
awk '/^CLIENT_LIST/ {print $2,$3}' /var/log/openvpn-status.log

For more advanced discovery, consider these approaches:

Python Status File Parser


import re

def parse_openvpn_status(filepath):
    clients = []
    with open(filepath) as f:
        for line in f:
            if line.startswith('CLIENT_LIST'):
                parts = re.split(r'\s+', line.strip())
                clients.append({
                    'name': parts[1],
                    'ip': parts[2],
                    'connected_since': parts[4]
                })
    return clients

Broadcast Ping Sweep

A simple bash solution for clients to discover peers:


#!/bin/bash
NETWORK="10.8.0.0/24"
nmap -sn $NETWORK | grep "Nmap scan report" | awk '{print $5}'

When implementing client discovery:

  • Restrict status file access with proper permissions
  • Consider rate limiting discovery requests
  • Use OpenVPN's built-in TLS authentication
  • Implement client-to-client restrictions if needed

For more complex environments:

  • Integrate with existing service discovery (Consul, etcd)
  • Use a simple REST API on the OpenVPN server
  • Implement a custom heartbeat protocol

When setting up an OpenVPN server with multiple clients in a private subnet (e.g., 10.8.0.0/24), administrators often need a way to discover which IP addresses are currently assigned to connected clients. While OpenVPN creates the virtual network, it doesn't provide built-in client discovery mechanisms beyond basic connectivity.

The most reliable approach is to query the OpenVPN server's status log:

# Method 1: Using management interface
echo "status 2" | nc localhost 7505

# Method 2: Parsing status file
cat /etc/openvpn/openvpn-status.log

# Sample output format:
# OpenVPN CLIENT LIST
# Updated,Thu Sep 22 10:45:12 2022
# Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since
# client1,10.8.0.10:52413,124512,45123,Thu Sep 22 10:30:01 2022
# client2,10.8.0.11:52414,23412,12345,Thu Sep 22 10:35:22 2022

For clients to discover each other without server access:

# Bash script using nmap (requires network access)
#!/bin/bash
nmap -sn 10.8.0.0/24 -oG - | grep "Status: Up" | awk '{print $2}'

# Python alternative:
import subprocess
result = subprocess.run(['nmap', '-sn', '10.8.0.0/24'], 
                       capture_output=True, text=True)
print([line.split()[-1] for line in result.stdout.splitlines() 
       if 'Nmap scan report' in line])

For more sophisticated tracking, consider these approaches:

# Using client-connect script (server-side)
#!/bin/bash
# /etc/openvpn/client-connect.sh
echo "$common_name connected with $ifconfig_pool_remote_ip" >> /var/log/openvpn_clients.log

# Then in server.conf:
client-connect /etc/openvpn/client-connect.sh

Remember that allowing clients to discover each other has security implications:

  • Enable proper firewall rules in the VPN subnet
  • Consider using client-to-client directive in server.conf carefully
  • For production environments, implement proper authentication

Instead of full discovery, push specific routes when needed:

# In server configuration
push "route 10.8.0.8 255.255.255.248"