railiance-infra/ansible/roles/base/defaults/main.yml

67 lines
2.7 KiB
YAML
Raw Normal View History

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>
2026-08-11 23:56:28 +02:00
---
# Base role defaults.
# When false, this role will not enable or rewrite UFW. Use that for hosts
# whose live packet filter is not UFW (CoulombCore: iptables INPUT DROP with
# a Plesk-era accept list). Enabling UFW there is an availability decision,
# not a side effect of an unrelated converge.
ufw_manage: true
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>
2026-08-11 23:56:28 +02:00
# Source addresses permitted to reach the k3s API (6443/tcp).
#
# WHY THIS EXISTS
# ---------------
# The k3s API was originally opened to Anywhere by this role, and the source
# restriction was later added by hand on the live host. That left the declared
# config WEAKER than reality: re-running this role would have removed the
# restriction and exposed the Kubernetes API to the internet. Found 2026-08-11.
#
# Operator addresses rotate (dynamic ISP leases). An allowlist is a treadmill:
# each rotation is either an outage or a stale grant to whoever the ISP
# reassigns the address to. RAIL-HO-WP-0009-T04 therefore keeps this list
# empty. Reach the API over the ops-bridge SSH tunnel
# (`k3s-api-railiance01`, local port 16444; `k3s-api-coulombcore`, 16443).
# See docs/adr/ADR-005-k3s-api-tunnel-only.md.
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>
2026-08-11 23:56:28 +02:00
#
# Deliberately empty by default. A host that sets no sources gets NO public
# access to 6443 — which is the safe failure. SSH (22) is unaffected, so a host
# converged with an empty list is always recoverable.
#
# Each entry, if any:
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>
2026-08-11 23:56:28 +02:00
# - address: "203.0.113.10"
# comment: "k3s-api-operator-workstation"
k3s_api_allowed_sources: []
# Source addresses whose k3s API access must be REMOVED on convergence.
# Move an address here when it stops being yours (or when the public
# allowlist is retired); convergence then prunes it.
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>
2026-08-11 23:56:28 +02:00
k3s_api_revoked_sources: []
# Source addresses permitted to send Flannel VXLAN (8472/udp).
#
# Empty by default. A single-node cluster does not need a public VXLAN
# grant; adding an unrestricted 8472/udp allow would expose the pod network
# to injection. Set this to the other nodes' addresses only when the cluster
# becomes multi-node (RAIL-BS-WP-0007 / ThreePhoenix HA).
#
# Each entry:
# - address: "203.0.113.20"
# comment: "flannel-vxlan-peer"
flannel_vxlan_allowed_sources: []
# Extra UFW allows that are not k3s. Used for provider agents that must stay
# reachable (HostEurope Nydus on 2224/tcp). Empty by default so a Hetzner
# host does not inherit a HostEurope-only hole.
#
# Each entry:
# - port: "2224"
# proto: tcp
# comment: "nydus-ex-api dashboard agent"
ufw_extra_allowed: []
# Ports 80/443 are separate from generic exceptions. They stay empty for a new
# reef unless the controller supplies reef_declaration_path and that source
# declaration carries exact ADR-0008 substrate grants.
public_web_ports: []
reef_declaration_path: ""