Skip to content

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 04 Nov 20:38
· 38 commits to main since this release

Participant installs are now safe to run on a home machine: the installer checks that the internet reaches the sensors, offers a host firewall, and every internal network is isolated from the host.

Updating an existing install: Docker cannot change an existing network, so the first update recreates the stack once (down, never -v; data volumes are kept). Docker Engine 28 or newer is needed for the network isolation. See Updates.

Added

  • ./scripts/participant.sh ports-check [--wait SECONDS] [--since ISO | --since-install] tells whether the internet reaches your sensors, and the participant installer runs it at the end and offers to re-check after you open the ports on your router. It makes no outside connection: it counts sessions from public addresses that your sensors already recorded, prints no address, reads the database in a read-only transaction, and exits 0 (reached) or 3 (nothing yet). status.sh points to it.

Changed

  • The participant installer no longer prints a fixed "14 days" date. The hub decides the probation period; ./scripts/status.sh shows the date from which the sensor counts.
  • Participant docs and installer summary: use port forwards rather than a DMZ, explain the DMZ risk, and say precisely when the route-out restriction holds (host firewall loaded) and that the firewall does not filter internet traffic to the machine's own services.

Security

  • Host firewall for participant mode: scripts/host/firewall-participant.nft loads with no placeholder other than the admin SSH port, rendered by scripts/host/render-firewall.sh and installed with scripts/host/install-firewall.sh (systemd unit, survives a reboot, --uninstall to undo). In its own nft table, it drops everything new, invalid or untracked from the sensors' uplink to the host and to the internet or the LAN, and limits hubproxy's uplink to TCP 443 on public addresses plus UDP DNS to the resolvers Docker uses. The full-mode template's DNS rule is narrowed the same way. The renderer refuses a host bridge that is not Docker's but matches the rule names, to avoid a lockout.
  • Every internal network has an isolated gateway (gateway_mode_ipv4: isolated), a fixed bridge name and IPv6 off, so a compromised container no longer reaches services on the host through its bridge. This needs Docker Engine 28 or newer, and the first update recreates the stack once (see docs/updates.md).
  • A guardrail checks the hardening of every service of every supported stack: read-only root, all capabilities dropped, no-new-privileges, a non-root uid:gid, memory, CPU and process limits, a healthcheck, noexec,nosuid,nodev tmpfs, no host namespaces, devices, Docker socket or unlisted bind mounts, isolated internal networks, and third-party images pinned by digest.
  • The TimescaleDB image is pinned by digest.
  • The installers offer to install the host firewall at the end (participant mode; asks before using sudo, never blocks, prints the two commands otherwise; participant.sh vpn reminds you to re-run it), and ./scripts/participant.sh firewall [install|uninstall|status] does it later.
  • Updates and rollbacks recreate the stack once (down --remove-orphans, never -v) when compose says an existing network cannot be reused (matched on its wording, not on any mention of a network); a foreign container attached to one of our networks stops the run with instructions instead of being disconnected.
  • CI pins the TimescaleDB test image by digest, like docker-compose.yml.
  • Automatic updates: the minimum release age is now at least 48 h whatever the release's own manifest says; AUTO_UPDATE_MIN_AGE_H in .env can raise it.
  • Automatic updates: a release that is unsigned, does not match its tag or has a signature cosign rejects is marked bad with its reason (network, Docker, Sigstore or disk problems are never held against a release) and the next newest release of the same major version is tried (3 at most per run), so one bad tag no longer blocks updates.
  • The installer warns when Docker Engine is older than 28, where internal networks are not isolated from the host.

Verify: scripts/verify-release.sh v0.9.0 and just verify-images v0.9.0.

Full Changelog: v0.8.0...v0.9.0