Make the k3s API tunnel-only (ADR-005), stop declaring Flannel VXLAN
open to Anywhere, tag the base role so firewall can be scoped, and
schedule the Goss declared-vs-live check. CoulombCore sets ufw_manage
false so a converge cannot enable UFW there. T02 still needs operator
approval for make converge-firewall HOST=Railiance01.
The live host restricted 6443/tcp to specific operator addresses, added by hand,
while this role still declared the port open to Anywhere with no source
restriction. The declared config was weaker than reality: running the base role
would have REMOVED the restriction and exposed the Kubernetes API to the
internet. Security was tightened on the host and never fed back into the source
of truth.
Found 2026-08-11 while diagnosing lost cluster access, which turned out to be an
ISP lease rotation (89.244.90.246 -> .236) against a hand-maintained allowlist.
Changes:
- defaults: k3s_api_allowed_sources (empty = 6443 closed to all external
sources, the safe failure; SSH unaffected so the host stays recoverable) and
k3s_api_revoked_sources, so rotated addresses are pruned rather than left as
standing grants to whoever the ISP reassigns them to
- tasks: grant approved sources, then remove any blanket rule, then revoke
retired ones. Order matters - grants are added before the blanket rule is
deleted so convergence never opens a window with no API access
- group_vars/all.yaml: the current operator address, plus the two stale grants
(.246 rotated, 85.132.220.102 historic) marked for revocation
- docs/verification.md: state that 6443 is source-restricted rather than
listing it as a plainly allowed port
Not yet converged against the live host - the role change is committed but
running it is a production action needing operator approval.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Mark T01 and T10 done after paginated forge comparison shows 0 Gitea-only
repos and all State Hub remotes on Forgejo. Advance T11 to progress with
per-repo cutover complete; Gitea read-only marking awaits operator signoff.
Refresh forgejo-migration-inventory.md with 2026-07-08 closure addendum.
Document backup cron PATH fix and 3/7 gate status after manual run.
Decrypt production forgejo-dump artifact, restore 14 repos in isolated
namespace, and harden restore script for large chunked copy and drill mailer stub.
Sync the workplan file with State Hub (fix-consistency backing link), record
2026-07-06 state-hub tier-3 cutover evidence, refresh the Forgejo org
inventory snapshot, and close T08 now that Actions criteria are met.
Add isolated-namespace restore drill (CNPG cluster, PVC, orchestration script)
and document successful 2026-07-04 run: production forgejo dump restored with
health 200 and pilot repos visible via API. Scheduled backups remain open.
Reflects live railiance01 deploy, cancels isolated probe T03 in favor of
in-production pilots, marks T08/T10 progress (forgejo-actions-probe,
glas-harness), and documents tier 0-3 migration sequencing before state-hub.
- base role: allow UFW routing direction (required for k3s flannel
pod networking to function across nodes)
- docs/deploy-stack.md: full S1→S5 ordered deploy runbook with
pre-conditions checklist and layer-by-layer steps
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- docs/verification.md: explains spec/server-baseline.yaml, goss/baseline.yaml,
make verify workflow, assertion mapping table, and how to add new checks
- docs/convergence.md: replace manual spot-check snippet with make verify reference
- workplans/RAIL-HO-WP-0002: mark completed (all tasks done, workstream closed)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>