NFTABLE 问题:IPv6 的行为与具有镜像配置的 IPv4 不同

NFTABLE 问题:IPv6 的行为与具有镜像配置的 IPv4 不同

我的服务器上的 IPv6 存在问题。我已将 nginx 配置为从 IPv4 和 IPv6 监听端口 443。它运行良好:我的网站在启用 TLS 的情况下可通过 Internet 访问。

当我激活 nftables 时事情变得复杂了:当我从 IPv4 访问我的网站时,它可以正常工作,但是当我从 IPv6 访问它时,连接超时 :(

输出sudo nft list ruleset

table inet filter {
        chain INPUT {
                type filter hook input priority filter; policy drop;
                meta nftrace set 1
                ct state established,related accept comment "allow established connections"
                iif "lo" accept comment "allow all from localhost"
                iif != "lo" ip daddr 127.0.0.0/8 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
                iif != "lo" ip6 daddr ::1 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
                iifname "tunnel0" accept comment "allow all from VPN"
                udp dport 12345 accept comment "allow VPN on port 12345"
                tcp dport { 22, 80, 443 } accept comment "allow HTTP, HTTPS and SSH on classic ports"
        }

        chain OUTPUT {
                type filter hook output priority filter; policy accept;
        }

        chain FORWARD {
                type filter hook forward priority filter; policy drop;
        }
}

输出sudo nft monitor trace | grep 443

trace id 76d7cb1a inet filter INPUT packet: iif "eth0" ether saddr AA:AA:AA:AA:AA:AA ether daddr BB:BB:BB:BB:BB:BB ip6 saddr 2a01:cb09:804b:cd61:CCCC:CCCC:CCCC:CCCC ip6 daddr 2001:CCCC:CCCC:CCCC::CCCC ip6 dscp cs0 ip6 ecn not-ect ip6 hoplimit 45 ip6 flowlabel 0 ip6 nexthdr tcp ip6 length 40 tcp sport 53184 tcp dport 443 tcp flags == syn tcp window 22240

请注意,我在端口 22 上使用 ssh 时没有遇到此问题。我nftables v0.9.8 (E.D.S.)在 Debian 11 上运行。

我几乎花了一天时间寻找解决方案。欢迎任何帮助!谢谢

答案1

ICMPv6 是基于 IPv6 的协议,它使用多播和单播实现链路层解析。放弃 ICMPv6 意味着不再有可用的解析:节点无法找到同一 LAN 中的其他节点。这包括上游 IPv6 路由器,如果放弃 ICMPv6,该路由器将无法使用 IPv6 与 Linux 系统通信。

相比之下,IPv4 依赖于不同的协议:ARP(使用广播和单播),它不通过 IPv4。因此,你可以放弃所有 ICMP,并且不会遇到 LAN 连接问题,因为 ARP 不受影响(但仍然可能受到PMTU黑洞以及在丢弃所有 ICMP 时出现的其他类似问题,尤其是在使用隧道时)。

因此,首先启用所有 ICMPv6,然后在第二次验证 IPv6 再次正常工作后,如果您不想启用所有 ICMPv6,请检查在邻居发现协议(对于非路由节点,我会说至少类型 134、135、136 和 137):

nft add rule inet filter INPUT 'icmpv6 type { 134, 135, 136, 137 } accept'

答案2

这对我来说很有效:

table inet filter {
    chain INPUT {
        type filter hook input priority 0; policy drop;

        meta l4proto ipv6-icmp accept
        ip6 ecn not-ect accept

        # Although I used the slightly more restrictive:
        # ip6 ecn not-ect ip6 hoplimit 1 accept
    }
}

请注意,您捕获的数据包是一个 ECN 数据包,就像我的一样(除了我的数据包具有来自本地链路 fe80::/10 saddr 的 ip6 hoplimit 1,而您的数据包具有 ip6 hoplimit 45)。似乎必须接受此数据包才能由我的 ISP(Spectrum Broadband)分配 IPv6 块,也许您在这些 ECN 数据包方面遇到了类似的困难。

相关内容