Update documentation for config/ migration, new install model, and firewall config API

Reflect config/ vs data/ split, install-time Jinja2 templating, auto-discovered
paths, ZeroSSL/ACME support, and the new firewall save-then-apply API in all
reference docs.
This commit is contained in:
2026-05-14 03:31:59 +00:00
parent 6106c1434d
commit dcb581a359
6 changed files with 166 additions and 90 deletions
+59 -26
View File
@@ -1,4 +1,4 @@
# Vacuum Wall Deployment Guide
# Deployment Guide
This guide walks through deploying Vacuum Wall on a real appliance or server. Vacuum Wall is an SSL proxy firewall appliance that combines edge proxying, firewall management, DHCP, DNS, and WireGuard in a single device.
@@ -22,21 +22,51 @@ This guide walks through deploying Vacuum Wall on a real appliance or server. Va
Download the Vacuum Wall repository onto the target machine, then run the installer with the required environment variables:
```bash
# Option A: Public DNS
PROJECT_DIR="/opt/vacuum-wall" \
USER_NAME="vacuum-wall" \
MGMT_DOMAIN=wall.example.com \
MGMT_PASS="strongpassword" \
MGMT_USER="admin" \
ACME_EMAIL="admin@example.com" \
bash install.sh
# Option B: mDNS (LAN-only, no DNS record needed)
MGMT_DOMAIN=vacuum-wall.local \
MGMT_PASS="strongpassword" \
MGMT_USER="admin" \
ACME_EMAIL="admin@example.com" \
bash install.sh
```
### Environment Variables
| Variable | Required | Description |
|---|---|---|
| `MGMT_DOMAIN` | Yes | The public-facing domain for the management WebUI. A DNS A record must point to the appliance's IP. |
| `PROJECT_DIR` | No | Directory where the project resides. Auto-discovers from `install.sh` location if not set. |
| `USER_NAME` | No | System user that runs the WebUI service. Defaults to `vacuum-wall`. |
| `MGMT_DOMAIN` | No | The domain for the management WebUI. Defaults to `$hostname.local` (auto-detected from the system hostname), which works with mDNS on your LAN (avahi-daemon is installed and enabled automatically). Set explicitly for a custom DNS domain (e.g., `wall.example.com`). **Errors if hostname is undetectable and this var is not set.** |
| `MGMT_PASS` | Yes | The password for HTTP basic auth protecting the WebUI. Use a strong, randomly generated password. |
| `MGMT_USER` | No | The username for WebUI access. Defaults to `admin`. |
| `ACME_EMAIL` | Yes | The email address registered with Let's Encrypt for certificate issuance and expiry notifications. |
| `ACME_EMAIL` | Yes | The email address registered with the ACME provider (ZeroSSL by default) for certificate issuance and expiry notifications. |
---
## Container / Custom Deployment
You can deploy Vacuum Wall in a container or at any custom path. Set `PROJECT_DIR` to the mount or bind path, and `USER_NAME` to whatever system user exists in the container or host environment:
```bash
# Docker volume mount example
PROJECT_DIR="/app/vacuum-wall" \
USER_NAME="ww-app" \
MGMT_DOMAIN="proxy.internal" \
MGMT_PASS="strongpassword" \
ACME_EMAIL="admin@example.com" \
bash install.sh
```
The systemd service unit files and sudoers whitelist are rendered from Jinja2 templates at install time, substituting `USER_NAME` and `PROJECT_DIR`. This means no hardcoded paths remain after installation.
---
@@ -44,27 +74,30 @@ bash install.sh
The installer performs the following steps automatically:
- **Package installation**: Installs firewalld, nginx, dnsmasq, wireguard-tools, python3, Flask, pip, jq, curl, iptables, nftables, and apache2-utils.
- **acme.sh installation**: Downloads and installs the acme.sh client to the project user's home directory for Let's Encrypt certificate management.
- **Flask installation**: Ensures the Flask Python package is available via pip for the WebUI backend.
- **System user creation**: Creates a dedicated `vacuum-wall` system user (nologin shell) that owns the project data and runs the WebUI service.
- **Directory setup**: Creates data directories under `/home/wall/vacuum-wall/data/` for nginx sites, dnsmasq config, firewall rules, and WireGuard config. Sets ownership to the `vacuum-wall` user.
- **Sudoers whitelist**: Installs a restrictive sudoers file at `/etc/sudoers.d/vacuum-wall` allowing the `vacuum-wall` user to run only the specific privileged commands needed for firewall, nginx, and dnsmasq management. Validates syntax with `visudo -cf`.
- **Package installation**: Installs firewalld, nginx, dnsmasq, avahi-daemon, wireguard-tools, python3, Flask, pip, jq, curl, iptables, nftables, and apache2-utils.
- **System user creation**: Creates a dedicated system user (default: `vacuum-wall`, configurable via `USER_NAME`) with a nologin shell that owns the project data and runs the WebUI service.
- **Python venv**: Sets up a Python virtual environment and installs project dependencies.
- **acme.sh installation**: Downloads and installs the acme.sh client to the project user's home directory for ACME certificate management.
- **Directory setup**: Creates config directories under `$PROJECT_DIR/config/` for each subsystem's declarative JSON, and data directories under `$PROJECT_DIR/data/` for nginx sites, dnsmasq fragments, firewall rules, and WireGuard config. Sets ownership to the configured system user.
- **Template rendering**: Renders system template files (`systemd/*.service`, `sudoers.d/`) via Jinja2, substituting `USER_NAME`, `PROJECT_DIR`, and `ACME_HOME`. Installed systemd and sudoers files contain no hardcoded values.
- **Sudoers whitelist**: Installs a restrictive sudoers file at `/etc/sudoers.d/vacuum-wall` allowing the configured user to run only the specific privileged commands needed for firewall, nginx, and dnsmasq management. Validates syntax with `visudo -cf`.
- **IP forwarding**: Enables `net.ipv4.ip_forward=1` in sysctl.conf and applies it at runtime, required for routing traffic between zones.
- **Firewalld initialization**: Starts and enables firewalld. Opens HTTP, HTTPS, and SSH services on the public zone for management access.
- **Dnsmasq initialization**: Starts and enables dnsmasq for future DHCP/DNS serving on internal interfaces.
- **mDNS broadcast**: Enables and starts avahi-daemon so the appliance advertises its hostname (`<hostname>.local`) on the local network.
- **Self-signed certificate**: Generates a temporary self-signed X.509 certificate for the management domain with the correct CN and SAN, placed where acme.sh would store a real cert.
- **Management proxy configuration**: Configures nginx as a reverse proxy that forward-proxies to the WebUI at `127.0.0.1:9090`, with HTTP-to-HTTPS redirect, basic auth, and WebSocket upgrade support.
- **Credentials**: Generates an htpasswd file using `apache2-utils` (with a Python fallback) for the management proxy's basic auth. Copies it to both `$USER_HOME/vacuum-wall/.htpasswd` (used by install.sh's initial nginx config) and `data/nginx/.htpasswd` (used by the running app).
- **Systemd units**: Installs three units:
- **Credentials**: Generates an htpasswd file using `apache2-utils` (with a Python fallback) for the management proxy's basic auth. Copies it to both `$USER_HOME/.htpasswd` (used by install.sh's initial nginx config) and `$PROJECT_DIR/data/nginx/.htpasswd` (used by the running app).
- **Initial nginx config**: Writes `$PROJECT_DIR/config/nginx/config.json` with the management domain and auth settings pre-configured, so the WebUI can render management proxy config out of the box.
- **Systemd units**: Installs three units (rendered from Jinja2 templates):
- `vacuum-wall.service` — the Flask WebUI backend.
- `vacuum-wall-acme.service` — the certificate renewal oneshot.
- `vacuum-wall-acme.timer` — periodic timer that triggers cert renewals.
- **Firewalld zones**: Creates initial zones:
- `internal` — trusted LAN zone with DHCP, DNS, and NTP services allowed.
- `vpn` — WireGuard tunnel zone.
- **Service startup**: Enables and starts nginx, the vacuum-wall WebUI, and the ACME renewal timer.
- **ACME registration**: Registers the Let's Encrypt account with the provided email via acme.sh.
- **Service startup**: Enables and starts nginx, the WebUI service, and the ACME renewal timer.
- **ACME registration**: Registers the ACME account with the provided email via acme.sh.
---
@@ -92,7 +125,7 @@ Log in with the username and password you provided during installation.
### Certificate Note
The initial certificate is **self-signed** and generated during installation. Your browser will show a security warning. This is expected. Once DNS is pointing to the appliance and port 80 is accessible from the internet, use the **Certs** tab in the WebUI to issue a real Let's Encrypt certificate for the management domain. After issuance, go to the **Proxy** tab and click **Apply** to reload nginx with the new cert.
The initial certificate is **self-signed** and generated during installation. Your browser will show a security warning. This is expected. Once DNS is pointing to the appliance and port 80 is accessible from the internet, use the **Certs** tab in the WebUI to issue a real ACME certificate for the management domain. After issuance, go to the **Proxy** tab and click **Apply** to reload nginx with the new cert.
---
@@ -207,7 +240,7 @@ journalctl -u nginx --no-pager -n 50
nginx -t
```
Common causes include port conflicts (another service on port 80/443), missing dependencies, or file permission issues on `/home/wall/vacuum-wall/data/`.
Common causes include port conflicts (another service on port 80/443), missing dependencies, or file permission issues on `$PROJECT_DIR/data/`.
### Firewall Rules Not Applying
@@ -226,14 +259,14 @@ visudo -cf /etc/sudoers.d/vacuum-wall
### Certificate Issuance Fails
Let's Encrypt ACME validation requires:
ACME validation via the ACME provider requires:
- The domain's DNS A record points to the appliance's public IP.
- Port 80 (HTTP-01 challenge) is accessible from the internet on the external interface.
- The ACME email was registered correctly. Check with:
```bash
su -s /bin/bash vacuum-wall -c "~/.acme.sh/acme.sh --list"
su -s /bin/bash "$USER_NAME" -c "~/.acme.sh/acme.sh --list"
```
If port 80 is blocked or the DNS record hasn't propagated yet, wait and retry. The ACME timer will also attempt renewal automatically.
@@ -244,16 +277,16 @@ Verify that:
- The LAN interface is assigned to a firewalld zone (check the **Interfaces** tab or `firewall-cmd --get-active-zones`).
- Dnsmasq is running: `systemctl status dnsmasq`.
- A DHCP range is configured for the correct interface. Check dnsmasq config at `/home/wall/vacuum-wall/data/dnsmasq/`.
- A DHCP range is configured for the correct interface. Check dnsmasq config at `$PROJECT_DIR/data/dnsmasq/`.
- The firewall allows DHCP traffic on the internal zone: `firewall-cmd --zone=internal --list-services` should include `dhcp` and `dns`.
### WebUI Not Accessible
1. Verify nginx is running: `systemctl status nginx`.
2. Test nginx configuration: `nginx -t`.
2. Check the management proxy configuration at `/etc/nginx/conf.d/vacuum-wall-mgmt.conf` (initial) or via the WebUI Proxy tab (after first apply).
4. Ensure the `vacuum-wall` WebUI service is listening on port 9090: `ss -tlnp | grep 9090`.
5. If using the self-signed cert, confirm your browser trusts it or use the WebUI to issue a real Let's Encrypt certificate.
3. Check the management proxy configuration at `/etc/nginx/conf.d/vacuum-wall-mgmt.conf` (initial) or via the WebUI Proxy tab (after first apply).
4. Ensure the WebUI service is listening on port 9090: `ss -tlnp | grep 9090`.
5. If using the self-signed cert, confirm your browser trusts it or use the WebUI to issue a real ACME certificate.
---
@@ -261,10 +294,10 @@ Verify that:
| Component | Service | Config Location |
|---|---|---|
| WebUI backend | `vacuum-wall.service` | `/home/wall/vacuum-wall/webui/` |
| WebUI backend | `vacuum-wall.service` | `$PROJECT_DIR/webui/` |
| Reverse proxy | `nginx` | `/etc/nginx/conf.d/vacuum-wall-mgmt.conf` |
| Firewall | `firewalld` | Managed via WebUI and `firewall-cmd` |
| DHCP/DNS | `dnsmasq` | `/home/wall/vacuum-wall/data/dnsmasq/` |
| VPN | wireguard-tools | `/home/wall/vacuum-wall/data/wireguard/` |
| Certificates | `vacuum-wall-acme.timer` | `/home/vacuum-wall/.acme.sh/` |
| Sudoers | — | `/etc/sudoers.d/vacuum-wall` |
| DHCP/DNS | `dnsmasq` | `$PROJECT_DIR/config/dnsmasq/` |
| VPN | wireguard-tools | `$PROJECT_DIR/config/wireguard/` |
| Certificates | `vacuum-wall-acme.timer` | `~/.acme.sh/` |
| Sudoers | — | `/etc/sudoers.d/vacuum-wall` |