Compose: require JWT secret, seed admin via env, stop publishing internal ports

- JWT_SECRET is mandatory (no more "supersecret" fallback).
- Pass OVPMON_INITIAL_ADMIN_USER/PASSWORD and OVPMON_CORS_ORIGINS to the
  APIs; add restart policy and drop the obsolete compose "version".
- Publish only 80/tcp and 1194/udp; expose 5001 and 8000 on ovp-net.
- CORS origins now come from OVPMON_CORS_ORIGINS instead of a hardcoded
  host (default: same-origin only).
- Update Docker/native deployment docs and README accordingly.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
iclaoudezinandClaude Sonnet 5.5 committed 2026-09-30 12:14:22 +00:00
1 parent 9b2882d5f4
commit 5de0501cbc
6 files changed
+57 -33

No files matched your search

+15 -7
View File
@@ -15,7 +15,7 @@ Volumes: `ovp_logs`, `ovp_config`, `ovp_pki`, `ovp_client_config`, `db_data`.
## Steps
1. Set a random JWT secret and the initial admin (compose reads them from the environment / `.env`):
1. Create `.env` next to `docker-compose.yml` (`JWT_SECRET` is mandatory: compose refuses to start without it):
```bash
cat > .env <<EOT
JWT_SECRET=$(openssl rand -hex 32)
@@ -24,17 +24,25 @@ Volumes: `ovp_logs`, `ovp_config`, `ovp_pki`, `ovp_client_config`, `db_data`.
EOT
chmod 600 .env
```
Pass the two `OVPMON_INITIAL_ADMIN_*` variables to `app-api` (`environment:`) for the first start.
2. `docker-compose up -d --build`
3. Open `http://<host>`, sign in, **PKI Configuration → Initialize PKI**.
4. Remove `OVPMON_INITIAL_ADMIN_*` from `.env` and recreate `app-api`.
4. Remove `OVPMON_INITIAL_ADMIN_*` from `.env` and run `docker-compose up -d app-api` (the seed is used only while the users table is empty).
## Compose settings
| Item | Value |
|---|---|
| Published ports | `80/tcp` (UI) and `1194/udp` (VPN) only; `5001` and `8000` are `expose`d on `ovp-net` and reached through Nginx in `app-ui` |
| Secrets | `JWT_SECRET` (required) → `OVPMON_API_SECRET_KEY` for both APIs |
| Initial admin | `OVPMON_INITIAL_ADMIN_USER` / `OVPMON_INITIAL_ADMIN_PASSWORD` (optional, first start) |
| CORS | `OVPMON_CORS_ORIGINS` (optional, comma-separated; off by default because the UI is same-origin) |
| Restart policy | `unless-stopped` |
## Hardening
- Publish only what is needed: in production drop the `5001:5001` and `8000:8000` mappings (Nginx already reaches them on `ovp-net`).
- Terminate TLS in front of `app-ui` (reverse proxy or mount a cert into the UI container); see [Nginx configuration](Nginx_Configuration.md).
- `ovp-profiler` is privileged (`NET_ADMIN`, TUN): restrict access to its port to the UI network.
- Back up the `db_data` and `ovp_pki` volumes.
- Terminate TLS in front of `app-ui` (reverse proxy or a certificate mounted into the UI container); see [Nginx configuration](Nginx_Configuration.md). The container serves plain HTTP on 80.
- `ovp-profiler` is privileged (`NET_ADMIN`, TUN): keep its API off the host network.
- Back up the `db_data` and `ovp_pki` volumes; never commit `.env`.
## Operations
+1
View File
@@ -27,6 +27,7 @@ OVPMON_OPENVPN_MONITOR_DB_PATH=/var/lib/ovpmon/openvpn_monitor.db
OVPMON_OPENVPN_MONITOR_LOG_PATH=/var/log/openvpn/openvpn-status.log
OVPMON_PROFILER_DB_PATH=/var/lib/ovpmon/ovpn_profiler.db
OVPMON_LOGGING_LEVEL=INFO
OVPMON_CORS_ORIGINS=https://<HOST>:8088
```
Create `/var/lib/ovpmon`, `/var/log/ovpmon`, `/var/log/openvpn`. For the first start also set `OVPMON_INITIAL_ADMIN_USER` / `OVPMON_INITIAL_ADMIN_PASSWORD`, then remove them.