Files
vacuum-wall/TODO.md
T
mteehan 7beba44b4b feat: pre-computed state store and async ACME issuance (fixes timeout mismatch)
- Add lib/state.py: in-memory state store with subsystem collectors
  (firewall, dnsmasq, nginx, acme, wireguard)
- Refactor all handlers: read from state on GET, call refresh_state()
  after mutations instead of invoking subprocesses per request
- daemon/server.py: add refresh_state(), /status/all, /status/refresh;
  populate state at startup
- webui/api/certs.py: async step-by-step ACME issuance (validate,
  issue with request_id, poll status) replacing blocking endpoint
- webui/server.py: render pages from state instead of direct lib calls
- Update templates, JS for async cert issuance with polling UI
- Update tests for state-based mocking; add test_state.py
- Fix SIM105 lint issue (contextlib.suppress)
- Add TODO.md with certificate issuance issue tracking

Resolves: WebUI 30s timeout freeze during cert issuance (Problem 1)
2026-05-30 05:45:40 +00:00

2.1 KiB

TODO — Certificate Issuance Issues

Problem 1: Timeout Mismatch Causes WebUI Freeze → FIXED

Date Found: May 30, 2026 Date Fixed: May 30, 2026

Symptom: Clicking "Issue Certificate" in the WebUI freezes for ~30 seconds, then returns a 500 error with "Daemon request timed out". Meanwhile the daemon silently runs acme.sh in the background for up to 120s before timing out itself.

Root Cause:

  • daemon/client.py — WebUI client uses timeout=30 for all daemon requests
  • daemon/handlers/acme.py — Daemon allows acme.sh subprocess timeout=120
  • The WebUI gives up at 30s while the daemon is still legitimately processing

Fix Applied: Replaced blocking issue endpoint with async step-by-step issuance:

  • POST /acme/validate — Pre-flight checks (instant): acme.sh installed, email configured, webroot ready, DNS resolves, challenge configured
  • POST /acme/issue — Returns immediately with request_id, spawns background task
  • GET /acme/issue/status — Client polls for step-by-step progress
  • UI shows pre-check results, then step progress with polling (no timeout issues)
  • Blocking DNS check prevents wasted acme.sh calls when domain doesn't resolve

Files Changed: daemon/handlers/acme.py, webui/api/certs.py, webui/templates/certs.html, webui/static/app.js


Problem 2: ZeroSSL Rate Limits Block Certificate Issuance

Date Found: May 30, 2026

Symptom: acme.sh fails to issue a certificate for 218broad.vacuum.network with:

The retryafter=86400 value is too large (> 600), will not retry anymore.

Root Cause: ZeroSSL CA returns a retry-after of 86400 seconds (24 hours), likely from a prior failed challenge. acme.sh has a hard cap of 600s on retry-after values and refuses to proceed when the CA requests a longer wait.

Files: N/A (acme.sh behavior, not a project code issue)

Workarounds:

  • Switch CA to Let's Encrypt: acme.sh --set-default-ca --server letsencrypt
  • Wait 24 hours and retry
  • Investigate and clean up prior failed challenges for the domain on ZeroSSL's side

Status