Make the k3s API firewall allowlist declarative
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>
This commit is contained in:
parent
88e71f7bd1
commit
c84fe7a3de
6 changed files with 184 additions and 2 deletions
|
|
@ -24,3 +24,29 @@ custodian_agent_pubkey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/V9fe5MGKdhTBz9Kw
|
|||
# Private key lives at ~/.ssh/id_ops on the workstation. Never commit the private key.
|
||||
ops_bridge_user: tegwick
|
||||
ops_bridge_pubkey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKQmXbAVlEa8dzGx8Hk2S7AITpz6sMWdCN0MeMOzL82u ops-bridge@custodian"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# k3s API firewall allowlist (6443/tcp)
|
||||
#
|
||||
# The k3s API is NOT world-reachable. Only these sources may connect.
|
||||
# Added 2026-08-11 after discovering the live host was source-restricted by hand
|
||||
# while this repo still declared 6443 open to Anywhere — meaning a convergence
|
||||
# run would have exposed the Kubernetes API to the internet.
|
||||
#
|
||||
# These are operator egress addresses, not secrets. They are dynamic: when your
|
||||
# ISP rotates the lease, MOVE the old entry to k3s_api_revoked_sources rather
|
||||
# than deleting the line, so convergence prunes the stale grant instead of
|
||||
# leaving it standing for whoever the address gets reassigned to.
|
||||
#
|
||||
# Durable alternative worth considering: reach the API over the ops-bridge SSH
|
||||
# tunnel instead (see railiance-infra/docs/deploy-stack.md, the
|
||||
# k3s-api-coulombcore pattern) and allow no public sources at all.
|
||||
k3s_api_allowed_sources:
|
||||
- address: "89.244.90.236"
|
||||
comment: "k3s-api-operator-current"
|
||||
|
||||
k3s_api_revoked_sources:
|
||||
- address: "89.244.90.246"
|
||||
comment: "rotated ISP lease, superseded 2026-08-11"
|
||||
- address: "85.132.220.102"
|
||||
comment: "historic operator address, retired"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue