Files
archy/.planning/phases/01-federation-mesh-hardening/01-20-SUMMARY.md
T

7.0 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions requirements-completed coverage duration completed status
01-federation-mesh-hardening 20 infra
tor
doctor
shell
mesh
permissions
phase provides
01-federation-mesh-hardening scripts/container-doctor.sh's fix_* convention and the archipelago-doctor.timer (OnUnitActiveSec=5min) that drives it
A permission predicate that tests the property that matters (group/other denied) instead of exact-matching one octal string
A 30-minute Tor restart backoff, so a restart storm is structurally impossible even if some future condition makes the fix fire repeatedly
tor
mesh
doctor
added patterns
Assert the property, not the representation: `2700` and `700` both deny group and other, which is the security property. Exact-matching the string `700` turned Tor's own setgid bit into a permanent false positive.
Pair a predicate fix with a rate limit: the predicate stops today's loop, the backoff stops the whole class of loop. One is a fix, both is a guarantee.
created modified
scripts/container-doctor.sh
Compare the low three digits of `stat -c '%a'` rather than the whole string, so both `700` and `2700` read as correct while `750`, `707` and `2755` are still corrected.
The 'already correct' path logs at debug level only. The original defect was invisible precisely because 'Fixed permissions on … (2700 -> 700)' looked like the doctor working — a healthy node should stay quiet.
Backoff state lives in `/var/lib/archipelago/doctor-tor-last-restart` with a 1800s window, and non-numeric/missing content reads as 0 so a corrupt state file fails open into 'restart allowed' rather than wedging the fix permanently.
FED-09
id description requirement verification human_judgment
D1 The doctor no longer restarts Tor on every run — Tor uptime grows past the doctor's 5-minute interval FED-09
kind ref status
manual_procedural archi-dev-box 2026-08-02: tor@default active since 2026-08-01 15:25:45 — 15+ hours continuous, spanning ~180 doctor intervals pass
false
id description requirement verification human_judgment
D2 A hidden-service directory at Tor's own 2700 is recognised as correct — no chmod, no restart FED-09
kind ref status
other Predicate exercised directly on tmpdirs: 2700 -> low3=700 -> ACCEPTED; 700 -> ACCEPTED pass
kind ref status
manual_procedural archi-dev-box: zero 'Fixed permissions … hidden_service' lines across 542 doctor log entries in 6 hours pass
false
id description requirement verification human_judgment
D3 A genuinely insecure directory (group/other readable) is still corrected FED-09
kind ref status
other Predicate exercised on 750, 707 and 2755 — all three fall through to the corrective chmod pass
false
id description requirement verification human_judgment
D4 Even on a real fix, Tor cannot be restarted more than once per backoff window FED-09
kind ref status
other TOR_RESTART_BACKOFF_SECONDS=1800 gates the restart against TOR_RESTART_STATE_FILE; non-numeric state reads as 0 pass
false
id description requirement verification human_judgment
D5 Tor retains its consensus/HSDir cache long enough to resolve .onion addresses FED-09
kind ref status
manual_procedural Post-OTA checkpoint on an affected node — NOT RUN (see below). 15h of unbroken Tor uptime on archi-dev-box is the necessary precondition and is met. deferred
true
30min 2026-08-02 complete-pending-post-ota-checkpoint

Phase 1 Plan 20: Stop the Doctor Fighting Tor Over the Setgid Bit (FED-09) Summary

The container doctor treated Tor's own 2700 hidden-service directory as a permission defect, "fixed" it, and restarted Tor — every five minutes, forever. Tor never lived long enough to build a usable HSDir cache, so onion lookups failed and the mesh's Tor fallback died with it.

Performance

  • Duration: ~30 min (code committed 2026-07-31 as 4435f95e; verification and this SUMMARY 2026-08-02)
  • Tasks: 1/2 (Task 2 is a post-OTA checkpoint — see below)
  • Files modified: 1

Accomplishments

  • The predicate now compares the low three digits of stat -c '%a', so Tor's setgid 2700 and a plain 700 both read as correct, while 750, 707 and 2755 are still corrected. Verified directly against all five modes.
  • A 30-minute restart backoff (/var/lib/archipelago/doctor-tor-last-restart) makes a restart storm impossible even if some future condition makes the fix fire repeatedly. The predicate fixes today's bug; the backoff retires the class.
  • The "already correct" branch logs at debug level so a healthy node stays quiet — the original defect hid inside a log line that read like success.

Evidence on a real node (archi-dev-box, 2026-08-02)

  • tor@default active since 2026-08-01 15:25:45 — over 15 hours continuous, spanning roughly 180 doctor intervals. Before the fix, observed restarts were 13:07:56 → 13:13:14 → 13:18:39 → 13:23:57, each within a second of a timer firing.
  • Zero Fixed permissions … hidden_service lines across 542 doctor log entries in the preceding 6 hours.

Deviations from Plan

None. The implementation matches the plan's action exactly: predicate corrected at the property level, backoff added, logging made quiet-when-healthy.

Process note: the code landed on 2026-07-31 as 4435f95e but no SUMMARY was written and the roadmap entry was never ticked, so the plan looked unstarted for two days. That is the bookkeeping gap this file closes.

Known Stubs

None.

Threat Flags

  • The plan's prohibition — never loosen hidden-service permissions — holds: group and other access is still denied on every path. 2700 is accepted precisely because it denies them; the setgid bit is orthogonal to that property.
  • Scope boundary respected: the FIPS direct-transport connect_fail (problem 1 in the diagnosis) was deliberately NOT touched here. It belongs with FED-03's structured review of the transport/dial layer.

Outstanding: post-OTA checkpoint (Task 2)

Task 2 verifies on an affected node after the release lands, and explicitly forbids deploying directly to a user's device (archy-x250-mad2 or any node that is not ours) — verification is post-OTA only. Remaining there:

  1. Tor uptime keeps growing across three doctor intervals (met on archi-dev-box; needs repeating on an affected node)
  2. No recurring "Fixed permissions" lines (met on archi-dev-box)
  3. Onion resolution works — a mesh send to a Tor-only peer succeeds and No more HSDir available to query is gone
  4. The doctor still corrects a deliberately chmod 750'd hidden-service directory

Items 3 and 4 are the ones genuinely outstanding; 1 and 2 already have real-node evidence.