fix: critical bugs + security hardening

Phase 1 (critical bugs):
- Fix firewall import string-to-list bug (system_import.py)
- Add rich rules removal in firewall config apply (handlers/firewall.py)

Phase 2 (security hardening):
- Restrict sudo wildcards to specific paths (sudoers.d/vacuum-walld)
- Fix TOCTOU: use /run/vacuum-wall/ for temp files (nginx, dnsmasq, network handlers)
- Remove unnecessary sudo from wg genkey/pubkey (handlers/wireguard.py)

Phase 3 (validation):
- Validate poll intervals > 0 (daemon/server.py)
- Restrict sysctl to whitelisted parameters (handlers/network.py)

Phase 4 (defensive programming):
- Enforce shell=False in run() and run_proc() (lib/common.py)
- Track issuance tasks for graceful shutdown (handlers/acme.py)
- Add nginx template marker consistency tests (tests/test_system_import.py)
This commit is contained in:
2026-07-10 17:05:37 +00:00
parent 803258cf18
commit 05524f3756
27 changed files with 1805 additions and 521 deletions
+15 -13
View File
@@ -24,28 +24,29 @@ The file `/etc/sudoers.d/vacuum-walld` grants the daemon user (`vacuum-walld`) p
| Firewall | `firewall-cmd *` | All firewalld operations (zone management, rules, services, ports) |
| Nginx | `nginx -s reload` | Graceful nginx configuration reload |
| Nginx | `nginx -t` | Nginx configuration syntax validation |
| Nginx file ops | `cp -- * /etc/nginx/*` | Copy rendered config files to system paths |
| Nginx file ops | `cp -- * /etc/nginx/conf.d/*` | Copy rendered config files to system paths |
| Nginx file ops | `cp -- * /etc/nginx/snippets/*` | Copy rendered config files to system paths |
| Nginx file ops | `rm /etc/nginx/conf.d/vacuum-wall.conf`, `/etc/nginx/snippets/vacuum-wall-ssl.conf` | Clean up generated nginx config files |
| Nginx file ops | `chown root:root /etc/nginx/conf.d/vacuum-wall.conf`, `/etc/nginx/snippets/vacuum-wall-ssl.conf` | Ensure correct ownership of nginx config files |
| Nginx status | `systemctl is-active nginx` | Check nginx service status |
| Nginx file ops | `cp * /etc/nginx/*` | Copy rendered config files to system paths |
| Nginx file ops | `cp * /etc/nginx/conf.d/*` | Copy rendered config files to system paths |
| Nginx file ops | `cp * /etc/nginx/snippets/*` | Copy rendered config files to system paths |
| Nginx file ops | `rm /etc/nginx/conf.d/vacuum-wall.conf`, `rm /etc/nginx/snippets/vacuum-wall-ssl.conf` | Clean up generated nginx config files |
| Nginx file ops | `chown root:root /etc/nginx/conf.d/vacuum-wall.conf`, `chown root:root /etc/nginx/snippets/vacuum-wall-ssl.conf` | Ensure correct ownership of nginx config files |
| Dnsmasq | `systemctl restart dnsmasq` | Apply updated dnsmasq configuration |
| Dnsmasq | `systemctl is-active dnsmasq` | Check dnsmasq service status |
| Networkd | `systemctl is-active dnsmasq` | Check dnsmasq service status |
| Dnsmasq status | `systemctl is-active dnsmasq` | Check dnsmasq service status |
| Dnsmasq file ops | `mkdir -p /etc/dnsmasq.d` | Ensure target directory exists |
| Dnsmasq file ops | `cp -- * /etc/dnsmasq.d/*` | Copy rendered config files |
| Dnsmasq leases | `cat /var/lib/dnsmasq/dnsmasq.leases` | Read dnsmasq lease table |
| Dnsmasq file ops | `cp * /etc/dnsmasq.d/*` | Copy rendered config files |
| Dnsmasq leases | `cat /var/lib/misc/dnsmasq.leases` | Read dnsmasq lease table |
| WireGuard | `wg-quick *` | WireGuard tunnel lifecycle (up, down, save, show) |
| WireGuard | `wg *` | WireGuard status and peer management |
| WireGuard file ops | `cp -- * /etc/wireguard/*` | Copy rendered config files |
| WireGuard file ops | `cp * /etc/wireguard/*` | Copy rendered config files |
| WireGuard file ops | `chown root:root /etc/wireguard/wg0.conf` | Ensure correct ownership of WG config |
| Certificates | (none) | acme.sh runs as the non-root daemon user directly; no sudo escalation is needed (webroot validation is used) |
| Network queries | `ip -o link show` | List network interfaces |
| Network queries | `ip -o addr show` | List IP addresses on interfaces |
| Network queries | `ip -o addr show *` | Query IP address for a specific interface (DHCP gateway auto-population) |
| Networkd | `networkctl status *` | Query interface status from networkd |
| Networkd | `networkctl reload *` | Reload networkd for a specific interface |
| Networkd | `networkctl reload` | Reload networkd for all interfaces |
| Networkd file ops | `cp -- * /etc/systemd/network/*` | Copy rendered network unit files |
| Networkd | `networkctl reconfigure *` | Reconfigure a specific interface |
| Networkd file ops | `cp * /etc/systemd/network/*` | Copy rendered network unit files |
| Networkd file ops | `rm /etc/systemd/network/*.network` | Remove stale network unit files |
| Networkd file ops | `mkdir -p /etc/systemd/network` | Ensure target directory exists |
| Sysctl | `sysctl -w *` | Set kernel parameters |
@@ -101,7 +102,8 @@ Both `vacuum-wall.service` (WebUI) and `vacuum-walld.service` (daemon) apply com
| Directive | Value | Effect |
|---|---|---|
| `ProtectSystem` | `strict` | Mounts the entire file system as read-only, except explicitly allowed paths |
| `ReadWritePaths` | project dir, `/tmp`, and (WebUI only) `config/`, `data/` subdirs | The project directory and runtime paths are writable |
| `ReadWritePaths` | project dir, `/tmp`, `/run/vacuum-wall`, and (WebUI only) `config/`, `data/` subdirs | The project directory and runtime paths are writable |
| `RuntimeDirectory` | `vacuum-wall` (daemon only) | Creates `/run/vacuum-wall` owned by the daemon user; removed on stop |
| `PrivateTmp` | `yes` | Provides a private `/tmp` and `/var/tmp` namespace |
| `NoNewPrivileges` | `yes` | Prevents the process from gaining new privileges via `setuid`/`setgid` |
| `PrivateDevices` | `yes` | Hides all device files under `/dev` |