fix: replace ip6tables with disable_ipv6 sysctl in vlan50 egress guard
Some checks failed
validate / lint (push) Failing after 1s
Some checks failed
validate / lint (push) Failing after 1s
nicolaka/netshoot:v0.11 (the pinned tag actually in use) is built on Alpine 3.18.0, where ip6tables is packaged separately from iptables; this image's Dockerfile only installs the latter, so ip6tables does not exist in the container at all (confirmed live: "ip6tables: not found", and against Alpine's own v3.18 package index, not master's). Write 1 to /proc/sys/net/ipv6/conf/all/disable_ipv6 instead - per the kernel's own ip-sysctl docs this is equivalent to also setting conf/default/disable_ipv6 and every existing per-interface disable_ipv6 (lo/eth0/net1) at once, and is strictly stronger than an iptables DROP policy would have been: no IPv6 activity happens on any interface at all, not just filtered output. Needs no capability beyond the NET_ADMIN the guard init container already has. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
26894d16ce
commit
7ce0dee711
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user