diff --git a/manifests/multus/vlan50-egress-guard-script.yaml b/manifests/multus/vlan50-egress-guard-script.yaml index fb06a9e..8b192b1 100644 --- a/manifests/multus/vlan50-egress-guard-script.yaml +++ b/manifests/multus/vlan50-egress-guard-script.yaml @@ -190,9 +190,38 @@ data: iptables -A VLAN50-GUARD -o eth0 -j DROP echo "[vlan50-egress-guard] blocking IPv6 entirely (both interfaces) — IPv4-only design" - ip6tables -P OUTPUT DROP - ip6tables -P FORWARD DROP - ip6tables -A OUTPUT -o lo -j ACCEPT + # sysctl, not an ip6tables DROP policy: nicolaka/netshoot:v0.11 (the + # pinned tag actually in use) is built on Alpine 3.18.0 per its real, + # tag-pinned Dockerfile — confirmed live, 2026-08-24, "ip6tables: not + # found". Alpine 3.18 packages ip6tables SEPARATELY from iptables + # (confirmed against Alpine's own v3.18 package index), and this + # image's Dockerfile only installs the latter, so ip6tables genuinely + # does not exist in this container at all — not a PATH issue (the + # iptables calls just above this ran fine from the same image). + # Disabling IPv6 at the netns level is also strictly stronger than a + # DROP policy would have been anyway: no IPv6 address, neighbor + # discovery, or routing activity happens on any interface here at + # all, not just filtered OUTPUT/FORWARD traffic. A single write to + # conf/all/disable_ipv6 is sufficient by itself — the kernel's own + # ip-sysctl documentation defines it as equivalent to writing + # conf/default/disable_ipv6 (for any interface created afterward) + # *and* every existing per-interface disable_ipv6 (lo/eth0/net1) all + # at once, not merely an aggregate read. Namespaced net.ipv6.* + # sysctls are writable directly by a process with CAP_NET_ADMIN in + # its own netns — no pod-spec sysctls: field is needed for this. + DISABLE_IPV6=/proc/sys/net/ipv6/conf/all/disable_ipv6 + if [ ! -w "${DISABLE_IPV6}" ]; then + echo "[vlan50-egress-guard] FATAL: ${DISABLE_IPV6} is not writable — refusing to continue without confirmed IPv6 disablement" >&2 + print_diagnostics + exit 1 + fi + echo 1 > "${DISABLE_IPV6}" + if [ "$(cat "${DISABLE_IPV6}")" != "1" ]; then + echo "[vlan50-egress-guard] FATAL: wrote 1 to ${DISABLE_IPV6} but it did not stick — refusing to continue without confirmed IPv6 disablement" >&2 + print_diagnostics + exit 1 + fi + echo "[vlan50-egress-guard] IPv6 disabled (conf/all/disable_ipv6=1)" echo "[vlan50-egress-guard] final state:" ip route show