我正在从 iptables 迁移到 nftables。我有一个关于 nftables 中数据包处理顺序的基本问题。
由于可以创建多个相同类型的表(例如 inet),并且可以在每个表内创建具有不同或相同优先级的链,因此处理顺序是什么。
例如,如果我创建以下内容,顺序是什么。
table inet t1 {
chain INPUT {
type filter hook input priority 20; policy accept;
...
}
}
table inet t2 {
chain INPUT {
type filter hook input priority 20; policy accept;
...
}
}
虽然我知道链与不同的输入挂钩,但我尚未理解不同表背后的逻辑。
如果这是一个愚蠢或基本的问题,请道歉
答案1
示例中的顺序为不明确的,但是两条链都会被遍历(除非数据包在看到的第一个链中被丢弃)。
Netfilter 和网络/路由堆栈提供排序
这是Netfilter 和通用网络中的数据包流示意图:
虽然它是用iptables请记住,应用于时整体行为是相同的nftables有细微差别(例如:之间没有分离碾压和筛选,这就是全部筛选在nftables除了 mangle/OUTPUT 之外,它可能应该被翻译成输入路由钩子输出,或者大部分的桥梁混合在一起ebtables和iptables在下半部分看到更新: 不存在于nftables存在但应避免使用nftables直接在桥梁家族直接,并使用内核 >= 5.3 if连线那里需要功能(并且br_netfilter
根本不使用内核模块)。
表的作用
一张表在nftables不等于中的表iptables: 这是不太严格的东西。在nftables, 这桌子是一个组织链条的容器,放和其他类型的对象,并限制它们的范围。与之相反iptables这是完全可以接受的,有时需要在同一个表中混合不同的链类型(例如:nat、过滤器、路由):例如,这是他们访问公共链的唯一方式放因为它的范围仅限于表而不是全局的(就像iptables' 同伴IP集)。
然后,拥有同一系列的多个表(再次包括相同类型的链)也是完全可以接受的,用于特定处理或处理特定流量:在更改此表的内容时,不存在更改其他表中的规则的风险(尽管有总体结果仍然存在产生冲突影响的风险)。它有助于管理规则。例如NFTLB负载均衡器创建表(在各个系列中),所有表都命名为NFTLB,旨在仅由其自身管理,不会与其他用户定义的表发生冲突。
钩子之间和钩子内的排序
在给定的系列(netdev、bridge、arp、ip、ip6)中,注册到不同钩子(入口、预路由、输入、转发、输出、后路由)的链按照 Netfilter 提供的钩子顺序进行排序,如上图所示。优先级的范围仅限于同一个钩子,在这里并不重要。例如,在转发数据包的情况下type filter hook prerouting priority 500
仍然会发生之前的情况。type filter hook forward priority -500
在适用的情况下,对于给定系列的每个可能的钩子,每个连锁店都将与在同一地点注册的其他连锁店竞争。这桌子除了定义家庭之外,在这里不起任何作用。只要优先级不同,在给定的钩子类型内,数据包就会从最低优先级到最高优先级遍历该钩子内的链。如果完全相同的优先级用于相同系列和钩子类型的两条链,则顺序变得不确定。当前内核版本在创建链时,会将链添加到相应链表结构中具有相同优先级的链之前还是之后?下一个内核版本是否仍保持相同的行为,或者某些优化是否会改变这个顺序?这没有记录。两个钩子仍然会被调用,但是它们的调用顺序是未定义的。
这有什么关系呢?这是引用自手册页下面,只是为了澄清一个数据包可以在同一个钩子中多次被接受(或不接受):
accept
终止规则集评估并接受数据包。数据包仍然可以稍后被另一个钩子丢弃,例如,前向钩子中的接受仍然允许稍后在后路由钩子中丢弃数据包,或者具有更高优先级编号并随后在处理管道中评估的另一个前向基本链。
例如,如果一个链接受某个数据包,而另一个链丢弃这个相同的数据包,则总体结果将始终是降低。但是一个钩子可能会执行额外的操作,从而导致副作用:例如,它可能会将数据包的源地址添加到放另一个称为下一个的链已丢弃该数据包。如果顺序颠倒并且首先丢弃数据包,则不会发生这种“副作用”操作,并且放将不会被更新。因此,在这种情况下应该避免使用完全相同的优先级。对于其他情况,大多数情况下没有发生下降,这并不重要。人们应该避免使用相同的优先级,除非知道这并不重要。
与其他网络子系统的关系
在一个钩子内,所有整数范围可以用来选择顺序,但一些特定的阈值确实很重要。
从nftables'维基, 这是遗产iptables挂钩值适用于ip系列,还包括其他子系统:
NF_IP_PRI_CONNTRACK_DEFRAG (-400)
: 碎片整理的优先级
NF_IP_PRI_RAW (-300)
: 连接跟踪操作之前放置的原始表的传统优先级
NF_IP_PRI_SELINUX_FIRST (-225)
: SELinux 操作
NF_IP_PRI_CONNTRACK (-200)
: 连接跟踪操作
NF_IP_PRI_MANGLE (-150)
: mangle 操作
NF_IP_PRI_NAT_DST (-100)
: 目标 NAT
NF_IP_PRI_FILTER (0)
: 过滤操作,过滤表
NF_IP_PRI_SECURITY (50)
: 可以设置 secmark 的安全表的位置 例如
NF_IP_PRI_NAT_SRC (100)
: source NAT
NF_IP_PRI_SELINUX_LAST (225)
: 数据包退出时的 SELinux
NF_IP_PRI_CONNTRACK_HELPER (300)
: 退出时的连接跟踪
其中只有少数真正重要:那些不是来自iptables。例如(非详尽)家庭中ip
:
NF_IP_PRI_CONNTRACK_DEFRAG (-400)
:对于一个能够看到传入 IPv4 片段的链,它应该在预路由优先级低于-400。在此之后,只能看到重新组装的数据包(检查片段是否存在的规则永远不会匹配)。NF_IP_PRI_CONNTRACK (-200)
:让链条发挥作用前 连线它应该注册在预路由或在输出概率低于-200。例如,以优先级NF_IP_PRI_RAW (-300)
(或任何其他值 < -200 但仍 > -400,如果希望在所有情况下都匹配端口)注册以添加notrack
声明以防止连线为该数据包创建一个连接条目。所以nftables相当于iptables' raw/PREROUTING 只是过滤预路由具有足够的优先权。
杂项
一些特殊情况:
这内网家庭户口簿内ip和ip6同时家庭的钩子。
类型 nat
当规则匹配并执行 NAT 相关语句时,它的行为有所不同:数据包将不会进一步遍历纳特链条在同一个钩子上。类型 nat注册方式不同。它在其他非 NAT 挂钩中具有固定的优先级。例如在预路由或者输出
NF_IP_PRI_NAT_DST
对于过滤器挂钩,NAT 挂钩均以固定优先级 = -100 发生 。多个 NAT 挂钩仍然尊重它们之间的优先级顺序。有关的其他详细信息类型 nat可以在这个Q/A中看到:nftables:多种类型的链是否都针对给定的钩子进行评估?双方的 NAT 规则iptables-旧版和nftables不应与 4.18 之前的内核混合。 4.18之前,第一个设施iptables-旧版和nftables注册将处理挂钩中的所有 NAT。
答案2
长话短说
为了理解 netfilter 的处理顺序,我更喜欢更直观的形式:所以我经常参考普劳夫
(input interface)
|
v
/-------+-------\
| sanity checks |
\-------+-------/
|
v hook NF_IP_PRE_ROUTING
+------+------+
| conntrack |
| defrag. |
+-------------+
| mangle |
| PREROUTING |
+-------------+
| nat (dst) |
| PREROUTING |
+------+------+
|
v
local delivery /----+----\ forward
+---------------+ route +---------------+
| \---------/ |
v v
/-----+-----\ /-----+-----\
| defrag. | | TTL check |
\-----+-----/ | dec. TTL |
| \-----+-----/
v hook NF_IP_LOCAL_IN |
+------+------+ |
| mangle (1) | |
| INPUT | |
+-------------+ |
| filter | v
| INPUT | /-----+-----\
+-------------+ | DF check |
| nat (src)(2)| \-----+-----/
+-------------+ |
| conntrack | |
| confirm | |
+------+------+ hook v NF_IP_FORWARD
| +------+------+
v | mangle (1) |
/-------+-------\ | FORWARD |
| local process | +-------------|
\-------+-------/ | filter |
| | FORWARD |
v +------+------+
/-----+-----\ |
| route | |
| frag. | |
\-----+-----/ |
| |
v hook NF_IP_LOCAL_OUT |
+------+------+ |
| conntrack | |
| defrag. | |
+-------------+ |
| mangle | |
| OUTPUT | |
+-------------+ v
| nat (dst)(3)| /-----+-----\
| OUTPUT | | frag. |
+-------------+ \-----+-----/
| filter | |
| OUTPUT | |
+------+------+ |
| |
v |
/-----+-----\ |
| reroute | |
\-----+-----/ |
| |
+------------------+ +------------------+
| |
v v hook NF_IP_POST_ROUTING
+---+-----+---+
| mangle (1) |
| POSTROUTING |
+-------------+
| nat (src) |
| defrag. |
| POSTROUTING |
+-------------+
| conntrack |
| confirm |
| frag. |
+------+------+
|
v
(output interface)