Difference between revisions of "Ruleset debug/tracing"

From nftables wiki
Jump to navigation Jump to search
Line 55: Line 55:
= complete example =
= complete example =


Here are a couple of complete examples of this debug/tracing mechanism in work.
Here are a couple of complete examples of this debug/tracing mechanism in work. Assuming you have this ruleset:


Simple tracing test:
<source lang="bash">
% 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
</source>
 
Then, add a chain that enables tracing:
 
<source lang="bash">
% nft add chain ip filter trace_chain { type filter hook prerouting priority -600\; }
</source>
 
And the rule to enable the tracing:
 
<source lang="bash">
% nft add rule ip filter trace_chain meta nftrace set 1
</source>
 
Simple tracing test, by pinging one host:
 
<source lang="bash">
% ping -c 1 8.8.8.8
</source>
 
You run on a different terminal:


<source lang="bash">
<source lang="bash">
% nft add rule inet filter input iif lo counter nftrace set 1 accept
% nft monitor trace
% nft monitor trace
trace id 530fa6dd inet filter input packet: iif lo
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 530fa6dd inet filter input rule iif lo accept (verdict accept)
trace id a95ea7ef ip filter trace_chain rule meta nftrace set 1 (verdict continue)
trace id 87a375ea inet filter input packet: iif lo
trace id a95ea7ef ip filter trace_chain verdict continue
trace id 87a375ea inet filter input rule iif lo accept (verdict accept)
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)
</source>
</source>



Revision as of 22:37, 28 October 2020

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