Nftables 规则集在启动时无法正确应用

Nftables 规则集在启动时无法正确应用

Ubuntu 18.04.1。

完全相同的规则集文件无论是由系统在启动时加载(损坏)还是在启动后手动加载(正常工作),都会产生不同的行为。
具体来说,当在启动时加载时,nft 似乎会将相关流量识别为其输入链。但在启动后(重新)加载时,它会正确地将其传递到正向链。
感兴趣的流量从公共接口上的端口 4022 经过 SSH DNAT 传输到端口 22 上的内部 IP。

我的 /etc/nftables.conf:

#!/usr/sbin/nft -f

flush ruleset

table ip nat {
        chain prerouting {
                        type nat hook prerouting priority -100; policy accept;
                        iif eth0 tcp dport 4022 dnat to 10.0.0.2:22
                }
        chain postrouting {
                        type nat hook postrouting priority 100; policy accept;
                        oifname "eth0" masquerade
                }
}

table ip filter {
        chain input {   
                        type filter hook input priority 0; policy drop;
                        tcp dport 4022 meta nftrace set 1
                        counter
                        ip protocol icmp icmp type echo-request accept
                        ct state { established, related} accept
                        iif lo accept
                        iif eth0 accept
                        iifname "eth0" jump input_eth0
                        iifname "br0" jump input_br0
                }
        chain forward { 
                        type filter hook forward priority 0; policy drop;
                        meta nftrace set 1
                        counter
                        ct state { established, related} accept
                        iifname "eth0" jump forward_eth0
                        iifname "br0" jump forward_br0
                }
        chain output {  
                        type filter hook output priority 0; policy accept;
                }

# ETH0 : 
        chain input_eth0 {
                        counter
                        tcp dport ssh accept
                        tcp dport http accept
                        tcp dport https accept
                }
        chain forward_eth0 {
                        counter
                        ip daddr 10.0.0.2 tcp dport 22 nftrace set 1 accept
                }

# LXD BRIDGE : 
        chain input_br0 {
                        counter
                        reject with icmp type host-prohibited
                }
        chain forward_br0 {
                        counter
                        ip saddr 10.0.0.2 accept
                        ip saddr 10.0.0.10 accept
                        ip saddr 10.0.0.11 accept
                        reject with icmp type host-prohibited
                }

# POSTROUTING : 
        chain pr {
                        type filter hook postrouting priority -10; policy accept;
                        oifname "eth0" jump pr_eth0
                }
        chain pr_eth0 {
                }

}

这是启动后、重新加载文件之前 nft 监视器跟踪的样子,其中 nft 似乎认为流量应该通过其输入链:

trace id 68d42e8a ip filter input packet: iif "eth0" ether saddr 00:de:ad:be:ef:01 ether daddr 00:de:ad:be:ef:02 ip saddr S.S.S.S ip daddr D.D.D.D ip dscp cs0 ip ecn not-ect ip ttl 58 ip id 50033 ip length 60 tcp sport 7240 tcp dport 4022 tcp flags == syn tcp window 29200 
trace id 68d42e8a ip filter input rule tcp dport 4022 nftrace set 1 (verdict continue)
trace id 68d42e8a ip filter input rule counter packets 230 bytes 382785 (verdict continue)
trace id 68d42e8a ip filter input rule iif "eth0" accept (verdict accept)

这是发出“sudo nft -f /etc/nftables.conf”后的跟踪开始,其中 nft 使用其前向链,正如我所期望的那样:

trace id 1177c4c4 ip filter forward packet: iif "eth0" oif "br0" ether saddr 00:de:ad:be:ef:01 ether daddr 00:de:ad:be:ef:02 ip saddr S.S.S.S ip daddr 10.0.0.2 ip dscp cs0 ip ecn not-ect ip ttl 57 ip id 22369 ip length 60 tcp sport 1665 tcp dport ssh tcp flags == syn tcp window 29200
trace id 1177c4c4 ip filter forward rule nftrace set 1 (verdict continue)
trace id 1177c4c4 ip filter forward rule counter packets 41 bytes 6437 (verdict continue)
trace id 1177c4c4 ip filter forward rule iifname "eth0" jump forward_eth0 (verdict jump forward_eth0)
trace id 1177c4c4 ip filter forward_eth0 rule counter packets 1 bytes 60 (verdict continue)
trace id 1177c4c4 ip filter forward_eth0 rule ip daddr 10.0.0.2 tcp dport ssh nftrace set 1 accept (verdict accept)
trace id 1177c4c4 ip filter pr verdict continue
trace id 1177c4c4 ip filter pr
trace id 1177c4c4 ip nat postrouting verdict continue
trace id 1177c4c4 ip nat postrouting
trace id b9475640 ip filter forward packet: iif "br0" oif "eth0" ether saddr 00:de:ad:be:ef:03 ether daddr 00:de:ad:be:ef:04 ip saddr 10.0.0.2 ip daddr S.S.S.S ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 0 ip length 60 tcp sport ssh tcp dport 1665 tcp flags == 0x12 tcp window 28960
trace id b9475640 ip filter forward rule nftrace set 1 (verdict continue)
trace id b9475640 ip filter forward rule counter packets 41 bytes 6437 (verdict continue)
trace id b9475640 ip filter forward rule ct state {  } accept (verdict accept)
trace id b9475640 ip filter pr packet: oif "eth0" ip saddr 10.0.0.2 ip daddr S.S.S.S ip dscp cs0 ip ecn not-ect ip ttl 63 ip id 0 ip length 60 tcp sport ssh tcp dport 1665 tcp flags == 0x12 tcp window 28960
trace id b9475640 ip filter pr rule oifname "eth0" jump pr_eth0 (verdict jump pr_eth0)
trace id b9475640 ip filter pr_eth0 verdict continue
trace id b9475640 ip filter pr verdict continue
trace id b9475640 ip filter pr
[...]

我在 /var/log/syslog、/var/log/kern.log、dmesg 等中没有看到 nft 发出的任何警告或错误。

eth0、br0 和 lo 均在 /etc/network/interfaces 中配置;不使用 netplan。

我的第一个猜测是,这个问题与 nft 在接口(eth0、br0)启动之前初始化有关,甚至可能还不存在。我还没有在 Ubuntu 以外的其他操作系统上尝试过。我在两台不同的服务器上都遇到了这个问题。我还没有尝试在 iptables 中复制 nftables 规则集。

有人知道如何修复——甚至排除故障——这个问题吗?

相关内容