Matching packet headers: Difference between revisions
(Link references to ethernet, EtherType, L2.) |
(Added section: Matching ARP headers) |
||
Line 22: | Line 22: | ||
Do not forget that the [https://en.wikipedia.org/wiki/Link_layer layer 2] header information is only available in the input path. | Do not forget that the [https://en.wikipedia.org/wiki/Link_layer layer 2] header information is only available in the input path. | ||
= Matching ARP headers = | |||
You can match [https://en.wikipedia.org/wiki/Address_Resolution_Protocol ARP] headers: | |||
* ''arp htype'' «[[Data_types#ARP_types|16-bit integer HTYPE]]» | |||
* ''arp ptype'' «[[Data_types#Ethernet_types|ether_type]]» | |||
* ''arp hlen'' «[[Data_types#ARP_types|8-bit integer HLEN]]» | |||
* ''arp plen'' «[[Data_types#ARP_types|8-bit integer PLEN]]» | |||
* ''arp operation'' «[[Data_types#ARP_types|arp_op]]» | |||
* ''arp'' {''saddr'' | ''daddr ''} ''ether'' «[[Data_types#Ethernet_types|ether_addr]]» | |||
* ''arp'' {''saddr'' | ''daddr ''} ''ip'' «[[Data_types#IP_types|ipv4_addr]]» | |||
Revision as of 15:28, 20 April 2021
The nft command line utility supports the following layer 4 protocols: AH, ESP, UDP, UDPlite, TCP, DCCP, SCTP and IPComp.
Matching ethernet headers
You can match packets on ethernet source or destination address or on EtherType:
- ether {saddr | daddr} «ether_addr»
- ether type «ether_type»
If you want to match ethernet traffic whose destination address is ff:ff:ff:ff:ff:ff, you can type the following command:
% nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter
You can also match packets on IEEE 802.1Q VLAN fields, if present:
- vlan type «ether_type» - always vlan for 802.1Q
- vlan id «12-bit integer» - match VID, the VLAN ID
- vlan cfi «1-bit integer» - match DEI, Drop Eligible Indicator (formerly CFI, Canonical Format Indicator)
- vlan pcp «3-bit integer» - match IEEE P802.1p PCP, Priority Code Point
Do not forget that the layer 2 header information is only available in the input path.
Matching ARP headers
You can match ARP headers:
- arp htype «16-bit integer HTYPE»
- arp ptype «ether_type»
- arp hlen «8-bit integer HLEN»
- arp plen «8-bit integer PLEN»
- arp operation «arp_op»
- arp {saddr | daddr } ether «ether_addr»
- arp {saddr | daddr } ip «ipv4_addr»
Matching transport protocol
The following rule shows how to match any kind of TCP traffic:
% nft add rule filter output ip protocol tcp
Matching IPv4 headers
You can also match traffic based on the IPv4 source and destination, the following example shows how to account all traffic that comes from 192.168.1.100 and that is addressed to 192.168.1.1:
% nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter
Note that, since the rule is attached to the input chain, your local machine needs to use the 192.168.1.1 address, otherwise you won't see any matching ;-).
To filter on a layer 4 protocol like TCP, you can use the protocol keyword:
% nft add rule filter input protocol tcp counter
Matching IPv6 headers
If you want to account IPv6 traffic that is addressed to abcd::100, you can type the following command:
% nft add rule filter output ip6 daddr abcd::100 counter
To filter on a layer 4 protocol like TCP, you can use the nexthdr keyword:
% nft add rule filter input ip6 nexthdr tcp counter
Do not forget to create an ip6 table and register the corresponding chains to run the examples.
NOTE: the syntax mixing IPv6/IPv4 notation is not supported yet: '::ffff:192.168.1.0'
Matching TCP/UDP/UDPlite traffic
The following examples show how to drop all tcp traffic for low TCP ports (1-1024):
% nft add rule filter input tcp dport 1-1024 counter drop
Note that this rule is using an interval (from 1 to 1024).
To match on TCP flags, you need to use a binary operation. For example, to count packets that are not SYN ones:
% nft add rule filter input tcp flags != syn counter
More complex filters can be used. For example, to count and log TCP packets with flags SYN and ACK set:
% nft -i
nft> add rule filter output tcp flags & (syn | ack) == syn | ack counter log
This example drops TCP SYN packets which a MSS lower than 500:
% nft add rule inet filter input tcp flags syn tcp option maxseg size 1-500 drop
Matching ICMP traffic
You can drop all ICMP echo requests (popularly known as pings) via:
% nft add rule filter input icmp type echo-request counter drop
You can use nft describe to find nft's available icmp type keywords:
% nft describe icmp type
payload expression, datatype icmp_type (ICMP type) (basetype integer), 8 bits
pre-defined symbolic constants (in decimal):
echo-reply 0
destination-unreachable 3
source-quench 4
redirect 5
echo-request 8
router-advertisement 9
router-solicitation 10
time-exceeded 11
parameter-problem 12
timestamp-request 13
timestamp-reply 14
info-request 15
info-reply 16
address-mask-request 17
address-mask-reply 18
You can also be more specific by matching a single icmp code:
% nft describe icmp code
payload expression, datatype icmp_code (icmp code) (basetype integer), 8 bits
pre-defined symbolic constants (in decimal):
net-unreachable 0
host-unreachable 1
prot-unreachable 2
port-unreachable 3
net-prohibited 9
host-prohibited 10
admin-prohibited 13
frag-needed 4
% nft add rule filter output icmp code frag-needed counter accept
Matching UDP/TCP headers in the same rule
The following example uses an anonymous l4proto set and a th (transport header) expression to match both TCP and UDP packets directed to port 53 (DNS):
% nft add rule filter input meta l4proto { tcp, udp } th dport 53 counter packets 0 bytes 0 accept comment \"accept DNS\"
Note: Before nftables 0.9.2 and Linux kernel 5.3 the th expression is not available. In this case you can use a raw payload expression to do the same job:
% nft add rule filter input meta l4proto { tcp, udp } @th,16,16 53 counter packets 0 bytes 0 accept comment \"accept DNS\"