refactor: unify project structure, improve security, and enhance deployment
- Fix WireGuard private key leak in API responses and config updates - Update systemd service to serve from repo root with adjusted sandbox - Add CLI flags, idempotency, and dev mode to install.sh - Extract common utilities to lib/common.py and webui/api/common.py - Migrate frontend to htmx for simpler, more maintainable UI - Update docs to reflect current architecture and deployment model - Vendor htmx dependencies per project requirements
This commit is contained in:
@@ -37,18 +37,18 @@ Flask WebUI ──→ lib/firewall.py ──→ sudo firewall-cmd ──→ fire
|
||||
Flask WebUI ──→ lib/nginx.py ──→ write local .conf files ──→ sudo cp to /etc/nginx/ ──→ sudo nginx -t && sudo nginx -s reload
|
||||
Flask WebUI ──→ lib/dnsmasq.py ──→ render config ──→ sudo tee /etc/dnsmasq.d/vacuum-wall.conf ──→ sudo systemctl reload dnsmasq
|
||||
Flask WebUI ──→ lib/acme.py ──→ acme.sh (no sudo, runs as service user) ──→ ZeroSSL ACME
|
||||
Flask WebUI ──→ lib/wireguard.py ──→ render $PROJECT_DIR/data/wireguard/wg0.conf ──→ sudo cp to /etc/wireguard/ ──→ sudo wg-quick up wg0
|
||||
Flask WebUI ──→ lib/wireguard.py ──→ render data/wireguard/wg0.conf ──→ sudo cp to /etc/wireguard/ ──→ sudo wg-quick up wg0
|
||||
```
|
||||
|
||||
Each `lib/` module encapsulates command construction, privilege escalation (via sudo where needed), and error handling for its subsystem. The modules read declarative configuration from `config/` and runtime artifacts from `data/`, render the appropriate system configuration files, and invoke the corresponding privileged operation. Note that `lib/acme.py` runs `acme.sh` without sudo — it executes as the unprivileged service user using webroot validation rather than standalone/TLS-ALPN modes that would require elevated privileges.
|
||||
|
||||
The `lib/` modules auto-discover the project root at runtime via `Path(__file__).resolve().parent.parent`, so no hardcoded paths are needed in Python code.
|
||||
The `lib/` modules auto-discover the project root at runtime via `Path(__file__).resolve().parent.parent`. This works because `install.sh` performs an editable pip install (`pip install -e .`), keeping module files in the project directory rather than copying them to `site-packages/`.
|
||||
|
||||
## Install-Time Templating
|
||||
|
||||
System configuration files in `system/` are Jinja2 templates rendered by `install.sh` at install time:
|
||||
|
||||
- **`systemd/vacuum-wall.service`**, **`systemd/vacuum-wall-acme.service`** — `{{ USER_NAME }}`, `{{ PROJECT_DIR }}`, `{{ ACME_HOME }}` are substituted to produce the final systemd unit files installed to `/etc/systemd/system/`.
|
||||
- **`systemd/vacuum-wall.service`**, **`systemd/vacuum-wall-acme.service`** — `{{ USER_NAME }}`, `{{ PROJECT_DIR }}`, `{{ ACME_HOME }}` are substituted to produce the final systemd unit files installed to `/etc/systemd/system/`. The `PROJECT_DIR` template variable is set from the `INSTALL_DIR` environment variable (defaults to the repo root).
|
||||
- **`sudoers.d/vacuum-wall`** — `{{ USER_NAME }}` is substituted to produce the sudoers whitelist.
|
||||
- The timer file (`vacuum-wall-acme.timer`) contains no variable paths and is installed as-is.
|
||||
|
||||
@@ -99,7 +99,7 @@ data/
|
||||
└── wireguard/ # WireGuard runtime artifacts
|
||||
```
|
||||
|
||||
Both `config/` and `data/` reside within the project directory (`$PROJECT_DIR/`). The systemd service unit's `ReadWritePaths` directive grants the Flask process write access to both directories, while keeping the rest of the filesystem read-only. The `PROJECT_DIR` value is templated into the service unit at install time.
|
||||
Both `config/` and `data/` reside within the project directory. The systemd service unit's `ReadWritePaths` directive grants the Flask process write access to both directories, while keeping the rest of the filesystem read-only. The `INSTALL_DIR` value is templated into the service unit at install time.
|
||||
|
||||
## File System Layout
|
||||
|
||||
|
||||
Reference in New Issue
Block a user