iptables-basic: close the address family the baseline never wrote #1

Merged
claudiomaradonna merged 1 commit from ipv6-firewall-baseline into main 2026-08-28 15:18:22 +02:00

The role wrote the v4 table and nothing else, which is not a smaller
firewall but an open one. Measured on a converged host: iptables -P INPUT DROP with every rule source-restricted, ip6tables -P INPUT ACCEPT beside
it, sshd bound to [::]:22, and the save handler persisting both files — so
the open half was restored at every boot as faithfully as the closed one. A
link-local address on the same segment is enough to use it.

Disabling IPv6 was never the mitigation it appeared to be.
hardening-basic writes net.ipv6.conf.{all,default,lo}.disable_ipv6=1, but
systemd-networkd sets net.ipv6.conf..disable_ipv6=0 on every link it
configures, after /etc/sysctl.d has been applied. So the three values that
are easy to check read 1 while the only interface carrying traffic has IPv6
live. Both READMEs now say that, with the measurement rather than the claim.

The v6 rules mirror the v4 ones except for ICMPv6, where mirroring would be
wrong: Neighbour Discovery is ICMPv6, so a blanket drop stops address
resolution on the link and takes Path MTU discovery with it. RFC 4890's
must-not-drop set, minus redirects, which accept_redirects=0 already refuses.

Gated on /proc/net/if_inet6 rather than on the binary: a kernel booted with
ipv6.disable=1 has nothing for ip6tables to talk to and must not fail the
play for the lack of it. The molecule scenario makes the same distinction
and says so aloud when the container cannot exercise the baseline.

Claude-Session: https://claude.ai/code/session_01W5FkkabPcwgqKTQv4LD7DP

The role wrote the v4 table and nothing else, which is not a smaller firewall but an open one. Measured on a converged host: `iptables -P INPUT DROP` with every rule source-restricted, `ip6tables -P INPUT ACCEPT` beside it, sshd bound to `[::]:22`, and the save handler persisting both files — so the open half was restored at every boot as faithfully as the closed one. A link-local address on the same segment is enough to use it. Disabling IPv6 was never the mitigation it appeared to be. hardening-basic writes net.ipv6.conf.{all,default,lo}.disable_ipv6=1, but systemd-networkd sets net.ipv6.conf.<iface>.disable_ipv6=0 on every link it configures, after /etc/sysctl.d has been applied. So the three values that are easy to check read 1 while the only interface carrying traffic has IPv6 live. Both READMEs now say that, with the measurement rather than the claim. The v6 rules mirror the v4 ones except for ICMPv6, where mirroring would be wrong: Neighbour Discovery *is* ICMPv6, so a blanket drop stops address resolution on the link and takes Path MTU discovery with it. RFC 4890's must-not-drop set, minus redirects, which accept_redirects=0 already refuses. Gated on /proc/net/if_inet6 rather than on the binary: a kernel booted with ipv6.disable=1 has nothing for ip6tables to talk to and must not fail the play for the lack of it. The molecule scenario makes the same distinction and says so aloud when the container cannot exercise the baseline. Claude-Session: https://claude.ai/code/session_01W5FkkabPcwgqKTQv4LD7DP
The role wrote the v4 table and nothing else, which is not a smaller
firewall but an open one. Measured on a converged host: `iptables -P INPUT
DROP` with every rule source-restricted, `ip6tables -P INPUT ACCEPT` beside
it, sshd bound to `[::]:22`, and the save handler persisting both files — so
the open half was restored at every boot as faithfully as the closed one. A
link-local address on the same segment is enough to use it.

Disabling IPv6 was never the mitigation it appeared to be.
hardening-basic writes net.ipv6.conf.{all,default,lo}.disable_ipv6=1, but
systemd-networkd sets net.ipv6.conf.<iface>.disable_ipv6=0 on every link it
configures, after /etc/sysctl.d has been applied. So the three values that
are easy to check read 1 while the only interface carrying traffic has IPv6
live. Both READMEs now say that, with the measurement rather than the claim.

The v6 rules mirror the v4 ones except for ICMPv6, where mirroring would be
wrong: Neighbour Discovery *is* ICMPv6, so a blanket drop stops address
resolution on the link and takes Path MTU discovery with it. RFC 4890's
must-not-drop set, minus redirects, which accept_redirects=0 already refuses.

Gated on /proc/net/if_inet6 rather than on the binary: a kernel booted with
ipv6.disable=1 has nothing for ip6tables to talk to and must not fail the
play for the lack of it. The molecule scenario makes the same distinction
and says so aloud when the container cannot exercise the baseline.

Claude-Session: https://claude.ai/code/session_01W5FkkabPcwgqKTQv4LD7DP
claudiomaradonna deleted branch ipv6-firewall-baseline 2026-08-28 15:18:25 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
claudiomaradonna/castrum!1
No description provided.