从 nftables v0.6 和 Linux 内核 4.6 开始,系统支持规则集调试与跟踪。
这相当于旧版 iptables 中的 -J TRACE 方法,但带来了一些重要改进。
启用调试与跟踪需要完成以下步骤:
- 在规则集中加入支持跟踪的配置,也就是在某条规则中设置
nftrace。 - 使用
nft工具监视跟踪事件。
启用 nftrace
要为一个数据包启用 nftrace,请使用包含以下语句的规则:
meta nftrace set 1
nftrace 本来就是数据包元信息的一部分。
当然,也可以只为符合指定匹配条件的数据包启用 nftrace。下面的示例只为 TCP 数据包启用 nftrace:
ip protocol tcp meta nftrace set 1
将 nftrace 限制在所需的数据包子集内,是正确调试规则集的关键;否则,可能会产生数量庞大的调试与跟踪信息,让人难以处理。
使用专用链启用跟踪
推荐专门增加一条链,用来启用跟踪。
注册一条 trace_chain 来启用跟踪。如果已经有一条 prerouting 链,请确保 trace_chain 的优先级使其先于现有的 prerouting 链执行。
% nft add chain filter trace_chain { type filter hook prerouting priority -301\; }
% nft add rule filter trace_chain meta nftrace set 1
这个示例假定已经存在一条优先级为 -300 的 raw prerouting 链,因此将跟踪链注册在紧接其前的位置,优先级设为 -301。
完成规则跟踪后,可以直接删除这条链,以关闭跟踪:
% nft delete chain filter trace_chain
监视跟踪事件
在 nftables 中,获取调试与跟踪事件的方式与 iptables 有所不同。现在使用的是基于事件的监视机制,由内核通知 nft 工具。
基本语法如下:
% nft monitor trace
每个跟踪事件都会带有一个 id,便于在同一次跟踪会话中区分并跟踪不同的数据包。
完整示例
下面给出一个完整示例,展示调试与跟踪机制的工作过程。
假设有如下规则集:
table ip filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related counter packets 2 bytes 292 accept
ct state new tcp dport 22 counter packets 0 bytes 0 accept
}
}
加载该规则集:
% nft -f ruleset.nft
然后增加一条用于启用跟踪的链:
% nft add chain ip filter trace_chain { type filter hook prerouting priority -1\; }
这样会将 trace_chain 注册在现有的 input 链之前。
再添加启用跟踪的规则:
% nft add rule ip filter trace_chain meta nftrace set 1
向一台主机发送 ping 请求,进行简单的跟踪测试:
% ping -c 1 8.8.8.8
在另一个终端中运行:
% nft monitor trace
trace id a95ea7ef ip filter trace_chain packet: iif "enp0s25" ether saddr 00:0d:b9:4a:49:3d ether daddr 3c:97:0e:39:aa:20 ip saddr 8.8.8.8 ip daddr 192.168.2.118 ip dscp cs0 ip ecn not-ect ip ttl 115 ip id 0 ip length 84 icmp type echo-reply icmp code net-unreachable icmp id 9253 icmp sequence 1 @th,64,96 24106705117628271805883024640
trace id a95ea7ef ip filter trace_chain rule meta nftrace set 1 (verdict continue)
trace id a95ea7ef ip filter trace_chain verdict continue
trace id a95ea7ef ip filter trace_chain policy accept
trace id a95ea7ef ip filter input packet: iif "enp0s25" ether saddr 00:0d:b9:4a:49:3d ether daddr 3c:97:0e:39:aa:20 ip saddr 8.8.8.8 ip daddr 192.168.2.118 ip dscp cs0 ip ecn not-ect ip ttl 115 ip id 0 ip length 84 icmp type echo-reply icmp code net-unreachable icmp id 9253 icmp sequence 1 @th,64,96 24106705117628271805883024640
trace id a95ea7ef ip filter input rule ct state established,related counter packets 168 bytes 53513 accept (verdict accept)
trace id 唯一标识一个数据包。跟踪信息首先描述该数据包进入链时的情况:
trace id a95ea7ef ip filter trace_chain packet: iif "enp0s25" ether saddr 00:0d:b9:4a:49:3d ether daddr 3c:97:0e:39:aa:20 ip saddr 8.8.8.8 ip daddr 192.168.2.118 ip dscp cs0 ip ecn not-ect ip ttl 115 ip id 0 ip length 84 icmp type echo-reply icmp code net-unreachable icmp id 9253 icmp sequence 1 @th,64,96 24106705117628271805883024640
随后,数据包继续经过规则集中的规则。
另请参阅
一些外部工具能够自动完成本文描述的全部步骤,可参阅:
- nftables-tracer,基于 Python。
- nftrace,基于 Go。
原文作者:nftables Wiki/Netfilter 项目贡献者,参见页面修订历史。原页面声明:除另有说明外,内容以 GNU Free Documentation License 1.3 或更新版本提供。该许可声明及原始来源在本译文中予以保留;译文修改为英译中,并加入已明确标注的译者说明。中文整理日期:2026 年 10 月 3 日。












暂无评论内容