Ruleset debug/tracing
Since nftables v0.6 and linux kernel 4.6, ruleset debug/tracing is supported.
This is an equivalent of the old iptables method -J TRACE, but with some great improvements.
The steps to enable debug/tracing is the following:
- give support in your ruleset for it (set nftrace in any of your rules)
- monitor the trace events from the nft tool
enabling nftrace
To enable nftrace in a packet, use a rule with this statement:
meta nftrace set 1
After all, nftrace is part of the metainformation of a packet.
Of course, you may only enable nftrace for a given matching packet. In the example below, we only enable nftrace for tcp packets using the loopback interface:
iif lo ip protocol tcp meta nftrace set 1
Adjusting nftrace to only your subset of desired packets is key to properly debug the ruleset, otherwise you may get a lot of debug/tracing information which may be overwhelming.
The following example shows how to enable tracing for your existing ruleset:
% nft add chain filter trace_chain { type filter hook prerouting priority -600\; }
% nft add rule filter trace_chain meta nftrace set 1
This is registering a trace_chain chain at priority -600 which contains a rule to enable tracing. If you already have a prerouting chain, then make sure the trace_chain priority comes before your existing prerouting chain.
Once you are done with rule tracing, you can just delete this chain to disable it:
% nft delete chain filter trace_chain
monitoring tracing events
In nftables, getting the debug/tracing events is a bit different from the iptables world. Now, we have an event-based monitor for the kernel to notify the nft tool.
The basic syntax is:
% nft monitor trace
Each trace event is assigned an 'id' for you to easily follow different packets in the same trace session.
complete example
Here are a couple of complete examples of this debug/tracing mechanism in work. Assuming you have this ruleset:
% cat ruleset.nft
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
Then, add a chain that enables tracing:
% nft add chain ip filter trace_chain { type filter hook prerouting priority -600\; }
And the rule to enable the tracing:
% nft add rule ip filter trace_chain meta nftrace set 1
Simple tracing test, by pinging one host:
% ping -c 1 8.8.8.8
You run on a different terminal:
% 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:dd: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:dd: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)
Tracing two different kind of packets at the same monitor session:
% nft filter input tcp dport 10000 nftrace set 1
% nft filter input icmp type echo-request nftrace set 1
% nft -nn monitor trace
trace id e1f5055f ip filter input packet: iif eth0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 ip saddr 192.168.122.1 ip daddr 192.168.122.83 ip tos 0 ip ttl 64 ip id 32315 ip length 84 icmp type echo-request icmp code 0 icmp id 10087 icmp sequence 1
trace id e1f5055f ip filter input rule icmp type echo-request nftrace set 1 (verdict continue)
trace id e1f5055f ip filter input verdict continue
trace id e1f5055f ip filter input
trace id 74e47ad2 ip filter input packet: iif vlan0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 vlan pcp 0 vlan cfi 1 vlan id 1000 ip saddr 10.0.0.1 ip daddr 10.0.0.2 ip tos 0 ip ttl 64 ip id 49030 ip length 84 icmp type echo-request icmp code 0 icmp id 10095 icmp sequence 1
trace id 74e47ad2 ip filter input rule icmp type echo-request nftrace set 1 (verdict continue)
trace id 74e47ad2 ip filter input verdict continue
trace id 74e47ad2 ip filter input
trace id 3030de23 ip filter input packet: iif vlan0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 vlan pcp 0 vlan cfi 1 vlan id 1000 ip saddr 10.0.0.1 ip daddr 10.0.0.2 ip tos 16 ip ttl 64 ip id 59062 ip length 60 tcp sport 55438 tcp dport 10000 tcp flags == syn tcp window 29200
trace id 3030de23 ip filter input rule tcp dport 10000 nftrace set 1 (verdict continue)
trace id 3030de23 ip filter input verdict continue
trace id 3030de23 ip filter input