我正在使用两台虚拟机测试 nftables 防火墙规则,一台带有活动防火墙,另一台尝试连接到它。
例如使用 netcat 并且没有防火墙:
nc -6 fe80::9d08:b3e2:47fa:2935%ens33 <any port>
如果没有服务正在监听,但端口已打开,则成功响应“连接被拒绝”。如果我让 netcat 在另一端监听端口,则连接成功。
然后我添加一条防火墙规则,删除除开放端口 33333 之外的所有内容:
nc -6 fe80::9d08:b3e2:47fa:2935%ens33 33333
并且连接再次按预期被拒绝/成功。
然后我尝试一些被防火墙默认策略丢弃的其他端口:
nc -6 fe80::9d08:b3e2:47fa:2935%ens33 22222
并且 netcat 会挂起直到超时,我想这是意料之中的。但现在的问题是:如果我再次尝试
nc -6 fe80::9d08:b3e2:47fa:2935%ens33 33333
它也会挂起,直到超时。
我必须刷新防火墙规则,再次成功运行 netcat,重新应用防火墙规则,然后它才能再次工作。直到我尝试连接到关闭的端口。
这只发生在 IPv6 上。我试过ncat
和nmap
,都tcpdump
出现了类似的怪异行为。IPv4 没有问题。
我似乎对 IPv6 网络有些不明白?
答案1
总结:最可能的解释是您删除了 ICMPv6。除非您了解到底哪些内容不应删除,否则请不要删除所有 ICMPv6。
在测试期间,您必须插入如下规则:
meta l4proto ipv6-icmp accept
在丢弃其他数据包的规则之前。上面的规则可以改进,但这超出了本问答的范围。
ICMPv6 除其他角色(例如 ping、超时等)外,还包括 IPv4 的 ARP 的等效角色:使用邻居发现协议从上层 IPv6 地址解析链路层 MAC 地址(新民主党)。虽然 ARP 不在ip
家庭内设置防火墙,但在arp
家庭内,NDP,部分如果 ICMPv6 确实被ip6
(或inet
) 家庭设置防火墙。如果全部丢弃,则 NDP 被丢弃。
缓存重新验证的方式是,一旦邻居条目在几秒钟后自然地从 REACHABLE 切换到 STALE 状态,它仍然可以在没有确认的情况下使用,尤其是在发生流量时。一段时间后,它会切换到 PROBE 状态,然后需要 NDP 确认,切换回 REACHABLE。因此,一种状态流是:
REACHABLE -> STALE -> PROBE -> REACHABLE
根据交通情况,还有其他可能性。详情请参阅RFC 4861。当没有流量时,STALE 状态可以存在很长时间:
从正确性角度来看,没有必要定期清除目标和邻居缓存条目。尽管陈旧 信息可能会无限期地保留在缓存中邻居不可达检测算法确保陈旧信息如果实际正在使用,则快速清除。
在 STALE 和 PROBE 状态下,旧条目被假定为无害:它仍可用于发送流量。当 NDP 几秒后失败时,此操作将停止:目标现在处于 FAILED 状态,并且 MAC 地址将从缓存中删除。
如果禁用所有流量,您也会禁用 NDP 流量并很快失去 IPv6 连接(包括全局 IPv6)。
这解释了您的所有症状:
- 您尝试了没有规则的 NDP:NDP 成功发生,客户端的 NDP 缓存进入 REACHABLE 状态,然后可能切换到 STALE 状态,该状态可能会持续很长时间
- 规则集已安装,丢弃 NDP 尝试。如果没有流量,客户端的 NDP 缓存可能会长时间处于 STALE 状态。
- 对 TCP 33333 的第一次测试使用了 STALE 缓存条目并成功。观察到的返回流量甚至可能会延迟切换到 PROBE 状态(因此第一次测试可能可以在几秒钟内成功重复)。
- 下一个测试要么在条目切换至 PROBE 状态(NDP 失败)然后切换至 FAILED 状态(删除 MAC 地址)之前未能到达目标,要么成功完成此操作但仍然被阻止,因为 TCP 22222 流量被 drop-all 规则阻止。重复尝试(包括 TCP SYN 重试)而没有回复将加速切换到 PROBE 状态。
- 邻居缓存迟早会切换到 PROBE 状态,然后切换到 FAILED 状态。
- 对 TCP 33333 的最后一次测试没有已知的 MAC 地址来发送 IPv6 帧:它无法成功。
这里使用 IPv6 链路层地址作为目的地时,还会观察到一个小的行为差异:当尝试到达链路层地址(即 fe80::/10 地址)时,与 IPv6 全局地址目的地或 IPv4 情况相反,客户端似乎不会在 3 秒后失败并出现EHOSTUNREACH
(没有到主机的路由):客户端根本没有发生任何警告(经过测试strace
)。
因此无法区分故障是由 NDP 故障(非预期影响)还是由防火墙的其余部分引起的:人们可能会认为防火墙突然出现异常,但事实并非如此。NDP 缓存中的状态更改可能需要长达 30 秒的时间。
您可以使用 (Linux) 客户端进行检查:
ip -6 neigh show fe80::9d08:b3e2:47fa:2935 dev ens33
最后可能会显示:
fe80::9d08:b3e2:47fa:2935 dev ens33 FAILED
可以通过以下方式实时跟踪状态变化:
ip -ts -6 monitor neigh dev ens33