I’m in the process of learning how to create advanced firewall rules and am having a hard time understanding the basic structure of the tables used in the NFT backend.
Among others, there are these three address families (see man NFT(8)
):
ADDRESS FAMILIES
Address families determine the type of packets which are processed. For each address family, the kernel contains so called hooks at specific stages of the packet processing paths, which invoke nftables if rules for these hooks exist.ip IPv4 address family. ip6 IPv6 address family. inet Internet (IPv4/IPv6) address family.
There are exactly three tables that match these address families:
# nft list tables
table inet firewalld
table ip firewalld
table ip6 firewalld
Question #1: Since when do we define table names with spaces?!
Question #2: Since when do we not have to use quotation marks around names with spaces in between?!
Anyway. So one would assume that table ip firewalld
has the chains and rules for IPv4, table ip6 firewalld
has the chains and rules for IPv6, and table inet firewalld
has the chains and rules that apply to both IPv4 and IPv6, correct? Wrong!
What you find is that all rules, even if they apply only to IPv4 or only to IPv6, appear in the table inet firewalld
. The other two tables are basically unused.
Worse, the table ip firewalld
has chains that apply only to IPv6:
chain nat_PRE_policy_allow-host-ipv6 {
jump nat_PRE_policy_allow-host-ipv6_pre
jump nat_PRE_policy_allow-host-ipv6_log
jump nat_PRE_policy_allow-host-ipv6_deny
jump nat_PRE_policy_allow-host-ipv6_allow
jump nat_PRE_policy_allow-host-ipv6_post
}
Question #3: Why has that been set up like this?
Question #4: What is the logic behind it?
Question #5: How would one define/insert a low priority rule that does what this old iptables rule has done: Drop all outbound traffic that has not explictely been allowed?
$ iptables -P OUTPUT DROP