docs(security): correct the M3 pod-to-node control #403

This commit is contained in:
ryan4yin | 二花 authored and GitHub committed 2026-10-07 17:58:54 +08:00
1 parent df6f9b8d6d
commit b64adc4c20
1 file changed
+11 -5
+11 -5
View File
@@ -202,11 +202,17 @@ checks remain necessary after deployment.
migration and a maintenance window. See WORKAROUNDS.md.
- **Remote consoles:** the libvirt VNC consoles listen on `127.0.0.1` only, and the shared firewall
drops 5900-5910 on every host. Reach a console through an SSH tunnel.
- **Pod-to-host firewall:** pod CIDR sources (`10.0.0.0/8`, `fd00::/104`) are accepted on the k3s
nodes, but the credential-bearing host ports are denied first (SSH, NFS, Postgres, restic, VNC,
Immich, and the exporter/monitoring ports). The broad accept stays so Cilium and in-cluster
service traffic keep working; a full port allowlist is future work. Ports 80/443 are deliberately
not denied, so in-cluster calls through the ingress are not broken.
- **Pod-to-host firewall:** two independent layers deny pod access to the credential-bearing host
ports (SSH, NFS, Postgres, restic, VNC, Immich, exporter/monitoring). The
`deny-pod-to-node-admin-ports` `CiliumClusterwideNetworkPolicy` in
[k8s-gitops#52](https://github.com/ryan4yin/k8s-gitops/pull/52) denies pod egress to
`host`/`remote-node` on those ports at the pod's own node; the k3s nodes' nftables rule drops the
same ports for pod CIDR sources (`10.0.0.0/8`, `fd00::/104`). The nftables rule only matches when
the pod IP survives to the destination, which requires Cilium's eBPF datapath: kube-proxy's
iptables masquerade rewrote pod -> node traffic to the source node IP and defeated it. That is why
k3s runs `--disable-kube-proxy` ([#404](https://github.com/ryan4yin/nix-config/pull/404)) and
Cilium runs `kubeProxyReplacement` with `bpf.masquerade`. Verified live on all nodes: pod ->
node:22 is dropped while kubelet, ingress (80/443 stay open), ClusterIP and DNS keep working.
Only selected pod security fields, RBAC rules/binding metadata, listeners and export metadata were
queried. Secret contents and raw kubeconfigs were not inspected. No live access policy, workload,