OpenVPN Integration with Grafana Dashboard using Prometheus & Kumina Exporter

Overview

This document outlines how to integrate an OpenVPN server with Grafana dashboards for real-time monitoring using Prometheus and the Kumina OpenVPN Exporter, and how to display authenticated Keycloak usernames by configuring server.conf.


Objective

  • Export VPN metrics (connected users, traffic, etc.) from OpenVPN

  • Visualize metrics in Grafana using Prometheus

  • Display actual usernames (from Keycloak) instead of default "client" labels

Architecture

csharp
[OpenVPN Server] 
      ↓ 
[Status Log + OAuth2 Script]
      ↓ 
[Kumina Exporter (Docker)]
      ↓ 
[Prometheus] 
      ↓ 
[Grafana Dashboard]

Step 1: Configure OpenVPN with OAuth2 (Keycloak)

Ensure OpenVPN is set up with openvpn-auth-oauth2 to authenticate users from Keycloak.

Sample relevant lines in server.conf

conf
verify-client-cert none # Replaces deprecated 'client-cert-not-required' 
username-as-common-name # Ensures Keycloak username is shown in status 
auth-user-pass-verify /etc/openvpn/oauth2-auth.sh via-env 
status /var/log/openvpn/status.log # Location of the status file 
status-version 2 
duplicate-cn # Allows multiple connections with same username

⚠️ Do NOT use client-cert-not-required — it has been removed in newer OpenVPN versions.


Step 2: Ensure oauth2-auth.sh Writes the Username (Optional)

You can write a basic script like:

bash
#!/bin/bash 
echo "$username" > /tmp/openvpn_last_user 
exit 0

Make sure it has executable permission:

bash
chmod +x /etc/openvpn/oauth2-auth.sh

Step 3: Run Kumina Exporter in Docker

bash
docker run -d \ 
 --name openvpn-exporter \ 
 -p 9176:9176 \ 
 -v /var/log/openvpn/status.log:/etc/openvpn_exporter/status:ro \ 
 kumina/openvpn-exporter

Ensure that the status.log is mounted read-only (:ro) and exists at the path used in Prometheus.


Step 4: Configure Prometheus

prometheus.yml

yaml
scrape_configs: 
  - job_name: 'openvpn' 
    static_configs: 
       - targets: ['<VPN_SERVER_IP>:9176']

Restart Prometheus:

bash
docker restart prometheus

Step 5: Import Grafana Dashboard

Use the official Kumina dashboard or import JSON dashboard using:

  • Data source: Prometheus

  • Example dashboard ID (if using Grafana.com): 10477

Modify panel labels like:

promql
openvpn_server_client_received_bytes_total{common_name!="UNDEF"}

To show actual usernames pulled from status.log via common_name.


Validation Checklist

Component

Status Check

OpenVPN Service

systemctl status openvpn@server

Status Log

cat /var/log/openvpn/status.log

Exporter

curl http://localhost:9176/metrics

Prometheus

http://<prometheus-ip>:9090/targets

Grafana Panels

Ensure real usernames appear in dashboard


Notes

  • The field common_name from status.log is populated by the Keycloak username.

  • If usernames still appear as client, double-check the .ovpn client config and ensure auth-user-pass is properly defined.

  • Avoid using generic certificates. Let Keycloak provide identity via openvpn-auth-oauth2.


Conclusion

You have successfully set up OpenVPN monitoring with user identification using:

  • ✅ OAuth2 (Keycloak)

  • ✅ Prometheus with Kumina Exporter

  • ✅ Grafana Dashboards

This setup ensures security, visibility, and auditability of all VPN users.