nftables:如何在接受判决后停止进一步的链遍历

nftables:如何在接受判决后停止进一步的链遍历

语境 :https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains 如果数据包被接受,并且存在另一个具有相同钩子类型且优先级更高的链,则数据包随后将遍历该链。因此,接受裁决(无论是通过规则还是默认链策略)不一定是最终裁决。但是,对于受到丢弃裁决的数据包,情况并非如此。相反,丢弃会立即生效,无需评估其他规则或链。

我希望不同的项目模块拥有各自的表和链,例如,firewalld 有自己的表。我想要我的表,每个表将由单独的团队/模块维护。来自该表的链中可以有重复的规则。现在我认为大多数时候我们知道要接受什么,我们拒绝所有我们不知道的规则。使用上述 nftable 设计,如果数据包在其中一个链中被接受,它将进入优先级更高的下一个链。接受后处理不会停止。对我来说,下一个链是 firewalld,由于我的规则不在 firewalld 链中,因此它丢弃了该数据包。

nft monitor 
trace id 1cd90444 ip filter INPUT packet: iif "ens192" ether saddr 00:0c:29:1b:82:51 ether daddr 00:50:56:9c:b6:7e ip saddr 10.221.39.90 ip daddr 10.221.39.50 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 55469 ip length 60 tcp sport 47944 tcp dport 2049 tcp flags == syn tcp window 29200                                 
trace id 1cd90444 ip filter INPUT rule tcp dport 2049 meta nftrace set 1 (verdict continue)               
trace id 1cd90444 ip filter INPUT rule tcp dport 2049 accept (verdict accept)                             
trace id 1cd90444 inet firewalld filter_INPUT packet: iif "ens192" ether saddr 00:0c:29:1b:82:51 ether daddr 00:50:56:9c:b6:7e ip saddr 10.221.39.90 ip daddr 10.221.39.50 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 55469 ip protocol tcp ip length 60 tcp sport 47944 tcp dport 2049 tcp flags == syn tcp window 29200     
trace id 1cd90444 inet firewalld filter_INPUT rule jump filter_INPUT_POLICIES_pre (verdict jump filter_INPUT_POLICIES_pre)
trace id 1cd90444 inet firewalld filter_INPUT_POLICIES_pre rule jump filter_IN_policy_allow-host-ipv6 (verdict jump filter_IN_policy_allow-host-ipv6) 
trace id 1cd90444 inet firewalld filter_IN_policy_allow-host-ipv6 rule jump filter_IN_policy_allow-host-ipv6_pre (verdict jump filter_IN_policy_allow-host-ipv6_pre)
trace id 1cd90444 inet firewalld filter_IN_policy_allow-host-ipv6_pre verdict continue 
...
trace id 1cd90444 inet firewalld filter_INPUT_POLICIES_post verdict continue                              
trace id 1cd90444 inet firewalld filter_INPUT rule reject with icmpx type admin-prohibited (verdict drop)     

看到ip filter INPUT判决结果为接受,然后防火墙将其丢弃。看起来接受规则必须位于链的最后,即优先级最高的链中。我可以使我的表具有更高的优先级,这将绕过防火墙表,但正如我提到的,可能会有多个表决定接受数据包,如果下一个表没有相同的接受,则总体结果将是丢弃(因为最后一个表有丢弃规则)。

请纠正我,低优先级表中的链/规则实际上毫无用处。我无法理解它的用途。有人可以举例说明低优先级链如何有用以及如何为不同的项目创建不同的表吗?

iptables 没有这个问题,那里Accept就是accept,哪些项目/防火墙需要nftables这样的设计?

答案1

当我今天遇到同样的问题时,我和你一样感到惊讶。

简介:我致力于利用 Linux 上的命名空间和网络编写自己的系统。因此,我必须在 中管理自己的规则nftables。由于firewalld也在系统上配置,并且它会阻止我想要允许的流量,因此最初我认为解决方案可能是创建优先级更高的链(优先级数字较低)。

你无法想象当我发现尽管我这样做了,我的流量还是被阻止了,我是多么惊讶firewalld。令人惊讶的是,你的问题是我在网上找到的唯一一个提到这个问题的问题。

正如您所说,阻止所有内容并仅接受您想要接受的流量是如此自然。然后,在操作系统上运行的不同应用程序,管理防火墙规则应该是独立的。它应该看起来像这样:

# rules for app X
accept input on port 80
forward 192.168.1.1:80 to 10.10.0.1:8080

# rules for app Y
accept input on port 22

# default action
drop whatever reached this point

app Y在当前实施中,由 管理的规则必须接受由 管理的规则,这是荒谬的app X,因为否则流量将被丢弃。另一方面,正如文档所述,drop行动是立即的。这意味着,防火墙通常会做的是:默认丢弃所有内容,关闭其他应用程序配置的流量的大门。

最初我认为它是通过这种方式实现的,nftables所以我的想法是编写自己的防火墙,直接连接到netfilter内核的模块,这样我就可以在nftables控制之前注入我的规则。

但令人遗憾的是,我们正在讨论的局限性来自于它netfilter本身: https://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-4.html#ss4.5

If NF_ACCEPT, the next hook attached to that point will be called.
If NF_DROP, the packet is dropped.

因此,只要任何钩子决定删除包,它就会被永久删除。但如果它被接受,那么如果任何其他应用程序注入自己的逻辑,它很可能会在稍后被删除。

这很糟糕,这意味着不同的应用程序(例如libvirt、、或自定义应用程序)必须争夺接受所需流量的优先级。如果链中的任何内容默认丢弃不相关的流量(例如docker),我们就会陷入混乱。firewalldiptablesfirewalld

我觉得这样设计的决定netfilter很糟糕……而且似乎没有解决办法。它禁用了在系统上安装多个防火墙来管理不同方面的可能性。无论你安装什么防火墙,它都具有垄断权。

相关内容