Matching packet metainformation: Difference between revisions

From nftables wiki
Jump to navigation Jump to search
(→‎The meta selectors: Put meta selectors into a table)
m (list pkttype options)
 
(32 intermediate revisions by one other user not shown)
Line 1: Line 1:
The meta selectors allows you to match ([[Setting_packet_metainformation |and in some cases, set]]) packet metainformation.
The meta selectors allows you to match -- [[Setting_packet_metainformation |and in some cases, set]] -- packet metainformation. That is, information the local host has about the packet (such as how / when it was received) that is not necessarily carried in the packet itself.


= The meta selectors =
= Matching by packet info =


The following meta selectors match -- and in some cases set -- packet metainformation:
The following ''meta'' selectors match packets by information carried by the packet itself:


{| class="wikitable"
{| class="wikitable"
!colspan="4"|Meta Selectors
!colspan="5"|''meta'' Packet Info Selectors
|- style="vertical-align:bottom;"
|- style="vertical-align:bottom;"
! Keyword
! Keyword
! [[Setting_packet_metainformation |Settable]]
! [[Setting_packet_metainformation |Settable]]
! style="text-align:left;" | Description
! style="text-align:left;" | Description
! style="text-align:left;" | [[Data_types|Data Type]]
! style="text-align:left;" | Notes
! style="text-align:left;" | Notes


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''mark''
| ''pkttype''
| [[Setting_packet_metainformation |Y]]
| [[Setting_packet_metainformation |Y]]
| packet mark
| packet type (''unicast'', ''broadcast'', ''multicast'', ''other'')
| pkt_type
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''iif''
| ''length''
|
|
| input interface index
| packet length in bytes
| integer (32 bit)
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''iifname''
| ''protocol''
|
| input interface name
|
|
| packet protocol / EtherType protocol value
| ether_type
| as in skb->protocol


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''iiftype''
| ''nfproto''
|
| input interface type
|
|
| netfilter packet protocol family
| integer (32 bit)
| like ipv4, ipv6, etc...; useful only in inet table


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''oif''
| ''l4proto''
|
| output interface index
|
|
| layer 4 protocol
| integer (8 bit)
| like tcp, udp, etc...; skips ipv6 extension headers


|- style="vertical-align:top;"
|}
| ''oifname''
|
| output interface name
|


|- style="vertical-align:top;"
= Matching by interface =
| ''oiftype''
|
| output interface type
|


|- style="vertical-align:top;"
The following ''meta'' selectors match packets based on incoming or outgoing interfaces:
| ''skuid''
|
| socket uid
|


|- style="vertical-align:top;"
{| class="wikitable"
| ''skgid''
!colspan="5"|''meta'' Interface Selectors
|
|- style="vertical-align:bottom;"
| socket gid
! Keyword
|
! [[Setting_packet_metainformation |Settable]]
! style="text-align:left;" | Description
! style="text-align:left;" | [[Data_types|Data Type]]
! style="text-align:left;" | Notes


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''nftrace''
| ''iif''
| [[Setting_packet_metainformation |Y]]
| [[Ruleset_debug/tracing|nftrace debugging]] bit
|
|
| input interface index
| iface_index
| Faster than ''iifname'' as it only has to compare a 32-bit unsigned integer instead of a string.
The interface index is dynamically allocated, so don't use this for interfaces that are dynamically created and destroyed, eg. ''ppp0''.


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''rtclassid''
| ''iifname''
|
|
| realm
| input interface name
| ifname
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''ibriport''
| ''iiftype''
|
|
| input bridge port
| input interface type
| iface_type
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''obriport''
| ''iifkind''
|
|
| output bridge port
| input interface kind name
| ifkind
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''ibrname''
| ''iifgroup''
|
|
| input bridge name
| input interface group
| devgroup
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''obrname''
| ''oif''
|
| output bridge name
|
|
| output interface index
| iface_index
| Faster than ''oifname'' as it only has to compare a 32-bit unsigned integer instead of a string.
The interface index is dynamically allocated, so don't use this for interfaces that are dynamically created and destroyed, eg. ''ppp0''.


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''pkttype''
| ''oifname''
| [[Setting_packet_metainformation |Y]]
|
| packet type
| output interface name
| ifname
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''cpu''
| ''oiftype''
|
|
| cpu number
| output interface type
| iface_type
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''iifgroup''
| ''oifkind''
|
|
| input interface group
| output interface kind name
| ifkind
|
|


Line 125: Line 133:
|
|
| output interface group
| output interface group
| devgroup
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''cgroup''
| ''ibrname''
|
| cgroup number
|
|
| input bridge interface name
| ifname
| equivalent to obsolete ''ibriport'' keyword


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''ipsec''
| ''obrname''
|
| ipsec (secpath) packet or not
|
|
| output bridge interface name
| ifname
|equivalent to obsolete ''oibriport'' keyword


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''time''
| ''ibrvproto''
|
| packet timestamp
|
|
| input bridge vlan protocol
| ether_type
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''day''
| ''ibrpvid''
|
| packet timestamp
|
|
| input bridge port pvid
| integer (16 bit)
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''hour''
| ''sdif''
|
|  
| packet timestamp
| slave device interface index
|
| integer
|  


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''length''
| ''sdifname''
|
| packet length
|
|
| slave device interface name
| ifname
|


|- style="vertical-align:top;"
|}
| ''protocol''
|
| packet protocol
| as in skb->protocol


|- style="vertical-align:top;"
An example rule that uses ''iifname'' to accept all traffic entering the loopback pseudodevice ''lo'':
| ''nfproto''
|
| netfilter packet protocol family
| like ipv4, ipv6, etc...


|- style="vertical-align:top;"
<source lang="bash">
| ''l4proto''
% nft add rule filter input meta iifname lo accept
|
</source>
| layer 4 protocol
| like tcp, udp, etc...


|- style="vertical-align:top;"
= Matching by packet mark, routing class and realm =
| ''priority''
| [[Setting_packet_metainformation |Y]]
| packet priority, tc handle
|


|- style="vertical-align:top;"
{| class="wikitable"
| ''random''
!colspan="5"|''meta'' Packet Mark & Routing Selectors
|
|- style="vertical-align:bottom;"
| match against a single / simple random number
! Keyword
|  
! [[Setting_packet_metainformation |Settable]]
! style="text-align:left;" | Description
! style="text-align:left;" | [[Data_types|Data Type]]
! style="text-align:left;" | Notes


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''secmark''
| ''mark''
| [[Setting_packet_metainformation |Y]]
| [[Setting_packet_metainformation |Y]]
| packet secmark
| packet mark
| mark
|
|


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''ibrvproto''
| ''priority''
|
| [[Setting_packet_metainformation |Y]]
| bridge protocol
| tc packet priority
|  
| tc_handle
| [[Classification_to_tc_structure_example |detailed usage example]]


|- style="vertical-align:top;"
|- style="vertical-align:top;"
| ''ibrpvid''
| ''rtclassid''
|
|
| bridge pvid
| routing realm
|  
| realm
| Routing realm references:
<ul>
<li>[http://linux-ip.net/gl/ip-cref/ip-cref-node172.html linux-ip.net]
<li>[http://www.policyrouting.org/PolicyRoutingBook/ONLINE/CH07.web.html policyrouting.org]
</ul>


|}
|}


= Matching packets by interface name =
You can match packets whose mark is 123 with the following rule:


You can use one of the following selectors to match the interface name:
<source lang="bash">
nft add rule filter output meta mark 123 counter
</source>


* ''iifname'', to match the input network interface name.
* Since nftables v0.7 you can match the packet priority, the tc classid:
* ''oifname'', to match the output network interface name.
* ''iif'', to match the interface index of the network interface name. This is faster than ''iifname'' as it only has to compare a 32-bits unsigned integer instead of a string. The interface index is dynamically allocated, so don't use this for interfaces that are dynamically created and destroyed, eg. ''ppp0''.
* ''oif'', like ''iif'' but it matches the output network interface index.


An example usage of the interface name is the following:
<source>
% nft add rule filter forward meta priority abcd:1234
</source>


<source lang="bash">
* Packet without set priority can be matched using meta priority none
% nft add rule filter input meta oifname lo accept
<source>
% nft add rule filter forward meta priority none
</source>
</source>


This rule accepts all traffic for the loopback pseudodevice ''lo''.
See also: [[Matching routing information|''nexthop'' and ''fib'' selectors]]
 
 
= Matching by socket UID / GID =


= Matching packets by packet mark =
{| class="wikitable"
!colspan="5"|''meta'' UID / GID Selectors
|- style="vertical-align:bottom;"
! Keyword
! [[Setting_packet_metainformation |Settable]]
! style="text-align:left;" | Description
! style="text-align:left;" | [[Data_types|Data Type]]
! style="text-align:left;" | Notes


You can match packets whose mark is 123 with the following rule:
|- style="vertical-align:top;"
| ''skuid''
|
| UID associated with originating socket
| uid
|


<source lang="bash">
|- style="vertical-align:top;"
nft add rule filter output meta mark 123 counter
| ''skgid''
</source>
|
| GID associated with originating socket
| gid
|


= Matching packets the socket UID =
|}


You can use your user name to match traffic, eg.
You can use your user name to match traffic, eg.
Line 276: Line 307:
'''Important''': Beware if you test this with ''ping'', it is usually installed with suid so that traffic will match the root user (uid=0).
'''Important''': Beware if you test this with ''ping'', it is usually installed with suid so that traffic will match the root user (uid=0).


= Matching packet priority =


* Since nftables v0.7 you can match the packet priority, the tc classid:
= Matching by time =
 
{| class="wikitable"
!colspan="5"|''meta'' Time Selectors
|- style="vertical-align:bottom;"
! Keyword
! [[Setting_packet_metainformation |Settable]]
! style="text-align:left;" | Description
! style="text-align:left;" | [[Data_types|Data Type]]
! style="text-align:left;" | Notes
 
|- style="vertical-align:top;"
| ''time''
|
| timestamp of packet reception
| time
| Can specify as:
* integer: ns since epoch, or
* string: date in ISO format.
 
|- style="vertical-align:top;"
| ''day''
|
| day of week
| day
| Can specify as:
* integer: 0 = Sunday to 6 = Saturday, or
* case-insensitive string: "Monday", "tuesday", etc. Unique abbreviations also work: "fri", "Sat".
 
|- style="vertical-align:top;"
| ''hour''
|
| hour of day
| hour
| 24-hour "HH:MM:SS", with seconds optional.
 
|}
 
 
= Matching by security selectors =
 
{| class="wikitable"
!colspan="5"|''meta'' Security Selectors
|- style="vertical-align:bottom;"
! Keyword
! [[Setting_packet_metainformation |Settable]]
! style="text-align:left;" | Description
! style="text-align:left;" | [[Data_types|Data Type]]
! style="text-align:left;" | Notes
 
|- style="vertical-align:top;"
| ''cpu''
|
| CPU number processing the packet
| integer (32 bit)
|
 
|- style="vertical-align:top;"
| ''cgroup''
|
| socket control group ID
| integer (32 bit)
|
 
|- style="vertical-align:top;"
| ''secmark''
| [[Setting_packet_metainformation |Y]]
| packet secmark
| integer (32 bit)
|
 
|- style="vertical-align:top;"
| ''ipsec''
|
| true if packet was ipsec encrypted
| boolean (1 bit)
| equivalent to obsolete ''secpath'' keyword
 
|}
 
 
= Matching by miscellaneous selectors =
 
In addition to those in the above subsections, the following miscellaneous meta selectors are available:
 
{| class="wikitable"
!colspan="5"|''meta'' Miscellaneous Selectors
|- style="vertical-align:bottom;"
! Keyword
! [[Setting_packet_metainformation |Settable]]
! style="text-align:left;" | Description
! style="text-align:left;" | [[Data_types|Data Type]]
! style="text-align:left;" | Notes
 
|- style="vertical-align:top;"
| ''nftrace''
| [[Setting_packet_metainformation |Y]]
| [[Ruleset_debug/tracing|nftrace debugging]] bit
| boolean (1 bit)
|


<source>
|- style="vertical-align:top;"
% nft add rule filter forward meta priority abcd:1234
| ''random''
</source>
|
| pseudo-random number
| integer (32 bit)
|


* Packet without set priority can be matched using meta priority none
|}
<source>
% nft add rule filter forward meta priority none
</source>

Latest revision as of 15:33, 28 March 2024

The meta selectors allows you to match -- and in some cases, set -- packet metainformation. That is, information the local host has about the packet (such as how / when it was received) that is not necessarily carried in the packet itself.

Matching by packet info

The following meta selectors match packets by information carried by the packet itself:

meta Packet Info Selectors
Keyword Settable Description Data Type Notes
pkttype Y packet type (unicast, broadcast, multicast, other) pkt_type
length packet length in bytes integer (32 bit)
protocol packet protocol / EtherType protocol value ether_type as in skb->protocol
nfproto netfilter packet protocol family integer (32 bit) like ipv4, ipv6, etc...; useful only in inet table
l4proto layer 4 protocol integer (8 bit) like tcp, udp, etc...; skips ipv6 extension headers

Matching by interface

The following meta selectors match packets based on incoming or outgoing interfaces:

meta Interface Selectors
Keyword Settable Description Data Type Notes
iif input interface index iface_index Faster than iifname as it only has to compare a 32-bit unsigned integer instead of a string.

The interface index is dynamically allocated, so don't use this for interfaces that are dynamically created and destroyed, eg. ppp0.

iifname input interface name ifname
iiftype input interface type iface_type
iifkind input interface kind name ifkind
iifgroup input interface group devgroup
oif output interface index iface_index Faster than oifname as it only has to compare a 32-bit unsigned integer instead of a string.

The interface index is dynamically allocated, so don't use this for interfaces that are dynamically created and destroyed, eg. ppp0.

oifname output interface name ifname
oiftype output interface type iface_type
oifkind output interface kind name ifkind
oifgroup output interface group devgroup
ibrname input bridge interface name ifname equivalent to obsolete ibriport keyword
obrname output bridge interface name ifname equivalent to obsolete oibriport keyword
ibrvproto input bridge vlan protocol ether_type
ibrpvid input bridge port pvid integer (16 bit)
sdif slave device interface index integer
sdifname slave device interface name ifname

An example rule that uses iifname to accept all traffic entering the loopback pseudodevice lo:

% nft add rule filter input meta iifname lo accept

Matching by packet mark, routing class and realm

meta Packet Mark & Routing Selectors
Keyword Settable Description Data Type Notes
mark Y packet mark mark
priority Y tc packet priority tc_handle detailed usage example
rtclassid routing realm realm Routing realm references:

You can match packets whose mark is 123 with the following rule:

nft add rule filter output meta mark 123 counter
  • Since nftables v0.7 you can match the packet priority, the tc classid:
% nft add rule filter forward meta priority abcd:1234
  • Packet without set priority can be matched using meta priority none
% nft add rule filter forward meta priority none

See also: nexthop and fib selectors


Matching by socket UID / GID

meta UID / GID Selectors
Keyword Settable Description Data Type Notes
skuid UID associated with originating socket uid
skgid GID associated with originating socket gid

You can use your user name to match traffic, eg.

% nft add rule filter output meta skuid pablo counter

Or the 32-bits unsigned integer (UID) in case there is no entry in /etc/passwd for a given user.

% nft add rule filter output meta skuid 1000 counter

Let's just generate some HTTP traffic to test this rule:

% wget --spider http://www.google.com

Then, if you check the counters, you can verify that the packets are matching that rule.

% nft list table filter
table ip filter {
        chain output {
                 type filter hook output priority 0;
                 skuid pablo counter packets 7 bytes 510
        }

        chain input {
                 type filter hook input priority 0;
        }
}

Important: Beware if you test this with ping, it is usually installed with suid so that traffic will match the root user (uid=0).


Matching by time

meta Time Selectors
Keyword Settable Description Data Type Notes
time timestamp of packet reception time Can specify as:
  • integer: ns since epoch, or
  • string: date in ISO format.
day day of week day Can specify as:
  • integer: 0 = Sunday to 6 = Saturday, or
  • case-insensitive string: "Monday", "tuesday", etc. Unique abbreviations also work: "fri", "Sat".
hour hour of day hour 24-hour "HH:MM:SS", with seconds optional.


Matching by security selectors

meta Security Selectors
Keyword Settable Description Data Type Notes
cpu CPU number processing the packet integer (32 bit)
cgroup socket control group ID integer (32 bit)
secmark Y packet secmark integer (32 bit)
ipsec true if packet was ipsec encrypted boolean (1 bit) equivalent to obsolete secpath keyword


Matching by miscellaneous selectors

In addition to those in the above subsections, the following miscellaneous meta selectors are available:

meta Miscellaneous Selectors
Keyword Settable Description Data Type Notes
nftrace Y nftrace debugging bit boolean (1 bit)
random pseudo-random number integer (32 bit)