9ffdbfa259f4fa35dc1cf43e7ec7f6efceaf38a0
- ovpmon-helper: new publish-crl command (validated copy of pki/crl.pem to /etc/openvpn/crl.pem, root:root 644); crl-verify allowlisted only for that path; CRL is refreshed on service start/restart. - Profiler: publish after gen-crl (init/revoke) and on server/configure; generator renders the published path when running unprivileged. - doas rule for publish-crl; docs and helper copy updated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
OpenVPN Monitor & Profiler
Web suite for OpenVPN servers: real-time traffic monitoring, history/analytics, PKI and client-profile management, one UI.
| Component | Dir | Stack | Default port |
|---|---|---|---|
| UI | APP_UI/ |
Vue 3 + Vite, served by Nginx | 80 (Docker) / 8088 (native, TLS) |
| Monitoring API | APP_CORE/ |
Flask (gunicorn) | 5001 (internal) |
| Data gatherer | APP_CORE/ |
Python daemon | - |
| Profiler API | APP_PROFILER/ |
FastAPI (uvicorn) | 8000 (internal) |
Nginx is the only public entry point: / UI, /api/ Monitoring API, /profiles-api/ Profiler API.
Quick start
- Containers:
docker-compose up -d --build, openhttp://<host>. Details: Deployment: Docker. - System services (systemd / OpenRC, no containers): Deployment: native.
After the first start: sign in, open PKI Configuration → Initialize PKI, generate the server config, start OpenVPN, create profiles.
First login and credentials
No default user is created. Seed the initial admin with OVPMON_INITIAL_ADMIN_USER / OVPMON_INITIAL_ADMIN_PASSWORD on first start (empty users table only), then remove them. Change the username and password and enable 2FA in Account.
Configuration
config.ini per component; overridden by OVPMON_{SECTION}_{KEY} environment variables.
| Variable | Purpose |
|---|---|
OVPMON_API_SECRET_KEY |
JWT secret shared by both APIs (must be random) |
OVPMON_INITIAL_ADMIN_USER / _PASSWORD |
One-time admin seed |
OVPMON_CORS_ORIGINS |
Extra allowed CORS origins, comma-separated (empty = same-origin only) |
OVPMON_OPENVPN_MONITOR_DB_PATH |
Monitoring DB |
OVPMON_PROFILER_DB_PATH |
Profiler DB |
OVPMON_OPENVPN_MONITOR_LOG_PATH |
openvpn-status.log path |
OVPMON_LOGGING_LEVEL |
INFO / DEBUG |
Documentation
- Index: DOCS/General/Index.md
- Deployment: Docker · System services · Nginx · Service management
- Security model: Security Architecture
- APIs: Monitoring · Profiler
Changes and results
| Date | Change | Document |
|---|---|---|
| 2026-09-30 | Security hardening: path traversal, 2FA token bypass, CORS, log leak, HTTPS, SSH, fail2ban | Security hardening |
| 2026-09-30 | Admin username change (API + UI), no built-in default admin | Admin username change |
| 2026-09-30 | Validation of server/PKI settings (config injection into the root-written OpenVPN config) | Settings validation |
| 2026-09-30 | API services run as an unprivileged user; root helper validates and installs the OpenVPN config | Privilege separation |
| 2026-09-30 | Route OpenVPN clients through a Hysteria2 tunnel to an exit node | Egress via Hysteria2 |
Notes
- Native deployments run the APIs as user
ovpmon; OpenVPN config install and service control go through a root helper (doas, fixed commands): see Privilege separation. - Keep
easy-rsa/,client-config/, databases and*.envout of git: they contain private keys and secrets.
Languages
Python
48.7%
Vue
35.2%
CSS
12%
JavaScript
2.3%
Jinja
0.8%
Other
1%