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.)

我幾乎花了一天時間尋找解決方案。歡迎任何幫助!感謝

答案1

ICMPv6是基於IPv6的協議,透過組播和單播實現鏈路層解析。丟棄 ICMPv6 意味著不再有可用的解決方案:節點無法找到同一 LAN 中的其他節點。這包括上游 IPv6 路由器,如果 ICMPv6 被丟棄,則上游 IPv6 路由器將無法使用 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 資料包相關的類似困難。

相關內容