Difference between revisions of "Matching connection tracking stateful metainformation"

From nftables wiki
Jump to: navigation, search
(Matching the conntrack mark)
(conntrack command sample output table: linked ct matches to sections below.)
 
(24 intermediate revisions by the same user not shown)
Line 1: Line 1:
As in ''iptables'', you can match the state tracking information (sometimes refered as ''conntrack'' or ''ct'' information) that Netfilter collects through the ''Connection Tracking System'' to deploy stateful firewalls.
+
nftables conntrack (''ct'') expressions enable [https://en.wikipedia.org/wiki/Stateful_firewall stateful firewalls] by matching packets that correspond to connections tracked by netfilter's [[Connection_Tracking_System | Connection Tracking System]].
  
''nftables'' provides the ''ct'' selector which can be used to match:
+
= Conntrack metadata available =
  
* State information: ''new'', ''established'', ''related'' and ''invalid''. In this regard, there is no changes with ''iptables''.
+
It is useful to refer to the [[Data_types#Conntrack_types|conntrack data types]].
* The conntrack mark.
 
* Status information: ''expected'', ''seen-reply'', ''assured'', ''confirmed'', ''snat'', ''dnat'', ''dying''.
 
  
== Matching the state information ==
 
  
The following example shows how to deploy an extremely simple stateful firewall with ''nftables'':
+
== Conntrack-assigned metadata ==
 +
 
 +
Conntrack itself maintains most of its metadata for each tracked connection. The [http://conntrack-tools.netfilter.org/conntrack.html ''conntrack''] command-line tool makes it easy to list these metadata as well as manage the connections. Following is a sample partial output, run on a host serving an active sshd session. The ''id'' option includes the unique conntrack id in the output; the ''extended'' option produces the listing in ''/proc/net/nf_conntrack'' format.
 +
 
 +
<source>
 +
% conntrack -L -o id,extended
 +
...
 +
ipv4    2 tcp      6 421957 ESTABLISHED src=192.168.0.2 dst=192.168.0.8 sport=34621 dport=22 src=192.168.0.8 dst=192.168.0.2 sport=22 dport=34621 [ASSURED] mark=6 use=1 id=2014938051
 +
...
 +
</source>
 +
 
 +
The following table lists each conntrack metadata field in the above output along with the nftables ''ct'' selector to match it.
 +
 
 +
{| class="wikitable"
 +
!colspan="5"|''conntrack'' command output
 +
|- style="vertical-align:bottom;"
 +
! style="text-align:right;" | Column&nbsp;#
 +
! style="text-align:left;" | Description
 +
! style="text-align:left;" | Example&nbsp;value
 +
! style="text-align:left;" | ''ct'' Match
 +
! style="text-align:left;" | Notes
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 1
 +
| L3&nbsp;protocol&nbsp;name
 +
| ''ipv4''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_l3proto_-_conntrack_L3_protocol|''ct&nbsp;l3proto'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 2
 +
| L3&nbsp;protocol&nbsp;number
 +
| ''2''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_l3proto_-_conntrack_L3_protocol|''ct&nbsp;l3proto'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 3
 +
| L4&nbsp;protocol&nbsp;name
 +
| ''tcp''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_protocol-_conntrack_L4_protocol|''ct&nbsp;protocol'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 4
 +
| L4&nbsp;protocol&nbsp;number
 +
| ''6''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_protocol-_conntrack_L4_protocol|''ct&nbsp;protocol'']]
 +
| As shown in [https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/in.h in.h] protocol value 6 indicates TCP.
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 5
 +
| timeout, s
 +
| ''421957''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_expiration|''ct&nbsp;expiration'']]
 +
| Seconds until conntrack entry is invalidated; reset to initial value when connection sees a new packet.
 +
Default TCP connection timeout is 5 days. You can change this via the [[Connection_Tracking_System|conntrack sysfs setting]] ''nf_conntrack_tcp_timeout_established''.
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 6
 +
| conntrack&nbsp;state
 +
| ''ESTABLISHED''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_state_-_conntrack_state|''ct&nbsp;state'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 7
 +
| L3&nbsp;source&nbsp;address,
 +
original&nbsp;direction
 +
| ''src=192.168.0.2''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L3_source_or_destination_address|''ct&nbsp;original&nbsp;saddr'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 8
 +
| L3&nbsp;destination&nbsp;address,
 +
original&nbsp;direction
 +
| ''dst=192.168.0.8''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L3_source_or_destination_address|''ct&nbsp;original&nbsp;daddr'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 9
 +
| L4&nbsp;protocol&nbsp;source,
 +
original&nbsp;direction
 +
| ''sport=34621''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L4_protocol_source_or_destination|''ct&nbsp;original&nbsp;proto&#8209;src'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 10
 +
| L4&nbsp;protocol&nbsp;destination,
 +
original&nbsp;direction
 +
| ''dport=22''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L4_protocol_source_or_destination|''ct&nbsp;original&nbsp;proto&#8209;dst'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 11
 +
| L3&nbsp;source&nbsp;address,
 +
reply&nbsp;direction
 +
| ''src=192.168.0.8''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L3_source_or_destination_address|''ct&nbsp;reply&nbsp;saddr'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 12
 +
| L3&nbsp;destination&nbsp;address,
 +
reply&nbsp;direction
 +
| ''dst=192.168.0.2''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L3_source_or_destination_address|''ct&nbsp;reply&nbsp;daddr'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 13
 +
| L4&nbsp;protocol&nbsp;source,
 +
reply&nbsp;direction
 +
| ''sport=22''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L4_protocol_source_or_destination|''ct&nbsp;reply&nbsp;proto&#8209;src'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 14
 +
| L4&nbsp;protocol&nbsp;destination,
 +
reply&nbsp;direction
 +
| ''dport=34621''
 +
| [[Matching_connection_tracking_stateful_metainformation#Conntrack_L4_protocol_source_or_destination|''ct&nbsp;reply&nbsp;proto&#8209;dst'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 15
 +
| conntrack&nbsp;status
 +
| ''[ASSURED]''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_status_-_conntrack_status|''ct&nbsp;status'']]
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 16
 +
| conntrack&nbsp;mark
 +
| ''mark=6''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_mark_-_conntrack_mark|''ct&nbsp;mark'']]
 +
| [[Setting_packet_connection_tracking_metainformation#ct_mark_set_-_Set_conntrack_mark|Can also be set]].
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 17
 +
| reference count
 +
| ''use=1''
 +
|
 +
| Mainly used by the garbage collector.
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 18
 +
| conntrack&nbsp;id
 +
| ''id=2014938051''
 +
| [[Matching_connection_tracking_stateful_metainformation#ct_id|''ct id'']]
 +
| Unique id assigned to this conntrack entry.
 +
 
 +
|}
 +
 
 +
 
 +
== User-assigned metadata ==
 +
 
 +
* Conntrack ''mark'', ''label'' and ''zone'' are user-settable, and nftables can subsequently match packets against them.
 +
* In addition, ''notrack'', ''ct helper set'' and ''ct event set'' affect conntrack and nftables operation.
 +
Please see [[Setting_packet_connection_tracking_metainformation|Setting packet connection tracking metainformation]] for more information.
 +
 
 +
 
 +
= Matching conntrack metadata =
 +
 
 +
== ''ct state'' - conntrack state ==
 +
 
 +
The ''ct state'' expression is almost certainly the one you will use the most.
 +
 
 +
The  conntrack state may be one of:
 +
{| class="wikitable"
 +
!colspan="5"|conntrack states
 +
|- style="vertical-align:bottom;"
 +
! style="text-align:left;" | State
 +
! style="text-align:left;" | Description
 +
 
 +
|- style="vertical-align:top;"
 +
| ''new''
 +
| Netfilter has so far seen packets between this pair of hosts in only one direction. At least one of these packets is part of a valid initialization sequence, e.g. SYN packet for a TCP connection.
 +
 
 +
|- style="vertical-align:top;"
 +
| ''established''
 +
| Netfilter has seen valid packets travel in both directions between this pair of hosts. For TCP connections, the [https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_establishment three-way-handshake] has been successfully completed.
 +
 
 +
|- style="vertical-align:top;"
 +
| ''related''
 +
| This connection was initiated after the main connection, as expected from normal operation of the main connection. A common example is an [https://en.wikipedia.org/wiki/File_Transfer_Protocol FTP] data channel established at the behest of an FTP control channel.
 +
 
 +
|- style="vertical-align:top;"
 +
| ''invalid''
 +
| Assigned to packets that do not follow the expected behavior of a connection.
 +
 
 +
|- style="vertical-align:top;"
 +
| ''untracked''
 +
| Dummy state assigned to packets that have been explicitly excluded from conntrack. See [[Setting_packet_connection_tracking_metainformation|notrack]].
 +
 
 +
|}
 +
 
 +
The following example ruleset shows how to deploy an extremely simple stateful firewall with nftables:
 +
 
 +
<source>
 +
table inet stateful_fw_demo {
 +
 
 +
    chain IN {
 +
        type filter hook input priority filter; policy drop;
 +
 
 +
        ct state established,related accept
 +
}
 +
</source>
 +
 
 +
The rule in the ''IN'' chain accepts packets that are part of an established connection, and related packets. Note the use of a comma-separated list of the conntrack states that you want to match. The default chain policy drops all other incoming packets. Thus, any attempt from a computer in the network to initiate a new connection to your computer will be blocked. However, traffic that is part of a flow that you have started will be accepted.
 +
 
 +
 
 +
== ''ct helper'' - conntrack helper ==
 +
 
 +
The following example shows how to match packets based on the conntrack helper:
  
 
<source lang="bash">
 
<source lang="bash">
nft add rule filter input ct state established,related counter accept #1
+
nft add rule filter input ct helper "ftp" counter
nft add rule filter input counter drop #2
 
 
</source>
 
</source>
  
The rule #1 allows packets that are part of an already established communication with the network. Thus, any attempt from a computer in the network to reach your computer will be dropped. However, the traffic that is part of a flow that you have started will be accepted. Note that the example above uses a comma separated list of the states that you want to match.
+
[[Conntrack_helpers|More on using ct helpers]].
 +
 
 +
 
 +
== ''ct status'' - conntrack status ==
 +
 
 +
The conntrack status is a bitfield defined by enum ''ip_conntrack_status'' in [https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git/tree/include/uapi/linux/netfilter/nf_conntrack_common.h /include/uapi/linux/netfilter/nf_conntrack_common.h]. Nftables includes (in [http://git.netfilter.org/nftables/tree/src/ct.c /src/ct.c struct ''ct_status_tbl'']) symbolic named constants for the conntrack status bits that make sense for filtering, as per the following table:
 +
 
 +
{| class="wikitable"
 +
!colspan="5"|conntrack status bits
 +
|- style="vertical-align:bottom;"
 +
! style="text-align:right;" | Bit&nbsp;#
 +
! style="text-align:left;" | Kernel symbol
 +
! style="text-align:left;" | Nftables selector
 +
! style="text-align:left;" | Description
 +
! style="text-align:left;" | Notes
  
If you are not familiar with Netfilter flow state machine, you can give a quick read to this [https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#STATEMACHINE link].
+
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 0
 +
| IPS_EXPECTED
 +
| ''expected''
 +
| Set for expected connection.
 +
| Never changes.
  
== Matching the conntrack mark ==
+
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 1
 +
| IPS_SEEN_REPLY
 +
| ''seen-reply''
 +
| Set upon seeing packets in both original and reply directions.
 +
| Once set, never unset.
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 2
 +
| IPS_ASSURED
 +
| ''assured''
 +
| Set when this conntrack entry should never be early-expired.
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 3
 +
| IPS_CONFIRMED
 +
| ''confirmed''
 +
| Set when originating packet has left the local host.
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 4
 +
| IPS_SRC_NAT
 +
| ''snat''
 +
| Set when connection needs SNAT in original dirction.
 +
| Never changed.
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 5
 +
| IPS_DST_NAT
 +
| ''dnat''
 +
| Set when connection needs DNAT in original dirction.
 +
| Never changed.
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 6
 +
| IPS_SEQ_ADJUST
 +
|
 +
| Set when connection needs TCP sequence adjustment.
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 7
 +
| IPS_SRC_NAT_DONE
 +
|
 +
|
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 8
 +
| IPS_DST_NAT_DONE
 +
|
 +
|
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 9
 +
| IPS_DYING
 +
| ''dying''
 +
| Set when connection is dying (removed from lists).
 +
| Cannot be unset.
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 10
 +
| IPS_FIXED_TIMEOUT
 +
|
 +
| Set when connection has fixed timeout.
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 11
 +
| IPS_TEMPLATE
 +
|
 +
| Set when conntrack entry is a template.
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 12
 +
| IPS_UNTRACKED
 +
|
 +
| Obsolete, not used anymore.
 +
| Formerly: set when conntrack entry is untracked (fake).
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 13
 +
| IPS_HELPER
 +
|
 +
| Set when conntrack entry got a helper explicitly attached.
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 14
 +
| IPS_OFFLOAD
 +
|
 +
| Set when conntrack entry has been offloaded to a flow table.
 +
|
 +
 
 +
|- style="vertical-align:top;"
 +
| style="text-align:right;" | 15
 +
| IPS_HW_OFFLOAD
 +
|
 +
| Set when conntrack entry has been offloaded to hardware.
 +
|
 +
 
 +
|}
 +
 
 +
Match single flag: ''ct status snat''
 +
 
 +
Match multiple flags: ''ct status {expected,dnat}''
 +
 
 +
Match inverted flag: ''(ct status & dnat) != dnat'' (See [https://marc.info/?l=netfilter&m=160270456112307&w=2 cannot use != with ct status].)
 +
 
 +
 
 +
== ''ct mark'' - conntrack mark ==
  
 
The following example shows how to match packets based on the conntrack mark:
 
The following example shows how to match packets based on the conntrack mark:
Line 30: Line 378:
 
To know more about conntrack marks and packet marks, see [[Setting packet metainformation]].
 
To know more about conntrack marks and packet marks, see [[Setting packet metainformation]].
  
== Matching the conntrack helper ==
 
  
The following example shows how to match packets based on the conntrack helper:
+
== ''ct label'' ==
 +
 
 +
If a [[Setting_packet_connection_tracking_metainformation#ct_label_set_-_Set_conntrack_label|conntrack label has been applied to a packet]], you can match such packets with this expression.
 +
 
 +
 
 +
== ''ct zone'' ==
 +
 
 +
Similar to ''ct label'', if a [[Setting_packet_connection_tracking_metainformation#ct_zone_set_-_Set_conntrack_zone|conntrack zone has been assigned to a packet]], you can then match such packets using this expression. You can optionally include a packet direction with this match: ''ct'' [''original'' | ''reply''] ''zone'' zone.
 +
 
 +
 
 +
== ''ct direction'' ==
 +
 
 +
A packet with ''original'' direction is traveling in the same direction as the first packet seen for this connection, e.g. in the direction of the original SYN packet for a TCP connection. A packet with ''reply'' direction is traveling in the direction opposite to ''original''.
 +
 
 +
 
 +
== ''ct expiration'' ==
 +
 
 +
You can match packets based on when their associated connection is set to expire, e.g. ''ct expiration < 1m30s''.
 +
 
 +
 
 +
== ''ct count'' ==
 +
 
 +
You can match based on the current number of tracked connections matching the specified properties. See [[Connlimits|connlimits]].
 +
 
 +
 
 +
== ''ct packets'' ==
 +
 
 +
Match based on how many packets have previously traversed the connection associated with a packet. If you specify an optional direction, only packets in that direction are counted. Otherwise, packets in both directions are counted. For example:<br>
 +
''ct'' [''original'' | ''reply''] packets < 10000
 +
 
 +
 
 +
== ''ct bytes'' ==
 +
 
 +
Match based on how many total bytes have previously traversed the connection associated with a packet. If you specify an optional direction, only traffic in that direction is counted. Otherwise, traffic in both directions is counted. For example:<br>
 +
''ct'' [''original'' | ''reply''] bytes < 100000
 +
 
 +
 
 +
== ''ct avgpkt'' ==
 +
 
 +
Match based on the average packet size (bytes/packet) seen so far on the connection associated with a packet. If you specify an optional direction, only traffic in that direction is counted. Otherwise, traffic in both directions is counted. For example:<br>
 +
''ct'' [''original'' | ''reply''] avgpkt < 100
 +
 
 +
 
 +
== ''ct l3proto'' - conntrack L3 protocol ==
 +
 
 +
Matches the L3 protocol of the conntrack entry associated with a packet. You can optionally include a packet direction with this match:<br>
 +
''ct'' [''original'' | ''reply''] ''l3proto'' l3_protocol.
 +
 
 +
 
 +
== Conntrack L3 source or destination address ==
 +
 
 +
This match requires specifying both direction and L3 protocol (''ip'' or ''ip6'' currently recognized):<br>
 +
''ct'' {''original'' | ''reply''} {''ip'' | ''ip6''} {''saddr'' | ''daddr''}
 +
 
 +
 
 +
== ''ct protocol''- conntrack L4 protocol ==
 +
 
 +
Matches the L4 protocol of the conntrack entry associated with a packet. You can optionally include a packet direction with this match:<br>
 +
''ct'' [''original'' | ''reply''] ''protocol'' l4_protocol.
 +
 
 +
 
 +
== Conntrack L4 protocol source or destination ==
 +
 
 +
This match requires specifying the direction:<br>
 +
''ct'' {''original'' | ''reply''} {''proto-src'' | ''proto-dst''}
 +
 
 +
 
 +
== ''ct id'' ==
  
<source lang="bash">
+
This expression will match packets associated with a specific connection with given conntrack id (as from ''conntrack -L -o id''). You can optionally include a packet direction with this match: ''ct'' [''original'' | ''reply''] ''id'' ct_id.
nft add rule filter input ct helper "ftp" counter
 
</source>
 

Latest revision as of 20:55, 15 April 2021

nftables conntrack (ct) expressions enable stateful firewalls by matching packets that correspond to connections tracked by netfilter's Connection Tracking System.

Conntrack metadata available

It is useful to refer to the conntrack data types.


Conntrack-assigned metadata

Conntrack itself maintains most of its metadata for each tracked connection. The conntrack command-line tool makes it easy to list these metadata as well as manage the connections. Following is a sample partial output, run on a host serving an active sshd session. The id option includes the unique conntrack id in the output; the extended option produces the listing in /proc/net/nf_conntrack format.

% conntrack -L -o id,extended
...
ipv4     2 tcp      6 421957 ESTABLISHED src=192.168.0.2 dst=192.168.0.8 sport=34621 dport=22 src=192.168.0.8 dst=192.168.0.2 sport=22 dport=34621 [ASSURED] mark=6 use=1 id=2014938051
...

The following table lists each conntrack metadata field in the above output along with the nftables ct selector to match it.

conntrack command output
Column # Description Example value ct Match Notes
1 L3 protocol name ipv4 ct l3proto
2 L3 protocol number 2 ct l3proto
3 L4 protocol name tcp ct protocol
4 L4 protocol number 6 ct protocol As shown in in.h protocol value 6 indicates TCP.
5 timeout, s 421957 ct expiration Seconds until conntrack entry is invalidated; reset to initial value when connection sees a new packet.

Default TCP connection timeout is 5 days. You can change this via the conntrack sysfs setting nf_conntrack_tcp_timeout_established.

6 conntrack state ESTABLISHED ct state
7 L3 source address,

original direction

src=192.168.0.2 ct original saddr
8 L3 destination address,

original direction

dst=192.168.0.8 ct original daddr
9 L4 protocol source,

original direction

sport=34621 ct original proto‑src
10 L4 protocol destination,

original direction

dport=22 ct original proto‑dst
11 L3 source address,

reply direction

src=192.168.0.8 ct reply saddr
12 L3 destination address,

reply direction

dst=192.168.0.2 ct reply daddr
13 L4 protocol source,

reply direction

sport=22 ct reply proto‑src
14 L4 protocol destination,

reply direction

dport=34621 ct reply proto‑dst
15 conntrack status [ASSURED] ct status
16 conntrack mark mark=6 ct mark Can also be set.
17 reference count use=1 Mainly used by the garbage collector.
18 conntrack id id=2014938051 ct id Unique id assigned to this conntrack entry.


User-assigned metadata

  • Conntrack mark, label and zone are user-settable, and nftables can subsequently match packets against them.
  • In addition, notrack, ct helper set and ct event set affect conntrack and nftables operation.

Please see Setting packet connection tracking metainformation for more information.


Matching conntrack metadata

ct state - conntrack state

The ct state expression is almost certainly the one you will use the most.

The conntrack state may be one of:

conntrack states
State Description
new Netfilter has so far seen packets between this pair of hosts in only one direction. At least one of these packets is part of a valid initialization sequence, e.g. SYN packet for a TCP connection.
established Netfilter has seen valid packets travel in both directions between this pair of hosts. For TCP connections, the three-way-handshake has been successfully completed.
related This connection was initiated after the main connection, as expected from normal operation of the main connection. A common example is an FTP data channel established at the behest of an FTP control channel.
invalid Assigned to packets that do not follow the expected behavior of a connection.
untracked Dummy state assigned to packets that have been explicitly excluded from conntrack. See notrack.

The following example ruleset shows how to deploy an extremely simple stateful firewall with nftables:

table inet stateful_fw_demo {

    chain IN {
        type filter hook input priority filter; policy drop;

        ct state established,related accept
}

The rule in the IN chain accepts packets that are part of an established connection, and related packets. Note the use of a comma-separated list of the conntrack states that you want to match. The default chain policy drops all other incoming packets. Thus, any attempt from a computer in the network to initiate a new connection to your computer will be blocked. However, traffic that is part of a flow that you have started will be accepted.


ct helper - conntrack helper

The following example shows how to match packets based on the conntrack helper:

nft add rule filter input ct helper "ftp" counter

More on using ct helpers.


ct status - conntrack status

The conntrack status is a bitfield defined by enum ip_conntrack_status in /include/uapi/linux/netfilter/nf_conntrack_common.h. Nftables includes (in /src/ct.c struct ct_status_tbl) symbolic named constants for the conntrack status bits that make sense for filtering, as per the following table:

conntrack status bits
Bit # Kernel symbol Nftables selector Description Notes
0 IPS_EXPECTED expected Set for expected connection. Never changes.
1 IPS_SEEN_REPLY seen-reply Set upon seeing packets in both original and reply directions. Once set, never unset.
2 IPS_ASSURED assured Set when this conntrack entry should never be early-expired.
3 IPS_CONFIRMED confirmed Set when originating packet has left the local host.
4 IPS_SRC_NAT snat Set when connection needs SNAT in original dirction. Never changed.
5 IPS_DST_NAT dnat Set when connection needs DNAT in original dirction. Never changed.
6 IPS_SEQ_ADJUST Set when connection needs TCP sequence adjustment.
7 IPS_SRC_NAT_DONE
8 IPS_DST_NAT_DONE
9 IPS_DYING dying Set when connection is dying (removed from lists). Cannot be unset.
10 IPS_FIXED_TIMEOUT Set when connection has fixed timeout.
11 IPS_TEMPLATE Set when conntrack entry is a template.
12 IPS_UNTRACKED Obsolete, not used anymore. Formerly: set when conntrack entry is untracked (fake).
13 IPS_HELPER Set when conntrack entry got a helper explicitly attached.
14 IPS_OFFLOAD Set when conntrack entry has been offloaded to a flow table.
15 IPS_HW_OFFLOAD Set when conntrack entry has been offloaded to hardware.

Match single flag: ct status snat

Match multiple flags: ct status {expected,dnat}

Match inverted flag: (ct status & dnat) != dnat (See cannot use != with ct status.)


ct mark - conntrack mark

The following example shows how to match packets based on the conntrack mark:

nft add rule filter input ct mark 123 counter

To know more about conntrack marks and packet marks, see Setting packet metainformation.


ct label

If a conntrack label has been applied to a packet, you can match such packets with this expression.


ct zone

Similar to ct label, if a conntrack zone has been assigned to a packet, you can then match such packets using this expression. You can optionally include a packet direction with this match: ct [original | reply] zone zone.


ct direction

A packet with original direction is traveling in the same direction as the first packet seen for this connection, e.g. in the direction of the original SYN packet for a TCP connection. A packet with reply direction is traveling in the direction opposite to original.


ct expiration

You can match packets based on when their associated connection is set to expire, e.g. ct expiration < 1m30s.


ct count

You can match based on the current number of tracked connections matching the specified properties. See connlimits.


ct packets

Match based on how many packets have previously traversed the connection associated with a packet. If you specify an optional direction, only packets in that direction are counted. Otherwise, packets in both directions are counted. For example:
ct [original | reply] packets < 10000


ct bytes

Match based on how many total bytes have previously traversed the connection associated with a packet. If you specify an optional direction, only traffic in that direction is counted. Otherwise, traffic in both directions is counted. For example:
ct [original | reply] bytes < 100000


ct avgpkt

Match based on the average packet size (bytes/packet) seen so far on the connection associated with a packet. If you specify an optional direction, only traffic in that direction is counted. Otherwise, traffic in both directions is counted. For example:
ct [original | reply] avgpkt < 100


ct l3proto - conntrack L3 protocol

Matches the L3 protocol of the conntrack entry associated with a packet. You can optionally include a packet direction with this match:
ct [original | reply] l3proto l3_protocol.


Conntrack L3 source or destination address

This match requires specifying both direction and L3 protocol (ip or ip6 currently recognized):
ct {original | reply} {ip | ip6} {saddr | daddr}


ct protocol- conntrack L4 protocol

Matches the L4 protocol of the conntrack entry associated with a packet. You can optionally include a packet direction with this match:
ct [original | reply] protocol l4_protocol.


Conntrack L4 protocol source or destination

This match requires specifying the direction:
ct {original | reply} {proto-src | proto-dst}


ct id

This expression will match packets associated with a specific connection with given conntrack id (as from conntrack -L -o id). You can optionally include a packet direction with this match: ct [original | reply] id ct_id.