nftables 规则集调试与跟踪:从 nftrace 标记到逐包判决

从 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

随后,数据包继续经过规则集中的规则。

另请参阅

一些外部工具能够自动完成本文描述的全部步骤,可参阅:

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容