Quick reference-nftables in 10 minutes: Difference between revisions
(Created page with "Find below some basic concepts to know before using nftables. '''table''' refers to a container of chains with no specific semantics. '''chain''' with...") |
m (→Rules: Clarify the explanation about the inserted rule position.) |
||
(34 intermediate revisions by 10 users not shown) | |||
Line 3: | Line 3: | ||
'''table''' refers to a container of [[Configuring chains|chains]] with no specific semantics. | '''table''' refers to a container of [[Configuring chains|chains]] with no specific semantics. | ||
'''chain''' within a [[Configuring tables|table]] refers to a container of [[ | '''chain''' within a [[Configuring tables|table]] refers to a container of [[Simple rule management|rules]]. | ||
'''rule''' refers to an action to be configured within a ''chain''. | '''rule''' refers to an action to be configured within a ''chain''. | ||
Line 14: | Line 14: | ||
== Tables == | == Tables == | ||
'''family''' refers to a one of the following table types: ''ip'', ''arp'', ''ip6'', ''bridge'', ''inet'', ''netdev''. | '''family''' refers to a one of the following table types: ''ip'', ''arp'', ''ip6'', ''bridge'', ''inet'', ''netdev''. It defaults to ''ip''. | ||
<source lang="bash"> | <source lang="bash"> | ||
% nft list tables [<family>] | % nft list tables [<family>] | ||
% nft list table [<family>] <name> | % nft [-n] [-a] list table [<family>] <name> | ||
% nft (add | delete | flush) table [<family>] <name> | % nft (add | delete | flush) table [<family>] <name> | ||
</source> | </source> | ||
The argument ''-n'' shows the addresses and other information that | The argument ''-n'' shows the addresses and other information that use names in numeric format. The ''-a'' argument is used to display each rule's ''handle'' (i.e., a numerical identifier). | ||
== Chains == | == Chains == | ||
Line 37: | Line 37: | ||
* The hooks for ''arp'' family are: '' input'', ''output''. | * The hooks for ''arp'' family are: '' input'', ''output''. | ||
* The ''bridge'' family handles ethernet packets traversing bridge devices. | * The ''bridge'' family handles ethernet packets traversing bridge devices. | ||
* The | * The hooks for ''netdev'' are: ''ingress'', ''egress''. | ||
'''priority''' refers to a number used to order the chains or to set them between some Netfilter operations. Possible values are: ''NF_IP_PRI_CONNTRACK_DEFRAG (-400)'', ''NF_IP_PRI_RAW (-300)'', ''NF_IP_PRI_SELINUX_FIRST (-225)'', ''NF_IP_PRI_CONNTRACK (-200)'', ''NF_IP_PRI_MANGLE (-150)'', ''NF_IP_PRI_NAT_DST (-100)'', ''NF_IP_PRI_FILTER (0)'', ''NF_IP_PRI_SECURITY (50)'', ''NF_IP_PRI_NAT_SRC (100)'', ''NF_IP_PRI_SELINUX_LAST (225)'', ''NF_IP_PRI_CONNTRACK_HELPER (300)''. | '''priority''' refers to a number used to order the chains or to set them between some Netfilter operations. Possible values are: ''NF_IP_PRI_CONNTRACK_DEFRAG (-400)'', ''NF_IP_PRI_RAW (-300)'', ''NF_IP_PRI_SELINUX_FIRST (-225)'', ''NF_IP_PRI_CONNTRACK (-200)'', ''NF_IP_PRI_MANGLE (-150)'', ''NF_IP_PRI_NAT_DST (-100)'', ''NF_IP_PRI_FILTER (0)'', ''NF_IP_PRI_SECURITY (50)'', ''NF_IP_PRI_NAT_SRC (100)'', ''NF_IP_PRI_SELINUX_LAST (225)'', ''NF_IP_PRI_CONNTRACK_HELPER (300)''. | ||
'''policy''' is the default verdict statement to control the flow in the chain. Possible values are: ''accept'' | '''policy''' is the default verdict statement to control the flow in the base chain. Possible values are: ''accept'' (default) and ''drop''. Warning: Setting the policy to ''drop'' discards all packets that | ||
have not been accepted by the ruleset. | |||
<source lang="bash"> | <source lang="bash"> | ||
% nft (add | create) chain [<family>] <table> <name> [ { type <type> hook <hook> [device <device>] priority <priority> \; [policy <policy> \;] } ] | % nft (add | create) chain [<family>] <table> <name> [ \{ type <type> hook <hook> [device <device>] priority <priority> \; [policy <policy> \;] \} ] | ||
% nft (delete | list | flush) chain [<family>] <table> <name> | % nft (delete | list | flush) chain [<family>] <table> <name> | ||
% nft rename chain [<family>] <table> <name> <newname> | % nft rename chain [<family>] <table> <name> <newname> | ||
Line 52: | Line 53: | ||
'''handle''' is an internal number that identifies a certain ''rule''. | '''handle''' is an internal number that identifies a certain ''rule''. | ||
<source lang="bash"> | <source lang="bash"> | ||
% nft add rule [<family>] <table> <chain> <matches> <statements> | % nft add rule [<family>] <table> <chain> <matches> <statements> | ||
% nft insert rule [<family>] <table> <chain> [position < | % nft insert rule [<family>] <table> <chain> [position <handle>] <matches> <statements> | ||
% nft replace rule [<family>] <table> <chain> [handle <handle>] <matches> <statements> | % nft replace rule [<family>] <table> <chain> [handle <handle>] <matches> <statements> | ||
% nft delete rule [<family>] <table> <chain> [handle <handle>] | % nft delete rule [<family>] <table> <chain> [handle <handle>] | ||
</source> | </source> | ||
Inserted rules are placed at the beginning of the chain, by default. However, if you specify a ''position'' handle, then the new rule is inserted just before the existing rule with that handle. | |||
=== Matches === | === Matches === | ||
Line 78: | Line 79: | ||
ip dscp 0x38 | ip dscp 0x38 | ||
ip dscp != 0x20 | ip dscp != 0x20 | ||
ip dscp {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, | ip dscp { cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, | ||
af22, af23, af31, af32, af33, af41, af42, af43, ef} | af22, af23, af31, af32, af33, af41, af42, af43, ef } | ||
</source> | </source> | ||
|- | |- | ||
Line 89: | Line 90: | ||
ip length 333-435 | ip length 333-435 | ||
ip length != 333-453 | ip length != 333-453 | ||
ip length { 333, 553, 673, 838} | ip length { 333, 553, 673, 838 } | ||
</source> | </source> | ||
|- | |- | ||
Line 105: | Line 106: | ||
| Fragmentation offset | | Fragmentation offset | ||
|<source lang="bash"> | |<source lang="bash"> | ||
ip frag-off | ip frag-off & 0x1fff != 0 # match fragments | ||
ip frag-off != | ip frag-off & 0x2000 != 0 # match MF flag | ||
ip frag-off & 0x4000 != 0 # match DF flag | |||
ip frag-off != | |||
</source> | </source> | ||
|- | |- | ||
Line 196: | Line 195: | ||
ip6 dscp 0x38 | ip6 dscp 0x38 | ||
ip6 dscp != 0x20 | ip6 dscp != 0x20 | ||
ip6 dscp {cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, ef} | ip6 dscp { cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, ef } | ||
</source> | </source> | ||
|- | |- | ||
Line 215: | Line 214: | ||
ip6 length 333-435 | ip6 length 333-435 | ||
ip6 length != 333-453 | ip6 length != 333-453 | ||
ip6 length { 333, 553, 673, 838} | ip6 length { 333, 553, 673, 838 } | ||
</source> | </source> | ||
|- | |- | ||
Line 221: | Line 220: | ||
| Next header type (Upper layer protocol number) | | Next header type (Upper layer protocol number) | ||
|<source lang="bash"> | |<source lang="bash"> | ||
ip6 nexthdr {esp, udp, ah, comp, udplite, tcp, dccp, sctp, icmpv6} | ip6 nexthdr { esp, udp, ah, comp, udplite, tcp, dccp, sctp, icmpv6 } | ||
ip6 nexthdr esp | ip6 nexthdr esp | ||
ip6 nexthdr != esp | ip6 nexthdr != esp | ||
Line 236: | Line 235: | ||
ip6 hoplimit 33-45 | ip6 hoplimit 33-45 | ||
ip6 hoplimit != 33-45 | ip6 hoplimit != 33-45 | ||
ip6 hoplimit {33, 55, 67, 88} | ip6 hoplimit { 33, 55, 67, 88 } | ||
ip6 hoplimit {33-55} | ip6 hoplimit { 33-55 } | ||
</source> | </source> | ||
|- | |- | ||
Line 262: | Line 261: | ||
</source> | </source> | ||
|} | |} | ||
==== Tcp ==== | ==== Tcp ==== | ||
Line 275: | Line 273: | ||
tcp dport != 33-45 | tcp dport != 33-45 | ||
tcp dport { 33-55 } | tcp dport { 33-55 } | ||
tcp dport {telnet, http, https } | tcp dport { telnet, http, https } | ||
tcp dport vmap { 22 : accept, 23 : drop } | tcp dport vmap { 22 : accept, 23 : drop } | ||
tcp dport vmap { 25:accept, 28:drop } | tcp dport vmap { 25:accept, 28:drop } | ||
Line 285: | Line 283: | ||
tcp sport 22 | tcp sport 22 | ||
tcp sport != 33-45 | tcp sport != 33-45 | ||
tcp sport { 33, 55, 67, 88} | tcp sport { 33, 55, 67, 88 } | ||
tcp sport { 33-55} | tcp sport { 33-55 } | ||
tcp sport vmap { 25:accept, 28:drop } | tcp sport vmap { 25:accept, 28:drop } | ||
tcp sport 1024 tcp dport 22 | tcp sport 1024 tcp dport 22 | ||
Line 310: | Line 308: | ||
| TCP flags | | TCP flags | ||
|<source lang="bash"> | |<source lang="bash"> | ||
tcp flags { fin, syn, rst, psh, ack, urg, ecn, cwr} | tcp flags { fin, syn, rst, psh, ack, urg, ecn, cwr } | ||
tcp flags cwr | tcp flags cwr | ||
tcp flags != cwr | tcp flags != cwr | ||
Line 347: | Line 345: | ||
</source> | </source> | ||
|} | |} | ||
==== Udp ==== | ==== Udp ==== | ||
Line 360: | Line 357: | ||
udp dport != 33-45 | udp dport != 33-45 | ||
udp dport { 33-55 } | udp dport { 33-55 } | ||
udp dport {telnet, http, https } | udp dport { telnet, http, https } | ||
udp dport vmap { 22 : accept, 23 : drop } | udp dport vmap { 22 : accept, 23 : drop } | ||
udp dport vmap { 25:accept, 28:drop } | udp dport vmap { 25:accept, 28:drop } | ||
Line 370: | Line 367: | ||
udp sport 22 | udp sport 22 | ||
udp sport != 33-45 | udp sport != 33-45 | ||
udp sport { 33, 55, 67, 88} | udp sport { 33, 55, 67, 88 } | ||
udp sport { 33-55} | udp sport { 33-55 } | ||
udp sport vmap { 25:accept, 28:drop } | udp sport vmap { 25:accept, 28:drop } | ||
udp sport 1024 | udp sport 1024 udp dport 22 | ||
</source> | </source> | ||
|- | |- | ||
Line 394: | Line 391: | ||
</source> | </source> | ||
|} | |} | ||
==== Udplite ==== | ==== Udplite ==== | ||
Line 407: | Line 403: | ||
udplite dport != 33-45 | udplite dport != 33-45 | ||
udplite dport { 33-55 } | udplite dport { 33-55 } | ||
udplite dport {telnet, http, https } | udplite dport { telnet, http, https } | ||
udplite dport vmap { 22 : accept, 23 : drop } | udplite dport vmap { 22 : accept, 23 : drop } | ||
udplite dport vmap { 25:accept, 28:drop } | udplite dport vmap { 25:accept, 28:drop } | ||
Line 417: | Line 413: | ||
udplite sport 22 | udplite sport 22 | ||
udplite sport != 33-45 | udplite sport != 33-45 | ||
udplite sport { 33, 55, 67, 88} | udplite sport { 33, 55, 67, 88 } | ||
udplite sport { 33-55} | udplite sport { 33-55 } | ||
udplite sport vmap { 25:accept, 28:drop } | udplite sport vmap { 25:accept, 28:drop } | ||
udplite sport 1024 | udplite sport 1024 udplite dport 22 | ||
</source> | </source> | ||
|- | |- | ||
Line 432: | Line 428: | ||
</source> | </source> | ||
|} | |} | ||
==== Sctp ==== | ==== Sctp ==== | ||
Line 445: | Line 440: | ||
sctp dport != 33-45 | sctp dport != 33-45 | ||
sctp dport { 33-55 } | sctp dport { 33-55 } | ||
sctp dport {telnet, http, https } | sctp dport { telnet, http, https } | ||
sctp dport vmap { 22 : accept, 23 : drop } | sctp dport vmap { 22 : accept, 23 : drop } | ||
sctp dport vmap { 25:accept, 28:drop } | sctp dport vmap { 25:accept, 28:drop } | ||
Line 455: | Line 450: | ||
sctp sport 22 | sctp sport 22 | ||
sctp sport != 33-45 | sctp sport != 33-45 | ||
sctp sport { 33, 55, 67, 88} | sctp sport { 33, 55, 67, 88 } | ||
sctp sport { 33-55} | sctp sport { 33-55 } | ||
sctp sport vmap { 25:accept, 28:drop } | sctp sport vmap { 25:accept, 28:drop } | ||
sctp sport 1024 | sctp sport 1024 sctp dport 22 | ||
</source> | </source> | ||
|- | |- | ||
Line 477: | Line 472: | ||
sctp vtag { 33, 55, 67, 88 } | sctp vtag { 33, 55, 67, 88 } | ||
sctp vtag { 33-55 } | sctp vtag { 33-55 } | ||
</source> | |||
|- | |||
| ''chunk <type>'' | |||
| Existence of a chunk with given type in packet | |||
|<source lang="bash"> | |||
sctp chunk init exists | |||
sctp chunk error missing | |||
</source> | |||
|- | |||
| ''chunk <type> <field>'' | |||
| A chunk's field value (implies chunk existence) | |||
|<sourcex lang="bash"> | |||
sctp chunk init flags 0x1 | |||
sctp chunk data tsn 0x23 | |||
</source> | </source> | ||
|} | |} | ||
==== Dccp ==== | ==== Dccp ==== | ||
Line 492: | Line 500: | ||
dccp dport != 33-45 | dccp dport != 33-45 | ||
dccp dport { 33-55 } | dccp dport { 33-55 } | ||
dccp dport {telnet, http, https } | dccp dport { telnet, http, https } | ||
dccp dport vmap { 22 : accept, 23 : drop } | dccp dport vmap { 22 : accept, 23 : drop } | ||
dccp dport vmap { 25:accept, 28:drop } | dccp dport vmap { 25:accept, 28:drop } | ||
Line 502: | Line 510: | ||
dccp sport 22 | dccp sport 22 | ||
dccp sport != 33-45 | dccp sport != 33-45 | ||
dccp sport { 33, 55, 67, 88} | dccp sport { 33, 55, 67, 88 } | ||
dccp sport { 33-55} | dccp sport { 33-55 } | ||
dccp sport vmap { 25:accept, 28:drop } | dccp sport vmap { 25:accept, 28:drop } | ||
dccp sport 1024 | dccp sport 1024 dccp dport 22 | ||
</source> | </source> | ||
|- | |- | ||
Line 511: | Line 519: | ||
| Type of packet | | Type of packet | ||
|<source lang="bash"> | |<source lang="bash"> | ||
dccp type {request, response, data, ack, dataack, closereq, close, reset, sync, syncack} | dccp type { request, response, data, ack, dataack, closereq, close, reset, sync, syncack } | ||
dccp type request | dccp type request | ||
dccp type != request | dccp type != request | ||
</source> | </source> | ||
|} | |} | ||
==== Ah ==== | ==== Ah ==== | ||
Line 528: | Line 535: | ||
ah hdrlength 11-23 | ah hdrlength 11-23 | ||
ah hdrlength != 11-23 | ah hdrlength != 11-23 | ||
ah hdrlength {11, 23, 44 } | ah hdrlength { 11, 23, 44 } | ||
</source> | </source> | ||
|- | |- | ||
Line 536: | Line 543: | ||
ah reserved 22 | ah reserved 22 | ||
ah reserved != 33-45 | ah reserved != 33-45 | ||
ah reserved {23, 100 } | ah reserved { 23, 100 } | ||
ah reserved { 33-55 } | ah reserved { 33-55 } | ||
</source> | </source> | ||
Line 545: | Line 552: | ||
ah spi 111 | ah spi 111 | ||
ah spi != 111-222 | ah spi != 111-222 | ||
ah spi {111, 122 } | ah spi { 111, 122 } | ||
</source> | </source> | ||
|- | |- | ||
Line 552: | Line 559: | ||
|<source lang="bash"> | |<source lang="bash"> | ||
ah sequence 123 | ah sequence 123 | ||
ah sequence {23, 25, 33} | ah sequence { 23, 25, 33 } | ||
ah sequence != 23-33 | ah sequence != 23-33 | ||
</source> | </source> | ||
|} | |} | ||
==== Esp ==== | ==== Esp ==== | ||
Line 568: | Line 574: | ||
esp spi 111 | esp spi 111 | ||
esp spi != 111-222 | esp spi != 111-222 | ||
esp spi {111, 122 } | esp spi { 111, 122 } | ||
</source> | </source> | ||
|- | |- | ||
Line 575: | Line 581: | ||
|<source lang="bash"> | |<source lang="bash"> | ||
esp sequence 123 | esp sequence 123 | ||
esp sequence {23, 25, 33} | esp sequence { 23, 25, 33 } | ||
esp sequence != 23-33 | esp sequence != 23-33 | ||
</source> | </source> | ||
|} | |} | ||
==== Comp ==== | ==== Comp ==== | ||
Line 590: | Line 595: | ||
|<source lang="bash"> | |<source lang="bash"> | ||
comp nexthdr != esp | comp nexthdr != esp | ||
comp nexthdr {esp, ah, comp, udp, udplite, tcp, tcp, dccp, sctp} | comp nexthdr { esp, ah, comp, udp, udplite, tcp, tcp, dccp, sctp } | ||
</source> | </source> | ||
|- | |- | ||
Line 598: | Line 603: | ||
comp flags 0x0 | comp flags 0x0 | ||
comp flags != 0x33-0x45 | comp flags != 0x33-0x45 | ||
comp flags {0x33, 0x55, 0x67, 0x88} | comp flags { 0x33, 0x55, 0x67, 0x88 } | ||
</source> | </source> | ||
|- | |- | ||
Line 606: | Line 611: | ||
comp cpi 22 | comp cpi 22 | ||
comp cpi != 33-45 | comp cpi != 33-45 | ||
comp cpi {33, 55, 67, 88} | comp cpi { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|} | |} | ||
==== Icmp ==== | ==== Icmp ==== | ||
Line 619: | Line 623: | ||
| ICMP packet type | | ICMP packet type | ||
|<source lang="bash"> | |<source lang="bash"> | ||
icmp type {echo-reply, destination-unreachable, source-quench, redirect, echo-request, time-exceeded, parameter-problem, timestamp-request, timestamp-reply, info-request, info-reply, address-mask-request, address-mask-reply, router-advertisement, router-solicitation} | icmp type { echo-reply, destination-unreachable, source-quench, redirect, echo-request, time-exceeded, parameter-problem, timestamp-request, timestamp-reply, info-request, info-reply, address-mask-request, address-mask-reply, router-advertisement, router-solicitation } | ||
</source> | </source> | ||
|- | |- | ||
Line 627: | Line 631: | ||
icmp code 111 | icmp code 111 | ||
icmp code != 33-55 | icmp code != 33-55 | ||
icmp code { 2, 4, 54, 33, 56} | icmp code { 2, 4, 54, 33, 56 } | ||
</source> | </source> | ||
|- | |- | ||
Line 680: | Line 684: | ||
| ICMPv6 packet type | | ICMPv6 packet type | ||
|<source lang="bash"> | |<source lang="bash"> | ||
icmpv6 type {destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert | icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, parameter-problem, mld2-listener-report } | ||
</source> | </source> | ||
|- | |- | ||
Line 688: | Line 692: | ||
icmpv6 code 4 | icmpv6 code 4 | ||
icmpv6 code 3-66 | icmpv6 code 3-66 | ||
icmpv6 code {5, 6, 7} | icmpv6 code { 5, 6, 7 } | ||
</source> | </source> | ||
|- | |- | ||
Line 728: | Line 732: | ||
icmpv6 max-delay 33-45 | icmpv6 max-delay 33-45 | ||
icmpv6 max-delay != 33-45 | icmpv6 max-delay != 33-45 | ||
icmpv6 max-delay {33, 55, 67, 88} | icmpv6 max-delay { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|} | |} | ||
Line 759: | Line 763: | ||
| Next protocol header | | Next protocol header | ||
|<source lang="bash"> | |<source lang="bash"> | ||
dst nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp} | dst nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp } | ||
dst nexthdr 22 | dst nexthdr 22 | ||
dst nexthdr != 33-45 | dst nexthdr != 33-45 | ||
Line 782: | Line 786: | ||
| Next protocol header | | Next protocol header | ||
|<source lang="bash"> | |<source lang="bash"> | ||
frag nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp, icmp} | frag nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp, icmp } | ||
frag nexthdr 6 | frag nexthdr 6 | ||
frag nexthdr != 50-51 | frag nexthdr != 50-51 | ||
Line 792: | Line 796: | ||
frag reserved 22 | frag reserved 22 | ||
frag reserved != 33-45 | frag reserved != 33-45 | ||
frag reserved { 33, 55, 67, 88} | frag reserved { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|- | |- | ||
Line 800: | Line 804: | ||
frag frag-off 22 | frag frag-off 22 | ||
frag frag-off != 33-45 | frag frag-off != 33-45 | ||
frag frag-off { 33, 55, 67, 88} | frag frag-off { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|- | |- | ||
Line 827: | Line 831: | ||
| Next protocol header | | Next protocol header | ||
|<source lang="bash"> | |<source lang="bash"> | ||
hbh nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, icmpv6} | hbh nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, icmpv6 } | ||
hbh nexthdr 22 | hbh nexthdr 22 | ||
hbh nexthdr != 33-45 | hbh nexthdr != 33-45 | ||
Line 866: | Line 870: | ||
| | | | ||
|<source lang="bash"> | |<source lang="bash"> | ||
mh type {binding-refresh-request, home-test-init, careof-test-init, home-test, careof-test, binding-update, binding-acknowledgement, binding-error, fast-binding-update, fast-binding-acknowledgement, fast-binding-advertisement, experimental-mobility-header, home-agent-switch-message} | mh type { binding-refresh-request, home-test-init, careof-test-init, home-test, careof-test, binding-update, binding-acknowledgement, binding-error, fast-binding-update, fast-binding-acknowledgement, fast-binding-advertisement, experimental-mobility-header, home-agent-switch-message } | ||
mh type home-agent-switch-message | mh type home-agent-switch-message | ||
mh type != home-agent-switch-message | mh type != home-agent-switch-message | ||
Line 876: | Line 880: | ||
mh reserved 22 | mh reserved 22 | ||
mh reserved != 33-45 | mh reserved != 33-45 | ||
mh reserved { 33, 55, 67, 88} | mh reserved { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|- | |- | ||
Line 884: | Line 888: | ||
mh checksum 22 | mh checksum 22 | ||
mh checksum != 33-45 | mh checksum != 33-45 | ||
mh checksum { 33, 55, 67, 88} | mh checksum { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|} | |} | ||
Line 923: | Line 927: | ||
rt seg-left 22 | rt seg-left 22 | ||
rt seg-left != 33-45 | rt seg-left != 33-45 | ||
rt seg-left { 33, 55, 67, 88} | rt seg-left { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|} | |} | ||
Line 972: | Line 976: | ||
arp htype 1 | arp htype 1 | ||
arp htype != 33-45 | arp htype != 33-45 | ||
arp htype { 33, 55, 67, 88} | arp htype { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|- | |- | ||
Line 980: | Line 984: | ||
arp hlen 1 | arp hlen 1 | ||
arp hlen != 33-45 | arp hlen != 33-45 | ||
arp hlen { 33, 55, 67, 88} | arp hlen { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|- | |- | ||
Line 988: | Line 992: | ||
arp plen 1 | arp plen 1 | ||
arp plen != 33-45 | arp plen != 33-45 | ||
arp plen { 33, 55, 67, 88} | arp plen { 33, 55, 67, 88 } | ||
</source> | </source> | ||
|- | |- | ||
Line 994: | Line 998: | ||
| | | | ||
|<source lang="bash"> | |<source lang="bash"> | ||
arp operation {nak, inreply, inrequest, rreply, rrequest, reply, request} | arp operation { nak, inreply, inrequest, rreply, rrequest, reply, request } | ||
</source> | </source> | ||
|} | |} | ||
Line 1,018: | Line 1,022: | ||
ct direction original | ct direction original | ||
ct direction != original | ct direction != original | ||
ct direction {reply, original} | ct direction { reply, original } | ||
</source> | </source> | ||
|- | |- | ||
Line 1,025: | Line 1,029: | ||
|<source lang="bash"> | |<source lang="bash"> | ||
ct status expected | ct status expected | ||
ct status != expected | (ct status & expected) != expected | ||
ct status {expected,seen-reply,assured,confirmed,snat,dnat,dying} | ct status { expected, seen-reply, assured, confirmed, snat, dnat, dying } | ||
</source> | </source> | ||
|- | |- | ||
Line 1,043: | Line 1,047: | ||
ct mark 0x00000032-0x00000045 | ct mark 0x00000032-0x00000045 | ||
ct mark != 0x00000032-0x00000045 | ct mark != 0x00000032-0x00000045 | ||
ct mark {0x32, 0x2222, 0x42de3} | ct mark { 0x32, 0x2222, 0x42de3 } | ||
ct mark {0x32-0x2222, 0x4444-0x42de3} | ct mark { 0x32-0x2222, 0x4444-0x42de3 } | ||
ct mark set 0x11 xor 0x1331 | ct mark set 0x11 xor 0x1331 | ||
ct mark set 0x11333 and 0x11 | ct mark set 0x11333 and 0x11 | ||
Line 1,064: | Line 1,068: | ||
ct expiration != 33-45 | ct expiration != 33-45 | ||
ct expiration != 33s-45s | ct expiration != 33s-45s | ||
ct expiration {33, 55, 67, 88} | ct expiration { 33, 55, 67, 88 } | ||
ct expiration { 1m7s, 33s, 55s, 1m28s} | ct expiration { 1m7s, 33s, 55s, 1m28s } | ||
</source> | </source> | ||
|- | |- | ||
Line 1,087: | Line 1,091: | ||
</source> | </source> | ||
|- | |- | ||
| | ''[original | reply] saddr <ip source address>'' | | | ''[original | reply] ip saddr <ip source address>'' | ||
| | | | ||
|<source lang="bash"> | |<source lang="bash"> | ||
ct original saddr 192.168.0.1 | ct original ip saddr 192.168.0.1 | ||
ct reply saddr 192.168.0.1 | ct reply ip saddr 192.168.0.1 | ||
ct original saddr 192.168.1.0/24 | ct original ip saddr 192.168.1.0/24 | ||
ct reply saddr 192.168.1.0/24 | ct reply ip saddr 192.168.1.0/24 | ||
</source> | </source> | ||
|- | |- | ||
| | ''[original | reply] daddr <ip destination address>'' | | | ''[original | reply] ip daddr <ip destination address>'' | ||
| | | | ||
|<source lang="bash"> | |<source lang="bash"> | ||
ct original daddr 192.168.0.1 | ct original ip daddr 192.168.0.1 | ||
ct reply daddr 192.168.0.1 | ct reply ip daddr 192.168.0.1 | ||
ct original daddr 192.168.1.0/24 | ct original ip daddr 192.168.1.0/24 | ||
ct reply daddr 192.168.1.0/24 | ct reply ip daddr 192.168.1.0/24 | ||
</source> | </source> | ||
|- | |- | ||
Line 1,127: | Line 1,131: | ||
|<source lang="bash"> | |<source lang="bash"> | ||
ct reply proto-src 53 | ct reply proto-src 53 | ||
</source> | |||
|- | |||
| | ''count [over] <number of connections>'' | |||
| | |||
|<source lang="bash"> | |||
ct count over 2 | |||
tcp dport 22 add @ssh_flood { ip saddr ct count over 2 } reject | |||
[ which requires an existing ssh_flood set, ie. add set filter ssh_flood { type ipv4_addr; flags dynamic; } ] | |||
</source> | </source> | ||
|} | |} | ||
==== Meta ==== | ==== Meta ==== | ||
Line 1,143: | Line 1,155: | ||
meta iifname "eth0" | meta iifname "eth0" | ||
meta iifname != "eth0" | meta iifname != "eth0" | ||
meta iifname {"eth0", "lo"} | meta iifname { "eth0", "lo" } | ||
meta iifname "eth*" | meta iifname "eth*" | ||
</source> | </source> | ||
Line 1,152: | Line 1,164: | ||
meta oifname "eth0" | meta oifname "eth0" | ||
meta oifname != "eth0" | meta oifname != "eth0" | ||
meta oifname {"eth0", "lo"} | meta oifname { "eth0", "lo" } | ||
meta oifname "eth*" | meta oifname "eth*" | ||
</source> | </source> | ||
Line 1,168: | Line 1,180: | ||
meta oif lo | meta oif lo | ||
meta oif != lo | meta oif != lo | ||
meta oif {eth0, lo} | meta oif { eth0, lo } | ||
</source> | </source> | ||
|- | |- | ||
Line 1,174: | Line 1,186: | ||
| Input interface type | | Input interface type | ||
|<source lang="bash"> | |<source lang="bash"> | ||
meta iiftype {ether, ppp, ipip, ipip6, loopback, sit, ipgre} | meta iiftype { ether, ppp, ipip, ipip6, loopback, sit, ipgre } | ||
meta iiftype != ether | meta iiftype != ether | ||
meta iiftype ether | meta iiftype ether | ||
Line 1,182: | Line 1,194: | ||
| Output interface hardware type | | Output interface hardware type | ||
|<source lang="bash"> | |<source lang="bash"> | ||
meta oiftype {ether, ppp, ipip, ipip6, loopback, sit, ipgre} | meta oiftype { ether, ppp, ipip, ipip6, loopback, sit, ipgre } | ||
meta oiftype != ether | meta oiftype != ether | ||
meta oiftype ether | meta oiftype ether | ||
Line 1,243: | Line 1,255: | ||
meta mark set 0x32 or 0xfffff | meta mark set 0x32 or 0xfffff | ||
meta mark set 0xfffe xor 0x16 | meta mark set 0xfffe xor 0x16 | ||
</source> | |||
|- | |||
| ''priority [set] <priority>'' | |||
| tc class id | |||
|<source lang="bash"> | |||
meta priority none | |||
meta priority 0x1:0x1 | |||
meta priority 0x1:0xffff | |||
meta priority 0xffff:0xffff | |||
meta priority set 0x1:0x1 | |||
meta priority set 0x1:0xffff | |||
meta priority set 0xffff:0xffff | |||
</source> | </source> | ||
|- | |- | ||
Line 1,248: | Line 1,272: | ||
| UID associated with originating socket | | UID associated with originating socket | ||
|<source lang="bash"> | |<source lang="bash"> | ||
meta skuid {bin, root, daemon} | meta skuid { bin, root, daemon } | ||
meta skuid root | meta skuid root | ||
meta skuid != root | meta skuid != root | ||
Line 1,262: | Line 1,286: | ||
| GID associated with originating socket | | GID associated with originating socket | ||
|<source lang="bash"> | |<source lang="bash"> | ||
meta skgid {bin, root, daemon} | meta skgid { bin, root, daemon } | ||
meta skgid root | meta skgid root | ||
meta skgid != root | meta skgid != root | ||
Line 1,284: | Line 1,308: | ||
meta pkttype broadcast | meta pkttype broadcast | ||
meta pkttype != broadcast | meta pkttype != broadcast | ||
meta pkttype { broadcast, unicast, multicast} | meta pkttype { broadcast, unicast, multicast } | ||
</source> | </source> | ||
|- | |- | ||
Line 1,305: | Line 1,329: | ||
meta iifgroup default | meta iifgroup default | ||
meta iifgroup != default | meta iifgroup != default | ||
meta iifgroup {default} | meta iifgroup { default } | ||
meta iifgroup { 11,33 } | meta iifgroup { 11,33 } | ||
meta iifgroup {11-33} | meta iifgroup { 11-33 } | ||
</source> | </source> | ||
|- | |- | ||
Line 1,317: | Line 1,341: | ||
meta oifgroup default | meta oifgroup default | ||
meta oifgroup != default | meta oifgroup != default | ||
meta oifgroup {default} | meta oifgroup { default } | ||
meta oifgroup { 11,33 } | meta oifgroup { 11,33 } | ||
meta oifgroup {11-33} | meta oifgroup { 11-33 } | ||
</source> | </source> | ||
|- | |- | ||
Line 1,330: | Line 1,354: | ||
meta cgroup 1048577-1048578 | meta cgroup 1048577-1048578 | ||
meta cgroup != 1048577-1048578 | meta cgroup != 1048577-1048578 | ||
meta cgroup {1048577-1048578} | meta cgroup { 1048577-1048578 } | ||
</source> | </source> | ||
|} | |} | ||
=== Statements === | === Statements === | ||
Line 1,381: | Line 1,404: | ||
==== Reject ==== | ==== Reject ==== | ||
The default '''reject''' will be the ICMP type '''port-unreachable'''. The '''icmpx''' is only used for inet family support. | |||
More information on the [[Rejecting_traffic]] page. | |||
{| class="wikitable" | {| class="wikitable" | ||
Line 1,400: | Line 1,427: | ||
reject with icmpv6 type addr-unreachable | reject with icmpv6 type addr-unreachable | ||
reject with icmpv6 type port-unreachable | reject with icmpv6 type port-unreachable | ||
reject with icmpx type host-unreachable | reject with icmpx type host-unreachable | ||
reject with icmpx type no-route | reject with icmpx type no-route | ||
reject with icmpx type admin-prohibited | reject with icmpx type admin-prohibited | ||
reject with icmpx type port-unreachable | reject with icmpx type port-unreachable | ||
ip protocol tcp reject with tcp reset | |||
</source> | </source> | ||
|} | |} | ||
==== Counter ==== | ==== Counter ==== | ||
Line 1,450: | Line 1,476: | ||
!colspan="6"|nat statement | !colspan="6"|nat statement | ||
|- | |- | ||
| ''dnat <destination address>'' | | ''dnat to <destination address>'' | ||
| Destination address translation | | Destination address translation | ||
|<source lang="bash"> | |<source lang="bash"> | ||
dnat 192.168.3.2 | dnat to 192.168.3.2 | ||
dnat ct mark map { 0x00000014 : 1.2.3.4} | dnat to ct mark map { 0x00000014 : 1.2.3.4 } | ||
</source> | </source> | ||
|- | |- | ||
| ''snat <ip source address>'' | | ''snat to <ip source address>'' | ||
| Source address translation | | Source address translation | ||
|<source lang="bash"> | |<source lang="bash"> | ||
snat 192.168.3.2 | snat to 192.168.3.2 | ||
snat 2001:838:35f:1::-2001:838:35f:2:::100 | snat to 2001:838:35f:1::-2001:838:35f:2:::100 | ||
</source> | </source> | ||
|- | |- | ||
Line 1,490: | Line 1,516: | ||
</source> | </source> | ||
|} | |} | ||
== Extras == | == Extras == | ||
Line 1,579: | Line 1,604: | ||
# open tcp ports: sshd (22), httpd (80) | # open tcp ports: sshd (22), httpd (80) | ||
tcp dport {ssh, http} accept | tcp dport { ssh, http } accept | ||
} | } | ||
} | } | ||
Line 1,598: | Line 1,623: | ||
# icmp | # icmp | ||
# routers may also want: mld-listener-query, nd-router-solicit | # routers may also want: mld-listener-query, nd-router-solicit | ||
icmpv6 type {echo-request,nd-neighbor-solicit} accept | icmpv6 type { echo-request, nd-neighbor-solicit } accept | ||
# open tcp ports: sshd (22), httpd (80) | # open tcp ports: sshd (22), httpd (80) | ||
tcp dport {ssh, http} accept | tcp dport { ssh, http } accept | ||
} | } | ||
} | } | ||
</source> | </source> |
Latest revision as of 08:52, 21 April 2024
Find below some basic concepts to know before using nftables.
table refers to a container of chains with no specific semantics.
chain within a table refers to a container of rules.
rule refers to an action to be configured within a chain.
nft command line
nft is the command line tool in order to interact with nftables at userspace.
Tables
family refers to a one of the following table types: ip, arp, ip6, bridge, inet, netdev. It defaults to ip.
% nft list tables [<family>]
% nft [-n] [-a] list table [<family>] <name>
% nft (add | delete | flush) table [<family>] <name>
The argument -n shows the addresses and other information that use names in numeric format. The -a argument is used to display each rule's handle (i.e., a numerical identifier).
Chains
type refers to the kind of chain to be created. Possible types are:
- filter: Supported by arp, bridge, ip, ip6 and inet table families.
- route: Mark packets (like mangle for the output hook, for other hooks use the type filter instead), supported by ip and ip6.
- nat: In order to perform Network Address Translation, supported by ip and ip6.
hook refers to an specific stage of the packet while it's being processed through the kernel. More info in Netfilter hooks.
- The hooks for ip, ip6 and inet families are: prerouting, input, forward, output, postrouting.
- The hooks for arp family are: input, output.
- The bridge family handles ethernet packets traversing bridge devices.
- The hooks for netdev are: ingress, egress.
priority refers to a number used to order the chains or to set them between some Netfilter operations. Possible values are: NF_IP_PRI_CONNTRACK_DEFRAG (-400), NF_IP_PRI_RAW (-300), NF_IP_PRI_SELINUX_FIRST (-225), NF_IP_PRI_CONNTRACK (-200), NF_IP_PRI_MANGLE (-150), NF_IP_PRI_NAT_DST (-100), NF_IP_PRI_FILTER (0), NF_IP_PRI_SECURITY (50), NF_IP_PRI_NAT_SRC (100), NF_IP_PRI_SELINUX_LAST (225), NF_IP_PRI_CONNTRACK_HELPER (300).
policy is the default verdict statement to control the flow in the base chain. Possible values are: accept (default) and drop. Warning: Setting the policy to drop discards all packets that have not been accepted by the ruleset.
% nft (add | create) chain [<family>] <table> <name> [ \{ type <type> hook <hook> [device <device>] priority <priority> \; [policy <policy> \;] \} ]
% nft (delete | list | flush) chain [<family>] <table> <name>
% nft rename chain [<family>] <table> <name> <newname>
Rules
handle is an internal number that identifies a certain rule.
% nft add rule [<family>] <table> <chain> <matches> <statements>
% nft insert rule [<family>] <table> <chain> [position <handle>] <matches> <statements>
% nft replace rule [<family>] <table> <chain> [handle <handle>] <matches> <statements>
% nft delete rule [<family>] <table> <chain> [handle <handle>]
Inserted rules are placed at the beginning of the chain, by default. However, if you specify a position handle, then the new rule is inserted just before the existing rule with that handle.
Matches
matches are clues used to access to certain packet information and create filters according to them.
Ip
ip match | |||||
---|---|---|---|---|---|
dscp <value> | ip dscp cs1
ip dscp != cs1
ip dscp 0x38
ip dscp != 0x20
ip dscp { cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21,
af22, af23, af31, af32, af33, af41, af42, af43, ef }
| ||||
length <length> | Total packet length | ip length 232
ip length != 233
ip length 333-435
ip length != 333-453
ip length { 333, 553, 673, 838 }
| |||
id <id> | IP ID | ip id 22
ip id != 233
ip id 33-45
ip id != 33-45
ip id { 33, 55, 67, 88 }
| |||
frag-off <value> | Fragmentation offset | ip frag-off & 0x1fff != 0 # match fragments
ip frag-off & 0x2000 != 0 # match MF flag
ip frag-off & 0x4000 != 0 # match DF flag
| |||
ttl <ttl> | Time to live | ip ttl 0
ip ttl 233
ip ttl 33-55
ip ttl != 45-50
ip ttl { 43, 53, 45 }
ip ttl { 33-55 }
| |||
protocol <protocol> | Upper layer protocol | ip protocol tcp
ip protocol 6
ip protocol != tcp
ip protocol { icmp, esp, ah, comp, udp, udplite, tcp, dccp, sctp }
| |||
checksum <checksum> | IP header checksum | ip checksum 13172
ip checksum 22
ip checksum != 233
ip checksum 33-45
ip checksum != 33-45
ip checksum { 33, 55, 67, 88 }
ip checksum { 33-55 }
| |||
saddr <ip source address> | Source address | ip saddr 192.168.2.0/24
ip saddr != 192.168.2.0/24
ip saddr 192.168.3.1 ip daddr 192.168.3.100
ip saddr != 1.1.1.1
ip saddr 1.1.1.1
ip saddr & 0xff == 1
ip saddr & 0.0.0.255 < 0.0.0.127
| |||
daddr <ip destination address> | Destination address | ip daddr 192.168.0.1
ip daddr != 192.168.0.1
ip daddr 192.168.0.1-192.168.0.250
ip daddr 10.0.0.0-10.255.255.255
ip daddr 172.16.0.0-172.31.255.255
ip daddr 192.168.3.1-192.168.4.250
ip daddr != 192.168.0.1-192.168.0.250
ip daddr { 192.168.0.1-192.168.0.250 }
ip daddr { 192.168.5.1, 192.168.5.2, 192.168.5.3 }
| |||
version <version> | Ip Header version | ip version 4
| |||
hdrlength <header length> | IP header length | ip hdrlength 0
ip hdrlength 15
|
Ip6
ip6 match | |||||
---|---|---|---|---|---|
dscp <value> | ip6 dscp cs1
ip6 dscp != cs1
ip6 dscp 0x38
ip6 dscp != 0x20
ip6 dscp { cs0, cs1, cs2, cs3, cs4, cs5, cs6, cs7, af11, af12, af13, af21, af22, af23, af31, af32, af33, af41, af42, af43, ef }
| ||||
flowlabel <label> | Flow label | ip6 flowlabel 22
ip6 flowlabel != 233
ip6 flowlabel { 33, 55, 67, 88 }
ip6 flowlabel { 33-55 }
| |||
length <length> | Payload length | ip6 length 232
ip6 length != 233
ip6 length 333-435
ip6 length != 333-453
ip6 length { 333, 553, 673, 838 }
| |||
nexthdr <header> | Next header type (Upper layer protocol number) | ip6 nexthdr { esp, udp, ah, comp, udplite, tcp, dccp, sctp, icmpv6 }
ip6 nexthdr esp
ip6 nexthdr != esp
ip6 nexthdr { 33-44 }
ip6 nexthdr 33-44
ip6 nexthdr != 33-44
| |||
hoplimit <hoplimit> | Hop limit | ip6 hoplimit 1
ip6 hoplimit != 233
ip6 hoplimit 33-45
ip6 hoplimit != 33-45
ip6 hoplimit { 33, 55, 67, 88 }
ip6 hoplimit { 33-55 }
| |||
saddr <ip source address> | Source Address | ip6 saddr 1234:1234:1234:1234:1234:1234:1234:1234
ip6 saddr ::1234:1234:1234:1234:1234:1234:1234
ip6 saddr ::/64
ip6 saddr ::1 ip6 daddr ::2
| |||
daddr <ip destination address> | Destination Address | ip6 daddr 1234:1234:1234:1234:1234:1234:1234:1234
ip6 daddr != ::1234:1234:1234:1234:1234:1234:1234-1234:1234::1234:1234:1234:1234:1234
| |||
version <version> | IP header version | ip6 version 6
|
Tcp
tcp match | |||||
---|---|---|---|---|---|
dport <destination port> | Destination port | tcp dport 22
tcp dport != 33-45
tcp dport { 33-55 }
tcp dport { telnet, http, https }
tcp dport vmap { 22 : accept, 23 : drop }
tcp dport vmap { 25:accept, 28:drop }
| |||
sport < source port> | Source port | tcp sport 22
tcp sport != 33-45
tcp sport { 33, 55, 67, 88 }
tcp sport { 33-55 }
tcp sport vmap { 25:accept, 28:drop }
tcp sport 1024 tcp dport 22
| |||
sequence <value> | Sequence number | tcp sequence 22
tcp sequence != 33-45
| |||
ackseq <value> | Acknowledgement number | tcp ackseq 22
tcp ackseq != 33-45
tcp ackseq { 33, 55, 67, 88 }
tcp ackseq { 33-55 }
| |||
flags <flags> | TCP flags | tcp flags { fin, syn, rst, psh, ack, urg, ecn, cwr }
tcp flags cwr
tcp flags != cwr
| |||
window <value> | Window | tcp window 22
tcp window != 33-45
tcp window { 33, 55, 67, 88 }
tcp window { 33-55 }
| |||
checksum <checksum> | IP header checksum | tcp checksum 22
tcp checksum != 33-45
tcp checksum { 33, 55, 67, 88 }
tcp checksum { 33-55 }
| |||
urgptr <pointer> | Urgent pointer | tcp urgptr 22
tcp urgptr != 33-45
tcp urgptr { 33, 55, 67, 88 }
| |||
doff <offset> | Data offset | tcp doff 8
|
Udp
udp match | |||||
---|---|---|---|---|---|
dport <destination port> | Destination port | udp dport 22
udp dport != 33-45
udp dport { 33-55 }
udp dport { telnet, http, https }
udp dport vmap { 22 : accept, 23 : drop }
udp dport vmap { 25:accept, 28:drop }
| |||
sport < source port> | Source port | udp sport 22
udp sport != 33-45
udp sport { 33, 55, 67, 88 }
udp sport { 33-55 }
udp sport vmap { 25:accept, 28:drop }
udp sport 1024 udp dport 22
| |||
length <length> | Total packet length | udp length 6666
udp length != 50-65
udp length { 50, 65 }
udp length { 35-50 }
| |||
checksum <checksum> | UDP checksum | udp checksum 22
udp checksum != 33-45
udp checksum { 33, 55, 67, 88 }
udp checksum { 33-55 }
|
Udplite
udplite match | |||||
---|---|---|---|---|---|
dport <destination port> | Destination port | udplite dport 22
udplite dport != 33-45
udplite dport { 33-55 }
udplite dport { telnet, http, https }
udplite dport vmap { 22 : accept, 23 : drop }
udplite dport vmap { 25:accept, 28:drop }
| |||
sport < source port> | Source port | udplite sport 22
udplite sport != 33-45
udplite sport { 33, 55, 67, 88 }
udplite sport { 33-55 }
udplite sport vmap { 25:accept, 28:drop }
udplite sport 1024 udplite dport 22
| |||
checksum <checksum> | Checksum | udplite checksum 22
udplite checksum != 33-45
udplite checksum { 33, 55, 67, 88 }
udplite checksum { 33-55 }
|
Sctp
sctp match | |||||
---|---|---|---|---|---|
dport <destination port> | Destination port | sctp dport 22
sctp dport != 33-45
sctp dport { 33-55 }
sctp dport { telnet, http, https }
sctp dport vmap { 22 : accept, 23 : drop }
sctp dport vmap { 25:accept, 28:drop }
| |||
sport < source port> | Source port | sctp sport 22
sctp sport != 33-45
sctp sport { 33, 55, 67, 88 }
sctp sport { 33-55 }
sctp sport vmap { 25:accept, 28:drop }
sctp sport 1024 sctp dport 22
| |||
checksum <checksum> | Checksum | sctp checksum 22
sctp checksum != 33-45
sctp checksum { 33, 55, 67, 88 }
sctp checksum { 33-55 }
| |||
vtag <tag> | Verification tag | sctp vtag 22
sctp vtag != 33-45
sctp vtag { 33, 55, 67, 88 }
sctp vtag { 33-55 }
| |||
chunk <type> | Existence of a chunk with given type in packet | sctp chunk init exists
sctp chunk error missing
| |||
chunk <type> <field> | A chunk's field value (implies chunk existence) | <sourcex lang="bash">
sctp chunk init flags 0x1 sctp chunk data tsn 0x23 </source> |
Dccp
dccp match | |||||
---|---|---|---|---|---|
dport <destination port> | Destination port | dccp dport 22
dccp dport != 33-45
dccp dport { 33-55 }
dccp dport { telnet, http, https }
dccp dport vmap { 22 : accept, 23 : drop }
dccp dport vmap { 25:accept, 28:drop }
| |||
sport < source port> | Source port | dccp sport 22
dccp sport != 33-45
dccp sport { 33, 55, 67, 88 }
dccp sport { 33-55 }
dccp sport vmap { 25:accept, 28:drop }
dccp sport 1024 dccp dport 22
| |||
type <type> | Type of packet | dccp type { request, response, data, ack, dataack, closereq, close, reset, sync, syncack }
dccp type request
dccp type != request
|
Ah
ah match | |||||
---|---|---|---|---|---|
hdrlength <length> | AH header length | ah hdrlength 11-23
ah hdrlength != 11-23
ah hdrlength { 11, 23, 44 }
| |||
reserved <value> | ah reserved 22
ah reserved != 33-45
ah reserved { 23, 100 }
ah reserved { 33-55 }
| ||||
spi <value> | ah spi 111
ah spi != 111-222
ah spi { 111, 122 }
| ||||
sequence <sequence> | Sequence Number | ah sequence 123
ah sequence { 23, 25, 33 }
ah sequence != 23-33
|
Esp
esp match | |||||
---|---|---|---|---|---|
spi <value> | esp spi 111
esp spi != 111-222
esp spi { 111, 122 }
| ||||
sequence <sequence> | Sequence Number | esp sequence 123
esp sequence { 23, 25, 33 }
esp sequence != 23-33
|
Comp
comp match | |||||
---|---|---|---|---|---|
nexthdr <protocol> | Next header protocol (Upper layer protocol) | comp nexthdr != esp
comp nexthdr { esp, ah, comp, udp, udplite, tcp, tcp, dccp, sctp }
| |||
flags <flags> | Flags | comp flags 0x0
comp flags != 0x33-0x45
comp flags { 0x33, 0x55, 0x67, 0x88 }
| |||
cpi <value> | Compression Parameter Index | comp cpi 22
comp cpi != 33-45
comp cpi { 33, 55, 67, 88 }
|
Icmp
icmp match | |||||
---|---|---|---|---|---|
type <type> | ICMP packet type | icmp type { echo-reply, destination-unreachable, source-quench, redirect, echo-request, time-exceeded, parameter-problem, timestamp-request, timestamp-reply, info-request, info-reply, address-mask-request, address-mask-reply, router-advertisement, router-solicitation }
| |||
code
|
ICMP packet code | icmp code 111
icmp code != 33-55
icmp code { 2, 4, 54, 33, 56 }
| |||
checksum <value> | ICMP packet checksum | icmp checksum 12343
icmp checksum != 11-343
icmp checksum { 1111, 222, 343 }
| |||
id <value> | ICMP packet id | icmp id 12343
icmp id != 11-343
icmp id { 1111, 222, 343 }
| |||
sequence <value> | ICMP packet sequence | icmp sequence 12343
icmp sequence != 11-343
icmp sequence { 1111, 222, 343 }
| |||
mtu <value> | ICMP packet mtu | icmp mtu 12343
icmp mtu != 11-343
icmp mtu { 1111, 222, 343 }
| |||
gateway <value> | ICMP packet gateway | icmp gateway 12343
icmp gateway != 11-343
icmp gateway { 1111, 222, 343 }
|
Icmpv6
icmpv6 match | |||||
---|---|---|---|---|---|
type <type> | ICMPv6 packet type | icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, parameter-problem, mld2-listener-report }
| |||
code
|
ICMPv6 packet code | icmpv6 code 4
icmpv6 code 3-66
icmpv6 code { 5, 6, 7 }
| |||
checksum <value> | ICMPv6 packet checksum | icmpv6 checksum 12343
icmpv6 checksum != 11-343
icmpv6 checksum { 1111, 222, 343 }
| |||
id <value> | ICMPv6 packet id | icmpv6 id 12343
icmpv6 id != 11-343
icmpv6 id { 1111, 222, 343 }
| |||
sequence <value> | ICMPv6 packet sequence | icmpv6 sequence 12343
icmpv6 sequence != 11-343
icmpv6 sequence { 1111, 222, 343 }
| |||
mtu <value> | ICMPv6 packet mtu | icmpv6 mtu 12343
icmpv6 mtu != 11-343
icmpv6 mtu { 1111, 222, 343 }
| |||
max-delay <value> | ICMPv6 packet max delay | icmpv6 max-delay 33-45
icmpv6 max-delay != 33-45
icmpv6 max-delay { 33, 55, 67, 88 }
|
Ether
ether match | |||||
---|---|---|---|---|---|
saddr <mac address> | Source mac address | ether saddr 00:0f:54:0c:11:04
| |||
type <type> | ether type vlan
|
Dst
dst match | |||||
---|---|---|---|---|---|
nexthdr <proto> | Next protocol header | dst nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp }
dst nexthdr 22
dst nexthdr != 33-45
| |||
hdrlength <length> | Header Length | dst hdrlength 22
dst hdrlength != 33-45
dst hdrlength { 33, 55, 67, 88 }
|
Frag
frag match | |||||
---|---|---|---|---|---|
nexthdr <proto> | Next protocol header | frag nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp, icmp }
frag nexthdr 6
frag nexthdr != 50-51
| |||
reserved <value> | frag reserved 22
frag reserved != 33-45
frag reserved { 33, 55, 67, 88 }
| ||||
frag-off <value> | frag frag-off 22
frag frag-off != 33-45
frag frag-off { 33, 55, 67, 88 }
| ||||
more-fragments <value> | frag more-fragments 0
frag more-fragments 0
| ||||
id <value> | frag id 1
frag id 33-45
|
Hbh
hbh match | |||||
---|---|---|---|---|---|
nexthdr <proto> | Next protocol header | hbh nexthdr { udplite, comp, udp, ah, sctp, esp, dccp, tcp, icmpv6 }
hbh nexthdr 22
hbh nexthdr != 33-45
| |||
hdrlength <length> | Header Length | hbh hdrlength 22
hbh hdrlength != 33-45
hbh hdrlength { 33, 55, 67, 88 }
|
Mh
mh match | |||||
---|---|---|---|---|---|
nexthdr <proto> | Next protocol header | mh nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp }
mh nexthdr 22
mh nexthdr != 33-45
| |||
hdrlength <length> | Header Length | mh hdrlength 22
mh hdrlength != 33-45
mh hdrlength { 33, 55, 67, 88 }
| |||
type <type> | mh type { binding-refresh-request, home-test-init, careof-test-init, home-test, careof-test, binding-update, binding-acknowledgement, binding-error, fast-binding-update, fast-binding-acknowledgement, fast-binding-advertisement, experimental-mobility-header, home-agent-switch-message }
mh type home-agent-switch-message
mh type != home-agent-switch-message
| ||||
reserved <value> | mh reserved 22
mh reserved != 33-45
mh reserved { 33, 55, 67, 88 }
| ||||
checksum <value> | mh checksum 22
mh checksum != 33-45
mh checksum { 33, 55, 67, 88 }
|
Rt
rt match | |||||
---|---|---|---|---|---|
nexthdr <proto> | Next protocol header | rt nexthdr { udplite, ipcomp, udp, ah, sctp, esp, dccp, tcp, ipv6-icmp }
rt nexthdr 22
rt nexthdr != 33-45
| |||
hdrlength <length> | Header Length | rt hdrlength 22
rt hdrlength != 33-45
rt hdrlength { 33, 55, 67, 88 }
| |||
type <type> | rt type 22
rt type != 33-45
rt type { 33, 55, 67, 88 }
| ||||
seg-left <value> | rt seg-left 22
rt seg-left != 33-45
rt seg-left { 33, 55, 67, 88 }
|
Vlan
vlan match | |||||
---|---|---|---|---|---|
id <value> | Vlan tag ID | vlan id 4094
vlan id 0
| |||
cfi <value> | vlan cfi 0
vlan cfi 1
| ||||
pcp <value> | vlan pcp 7
vlan pcp 3
|
Arp
arp match | |||||
---|---|---|---|---|---|
ptype <value> | Payload type | arp ptype 0x0800
| |||
htype <value> | Header type | arp htype 1
arp htype != 33-45
arp htype { 33, 55, 67, 88 }
| |||
hlen <length> | Header Length | arp hlen 1
arp hlen != 33-45
arp hlen { 33, 55, 67, 88 }
| |||
plen <length> | Payload length | arp plen 1
arp plen != 33-45
arp plen { 33, 55, 67, 88 }
| |||
operation <value> | arp operation { nak, inreply, inrequest, rreply, rrequest, reply, request }
|
Ct
ct match | |||||
---|---|---|---|---|---|
state <state> | State of the connection | ct state { new, established, related, untracked }
ct state != related
ct state established
ct state 8
| |||
direction <value> | Direction of the packet relative to the connection | ct direction original
ct direction != original
ct direction { reply, original }
| |||
status <status> | Status of the connection | ct status expected
(ct status & expected) != expected
ct status { expected, seen-reply, assured, confirmed, snat, dnat, dying }
| |||
mark [set] | Mark of the connection | ct mark 0
ct mark or 0x23 == 0x11
ct mark or 0x3 != 0x1
ct mark and 0x23 == 0x11
ct mark and 0x3 != 0x1
ct mark xor 0x23 == 0x11
ct mark xor 0x3 != 0x1
ct mark 0x00000032
ct mark != 0x00000032
ct mark 0x00000032-0x00000045
ct mark != 0x00000032-0x00000045
ct mark { 0x32, 0x2222, 0x42de3 }
ct mark { 0x32-0x2222, 0x4444-0x42de3 }
ct mark set 0x11 xor 0x1331
ct mark set 0x11333 and 0x11
ct mark set 0x12 or 0x11
ct mark set 0x11
ct mark set mark
ct mark set mark map { 1 : 10, 2 : 20, 3 : 30 }
| |||
expiration | Connection expiration time | ct expiration 30
ct expiration 30s
ct expiration != 233
ct expiration != 3m53s
ct expiration 33-45
ct expiration 33s-45s
ct expiration != 33-45
ct expiration != 33s-45s
ct expiration { 33, 55, 67, 88 }
ct expiration { 1m7s, 33s, 55s, 1m28s }
| |||
helper "<helper>" | Helper associated with the connection | ct helper "ftp"
| |||
[original | reply] bytes <value> | ct original bytes > 100000
ct bytes > 100000
| ||||
[original | reply] packets <value> | ct reply packets < 100
| ||||
[original | reply] ip saddr <ip source address> | ct original ip saddr 192.168.0.1
ct reply ip saddr 192.168.0.1
ct original ip saddr 192.168.1.0/24
ct reply ip saddr 192.168.1.0/24
| ||||
[original | reply] ip daddr <ip destination address> | ct original ip daddr 192.168.0.1
ct reply ip daddr 192.168.0.1
ct original ip daddr 192.168.1.0/24
ct reply ip daddr 192.168.1.0/24
| ||||
[original | reply] l3proto <protocol> | ct original l3proto ipv4
| ||||
[original | reply] protocol <protocol> | ct original protocol 6
| ||||
[original | reply] proto-dst <port> | ct original proto-dst 22
| ||||
[original | reply] proto-src <port> | ct reply proto-src 53
| ||||
count [over] <number of connections> | ct count over 2
tcp dport 22 add @ssh_flood { ip saddr ct count over 2 } reject
[ which requires an existing ssh_flood set, ie. add set filter ssh_flood { type ipv4_addr; flags dynamic; } ]
|
Meta
meta matches packet by metainformation.
meta match | |||||
---|---|---|---|---|---|
iifname <input interface name> | Input interface name | meta iifname "eth0"
meta iifname != "eth0"
meta iifname { "eth0", "lo" }
meta iifname "eth*"
| |||
oifname <output interface name> | Output interface name | meta oifname "eth0"
meta oifname != "eth0"
meta oifname { "eth0", "lo" }
meta oifname "eth*"
| |||
iif <input interface index> | Input interface index | meta iif eth0
meta iif != eth0
| |||
oif <output interface index> | Output interface index | meta oif lo
meta oif != lo
meta oif { eth0, lo }
| |||
iiftype <input interface type> | Input interface type | meta iiftype { ether, ppp, ipip, ipip6, loopback, sit, ipgre }
meta iiftype != ether
meta iiftype ether
| |||
oiftype <output interface type> | Output interface hardware type | meta oiftype { ether, ppp, ipip, ipip6, loopback, sit, ipgre }
meta oiftype != ether
meta oiftype ether
| |||
length <length> | Length of the packet in bytes | meta length 1000
meta length != 1000
meta length > 1000
meta length 33-45
meta length != 33-45
meta length { 33, 55, 67, 88 }
meta length { 33-55, 67-88 }
| |||
protocol <protocol> | ethertype protocol | meta protocol ip
meta protocol != ip
meta protocol { ip, arp, ip6, vlan }
| |||
nfproto <protocol> | meta nfproto ipv4
meta nfproto != ipv6
meta nfproto { ipv4, ipv6 }
| ||||
l4proto <protocol> | meta l4proto 22
meta l4proto != 233
meta l4proto 33-45
meta l4proto { 33, 55, 67, 88 }
meta l4proto { 33-55 }
| ||||
mark [set] | Packet mark | meta mark 0x4
meta mark 0x00000032
meta mark and 0x03 == 0x01
meta mark and 0x03 != 0x01
meta mark != 0x10
meta mark or 0x03 == 0x01
meta mark or 0x03 != 0x01
meta mark xor 0x03 == 0x01
meta mark xor 0x03 != 0x01
meta mark set 0xffffffc8 xor 0x16
meta mark set 0x16 and 0x16
meta mark set 0xffffffe9 or 0x16
meta mark set 0xffffffde and 0x16
meta mark set 0x32 or 0xfffff
meta mark set 0xfffe xor 0x16
| |||
priority [set] <priority> | tc class id | meta priority none
meta priority 0x1:0x1
meta priority 0x1:0xffff
meta priority 0xffff:0xffff
meta priority set 0x1:0x1
meta priority set 0x1:0xffff
meta priority set 0xffff:0xffff
| |||
skuid <user id> | UID associated with originating socket | meta skuid { bin, root, daemon }
meta skuid root
meta skuid != root
meta skuid lt 3000
meta skuid gt 3000
meta skuid eq 3000
meta skuid 3001-3005
meta skuid != 2001-2005
meta skuid { 2001-2005 }
| |||
skgid <group id> | GID associated with originating socket | meta skgid { bin, root, daemon }
meta skgid root
meta skgid != root
meta skgid lt 3000
meta skgid gt 3000
meta skgid eq 3000
meta skgid 3001-3005
meta skgid != 2001-2005
meta skgid { 2001-2005 }
| |||
rtclassid <class> | Routing realm | meta rtclassid cosmos
| |||
pkttype <type> | Packet type | meta pkttype broadcast
meta pkttype != broadcast
meta pkttype { broadcast, unicast, multicast }
| |||
cpu <cpu index> | CPU ID | meta cpu 1
meta cpu != 1
meta cpu 1-3
meta cpu != 1-2
meta cpu { 2,3 }
meta cpu { 2-3, 5-7 }
| |||
iifgroup <input group> | Input interface group | meta iifgroup 0
meta iifgroup != 0
meta iifgroup default
meta iifgroup != default
meta iifgroup { default }
meta iifgroup { 11,33 }
meta iifgroup { 11-33 }
| |||
oifgroup <group> | Output interface group | meta oifgroup 0
meta oifgroup != 0
meta oifgroup default
meta oifgroup != default
meta oifgroup { default }
meta oifgroup { 11,33 }
meta oifgroup { 11-33 }
| |||
cgroup <group> | meta cgroup 1048577
meta cgroup != 1048577
meta cgroup { 1048577, 1048578 }
meta cgroup 1048577-1048578
meta cgroup != 1048577-1048578
meta cgroup { 1048577-1048578 }
|
Statements
statement is the action performed when the packet match the rule. It could be terminal and non-terminal. In a certain rule we can consider several non-terminal statements but only a single terminal statement.
Verdict statements
The verdict statement alters control flow in the ruleset and issues policy decisions for packets. The valid verdict statements are:
- accept: Accept the packet and stop the remain rules evaluation.
- drop: Drop the packet and stop the remain rules evaluation.
- queue: Queue the packet to userspace and stop the remain rules evaluation.
- continue: Continue the ruleset evaluation with the next rule.
- return: Return from the current chain and continue at the next rule of the last chain. In a base chain it is equivalent to accept
- jump <chain>: Continue at the first rule of <chain>. It will continue at the next rule after a return statement is issued
- goto <chain>: Similar to jump, but after the new chain the evaluation will continue at the last chain instead of the one containing the goto statement
Log
log statement | |||||
---|---|---|---|---|---|
level [over] <value> <unit> [burst <value> <unit>] | Log level | log
log level emerg
log level alert
log level crit
log level err
log level warn
log level notice
log level info
log level debug
| |||
group <value> [queue-threshold <value>] [snaplen <value>] [prefix "<prefix>"] | log prefix aaaaa-aaaaaa group 2 snaplen 33
log group 2 queue-threshold 2
log group 2 snaplen 33
|
Reject
The default reject will be the ICMP type port-unreachable. The icmpx is only used for inet family support.
More information on the Rejecting_traffic page.
reject statement | |||||
---|---|---|---|---|---|
with <protocol> type <type> | reject
reject with icmp type host-unreachable
reject with icmp type net-unreachable
reject with icmp type prot-unreachable
reject with icmp type port-unreachable
reject with icmp type net-prohibited
reject with icmp type host-prohibited
reject with icmp type admin-prohibited
reject with icmpv6 type no-route
reject with icmpv6 type admin-prohibited
reject with icmpv6 type addr-unreachable
reject with icmpv6 type port-unreachable
reject with icmpx type host-unreachable
reject with icmpx type no-route
reject with icmpx type admin-prohibited
reject with icmpx type port-unreachable
ip protocol tcp reject with tcp reset
|
Counter
counter statement | |||||
---|---|---|---|---|---|
packets <packets> bytes <bytes> | counter
counter packets 0 bytes 0
|
Limit
limit statement | |||||
---|---|---|---|---|---|
rate [over] <value> <unit> [burst <value> <unit>] | Rate limit | limit rate 400/minute
limit rate 400/hour
limit rate over 40/day
limit rate over 400/week
limit rate over 1023/second burst 10 packets
limit rate 1025 kbytes/second
limit rate 1023000 mbytes/second
limit rate 1025 bytes/second burst 512 bytes
limit rate 1025 kbytes/second burst 1023 kbytes
limit rate 1025 mbytes/second burst 1025 kbytes
limit rate 1025000 mbytes/second burst 1023 mbytes
|
Nat
nat statement | |||||
---|---|---|---|---|---|
dnat to <destination address> | Destination address translation | dnat to 192.168.3.2
dnat to ct mark map { 0x00000014 : 1.2.3.4 }
| |||
snat to <ip source address> | Source address translation | snat to 192.168.3.2
snat to 2001:838:35f:1::-2001:838:35f:2:::100
| |||
masquerade [<type>] [to :<port>] | Masquerade | masquerade
masquerade persistent,fully-random,random
masquerade to :1024
masquerade to :1024-2048
|
Queue
queue statement | |||||
---|---|---|---|---|---|
num <value> <scheduler> | queue
queue num 2
queue num 2-3
queue num 4-5 fanout bypass
queue num 4-5 fanout
queue num 4-5 bypass
|
Extras
Export Configuration
% nft export (xml | json)
Monitor Events
Monitor events from Netlink creating filters.
% nft monitor [new | destroy] [tables | chains | sets | rules | elements] [xml | json]
Nft scripting
List ruleset
% nft list ruleset
Flush ruleset
% nft flush ruleset
Load ruleset
Create a command batch file and load it with the nft interpreter,
% echo "flush ruleset" > /etc/nftables.rules
% echo "add table filter" >> /etc/nftables.rules
% echo "add chain filter input" >> /etc/nftables.rules
% echo "add rule filter input meta iifname lo accept" >> /etc/nftables.rules
% nft -f /etc/nftables.rules
or create an executable nft script file,
% cat << EOF > /etc/nftables.rules
> #!/usr/local/sbin/nft -f
> flush ruleset
> add table filter
> add chain filter input
> add rule filter input meta iifname lo accept
> EOF
% chmod u+x /etc/nftables.rules
% /etc/nftables.rules
or create an executable nft script file from an already created ruleset,
% nft list ruleset > /etc/nftables.rules
% nft flush ruleset
% nft -f /etc/nftables.rules
Examples
Simple IP/IPv6 Firewall
flush ruleset
table firewall {
chain incoming {
type filter hook input priority 0; policy drop;
# established/related connections
ct state established,related accept
# loopback interface
iifname lo accept
# icmp
icmp type echo-request accept
# open tcp ports: sshd (22), httpd (80)
tcp dport { ssh, http } accept
}
}
table ip6 firewall {
chain incoming {
type filter hook input priority 0; policy drop;
# established/related connections
ct state established,related accept
# invalid connections
ct state invalid drop
# loopback interface
iifname lo accept
# icmp
# routers may also want: mld-listener-query, nd-router-solicit
icmpv6 type { echo-request, nd-neighbor-solicit } accept
# open tcp ports: sshd (22), httpd (80)
tcp dport { ssh, http } accept
}
}