Files
OpenVPN-Monitoring-Simple/DOCS/General/Deployment_Native.md
T

83 lines
4.2 KiB
Markdown
Raw Normal View History

# Deployment: system services (no containers)
Tested on **Alpine 3.23 (OpenRC)**; Debian/Ubuntu (systemd) differs only in service manager. Unit/init templates: [`systemd/`](systemd), [`openrc/`](openrc/INSTALL.md). Generic notes: [Deployment](Deployment.md), [Service management](Service_Management.md), [Nginx](Nginx_Configuration.md).
## 1. Packages
- Alpine: `apk add python3 py3-pip nginx nodejs npm openvpn easy-rsa iptables bash`
- Debian/Ubuntu: `apt install python3-venv nginx nodejs npm openvpn easy-rsa iptables`
## 2. Backend
```bash
cd APP_CORE && python3 -m venv venv && venv/bin/pip install -r requirements.txt gunicorn
cd APP_PROFILER && python3 -m venv venv && venv/bin/pip install -r requirements.txt
mkdir -p APP_PROFILER/easy-rsa && cp -r /usr/share/easy-rsa/* APP_PROFILER/easy-rsa/ # Docker entrypoint does this automatically
```
## 3. Environment file
`/etc/ovpmon/env` (chmod 600), loaded by the services:
```
OVPMON_API_SECRET_KEY=<openssl rand -hex 32>
OVPMON_API_HOST=127.0.0.1
OVPMON_API_PORT=5001
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.
## 4. Services
| Service | Command | Listens |
|---|---|---|
| `ovpmon-api` | `APP_CORE/venv/bin/gunicorn -w 2 -b 127.0.0.1:5001 openvpn_api_v3:app` (cwd `APP_CORE`) | 127.0.0.1:5001 |
| `ovpmon-gatherer` | `APP_CORE/venv/bin/python openvpn_gatherer_v3.py` (cwd `APP_CORE`) | - |
| `ovpmon-profiler` | `APP_PROFILER/venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000` (cwd `APP_PROFILER`) | 127.0.0.1:8000 |
OpenRC (Alpine): `supervisor=supervise-daemon`, `respawn_delay=3`, source `/etc/ovpmon/env` in `start_pre`, then `rc-update add <svc> default && rc-service <svc> start`. systemd: use the units from `systemd/` with `EnvironmentFile=/etc/ovpmon/env`.
The Profiler restarts OpenVPN through `rc-service openvpn` (Alpine) or `systemctl openvpn`; on Alpine link the config: `ln -s server.conf /etc/openvpn/openvpn.conf` and enable the `openvpn` service.
## 5. UI and Nginx (HTTPS on 8088)
```bash
cd APP_UI && npm install && npm run build
mkdir -p /var/www/ovpmon && cp -r dist/. /var/www/ovpmon/
```
Certificate (self-signed, replace with a real one when a domain is available):
```bash
mkdir -p /etc/ovpmon/tls && cd /etc/ovpmon/tls
openssl req -x509 -nodes -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -days 825 \
-subj "/CN=ovpmon" -addext "subjectAltName=IP:<HOST-IP>,DNS:ovpmon" -keyout ovpmon.key -out ovpmon.crt
chmod 600 ovpmon.key
```
Nginx server (`/etc/nginx/http.d/ovpmon.conf` on Alpine): `listen 8088 ssl`, TLS 1.2/1.3, `error_page 497 =301 https://$host:8088$request_uri`, security headers, `limit_req` (5 r/min) on `/api/auth/login`, `/` → static UI, `/api/` → `127.0.0.1:5001`, `/profiles-api/` → `127.0.0.1:8000/api/`. Full listing: [Nginx configuration](Nginx_Configuration.md). Do not declare a second `ssl_session_cache shared:SSL` zone with a different size than the main `nginx.conf`.
## 6. First run
1. `https://<host>:8088/` → sign in with the seeded admin → **Account**: change username/password, enable 2FA.
2. **PKI Configuration → Initialize PKI** → generate server config → start OpenVPN → create profiles.
## 7. Host hardening (recommended)
- SSH: key-only (`PasswordAuthentication no`, `KbdInteractiveAuthentication no`, `PermitRootLogin prohibit-password`); note that cloud-init drop-ins in `/etc/ssh/sshd_config.d/` can override the main file, so put settings in `00-*.conf`.
- fail2ban: jails `sshd` and one for `POST /api/auth/login` (401/429/503) on the Nginx access log.
- Backends bound to `127.0.0.1`; only 8088 (UI/API) and the VPN port are public.
## 8. Verify
```bash
rc-status | grep -E "ovpmon|nginx|openvpn" # or: systemctl status ovpmon-*
ss -tlnp | grep -E ":(8088|5001|8000) "
curl -sk -o /dev/null -w "%{http_code}\n" https://127.0.0.1:8088/ # 200
curl -sk -o /dev/null -w "%{http_code}\n" https://127.0.0.1:8088/profiles-api/config # 401 without token
```