About Hooks and Chains
Hooks are points in a system where packets can be intercepted for processing. These hooks are
where nftables
applies chains and rules that decide what happens to a packet.
Different hooks are available depending on the address family applied to a table.
The following table shows the hooks available to each address family.
Address Family | Hook | Description |
---|---|---|
IP, IPv6, inet / Bridge |
prerouting |
Processes all incoming packets before routing decisions. |
input |
Handles packets destined for the local system. |
|
forward |
Manages packets being forwarded to another host. |
|
output |
Processes packets originating from the local system. |
|
postrouting |
Deals with all outgoing packets after routing. |
|
ingress |
Manages incoming packets before the prerouting, available from Linux kernel 5.10 for inet family. |
|
ARP |
input |
Processes packets for the local system. |
output |
Handles packets sent from the local system. |
|
Netdev |
ingress |
Processes incoming packets after network taps, such as tcpdump, before layer 3 handling. |
egress |
Manages outgoing packets after layer 3 handling but before final network exit. |
nftables
includes
the following chain types:
- Base Chains: These are chains directly built on a hook. For example, a base chain
named
myinput
might be linked to the inet input hook for IPv4 or IPv6 packets arriving at the local system. - Regular Chains: These are chains that jump from base chains or other regular chains. They aren't built directly at a hook but can be part of the decision-making process within a base chain.
filter
: Primarily used for packet filtering, such as whether to permit or block packets based on various criteria such as source and destination IP, ports, protocols, and so on. This chain type works with all address families and their hooks.nat
: Primarily used to change IP addresses, ports, or both in packet headers for NAT operations. This includes changes to Source NAT (SNAT) for outgoing traffic and Destination NAT (DNAT) for incoming traffic. This chain type can be configured with ip, ipv6, and inet address families and can take the prerouting, input, output, and postrouting hooks.route
: Primarily used for routing decisions such as altering a routing table or marking packets for specific routing policies. This chain type can be used with ip and ipv6 address families and can take the output hook only.
When using the ingress or egress hooks, specify a network interface name as a string with the
device
parameter. Any ingress or egress chains only filters traffic from
the interface specified in the device parameter.
The priority parameter uses a signed integer or a standard priority name to determine the order in which chains with the same hook are processed. Chains process from lower priority values or names to higher priority values or names.
The following table shows priority names and values for each associated address family and hook type.
Name | Value | Family | Hooks |
---|---|---|---|
raw |
-300 |
ip, ip6, inet | all |
mangle |
-150 |
ip, ip6, inet | all |
dsnat |
-100 |
ip, ip6, inet | prerouting |
filter |
0 |
ip, ip6, inet, arp, netdev | all |
security |
50 |
ip, ip6, inet | all |
srcnat |
100 |
ip, ip6, inet | postrouting |
The following table shows priority names and values for the bridge address family and hook type.
Name | Value | Hooks |
---|---|---|
dsnat |
-300 |
prerouting |
filter |
-200 |
all |
out |
100 |
output |
srcnat |
300 |
postrouting |
You can also choose to set a policy on a chain that defines whether to
accept
or drop
a packet when none of the rules defined on
the chain matches the packet. By default, base chains accept all packets. However, setting a
policy to drop all traffic not explicitly allowed by a chain is good practice for security
reasons.
Creating Base Chains
nftable
base chains in memory, do the following:
-
Create a chain for a specific address family type and table using the following syntax:
sudo nft add chain <address_family> <table_name> <chain_name>{ type <chain_type> hook <hook_type> device <network_interface_name> priority <priority> policy <policy> comment <comment> ; }
In the previous,- <address_family> can be
ip
,ip6
,inet
,arp
,bridge
, ornetdev
. Allnftables
objects are in one of these address family. For more information about these address families, see thenft(8)
manual page. - <table_name> is the name of the table. Tables are containers for chains, which in turn are containers for rules.
- <chain_name> is an arbitrary name for the chain. People migrating from iptables based firewalls often use traditional iptables naming.
- <chain_type> is the chain type. Valid values for base chains are
filter
,nat
, androute
. For more information, see About Hooks and Chains. - <hook_type> is the hook type. Possible values depend on the selected address family and chain type. For more information, see About Hooks and Chains.
- <network_interface_name> is the network interface name for the device parameter. This parameter is only required when using the ingress or egress hooks.
- <priority> is the priority value or name for the chain. Priority depends on the selected address family and hook type. For more information, see About Hooks and Chains.
- <policy> is the action taken if all rules defined on the chain fail to
match the packet. Valid values are
accept
ordrop
. If not specified, the default value isaccept
.
For example, the following command creates a chain in themytable
table calledmychain
with theinet
family. The chain type isfilter
, the hook isinput
, and the priority is0
. Finally, the policy is set to drop all packets that don't match a rule:sudo nft add chain inet mytable mychain "{ type filter hook input priority 0 ; policy drop ; }"
- <address_family> can be
- Do the following:
- To view all chains, do the following:
sudo nft list chains
- To view a single chain, do the following:
sudo nft list chain <address_family> <table_name>
<chain_name>
- To view all chains, do the following: