4

Context : https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains If a packet is accepted and there is another chain, bearing the same hook type and with a later priority, then the packet will subsequently traverse this other chain. Hence, an accept verdict - be it by way of a rule or the default chain policy - isn't necessarily final. However, the same is not true of packets that are subjected to a drop verdict. Instead, drops take immediate effect, with no further rules or chains being evaluated.

I wanted to have different project modules to have there tables and chains, For example firewalld has its tables. I want my table, each table will be maintained by individual teams/modules. There can be duplicate rules in chains from that tables. Now I think most of times we know what to accept and we deny everything that we don't know. With above nftable design, if packet is accepted in one of the chain, it goes to next chain which is of higher priority. Processing don't stop after accept. for me next chain was firewalld and since my rules are not present in firewalld chain it dropped that packet.

nft monitor 
trace id 1cd90444 ip filter INPUT packet: iif "ens192" ether saddr 00:0c:29:1b:82:51 ether daddr 00:50:56:9c:b6:7e ip saddr 10.221.39.90 ip daddr 10.221.39.50 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 55469 ip length 60 tcp sport 47944 tcp dport 2049 tcp flags == syn tcp window 29200                                 
trace id 1cd90444 ip filter INPUT rule tcp dport 2049 meta nftrace set 1 (verdict continue)               
trace id 1cd90444 ip filter INPUT rule tcp dport 2049 accept (verdict accept)                             
trace id 1cd90444 inet firewalld filter_INPUT packet: iif "ens192" ether saddr 00:0c:29:1b:82:51 ether daddr 00:50:56:9c:b6:7e ip saddr 10.221.39.90 ip daddr 10.221.39.50 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 55469 ip protocol tcp ip length 60 tcp sport 47944 tcp dport 2049 tcp flags == syn tcp window 29200     
trace id 1cd90444 inet firewalld filter_INPUT rule jump filter_INPUT_POLICIES_pre (verdict jump filter_INPUT_POLICIES_pre)
trace id 1cd90444 inet firewalld filter_INPUT_POLICIES_pre rule jump filter_IN_policy_allow-host-ipv6 (verdict jump filter_IN_policy_allow-host-ipv6) 
trace id 1cd90444 inet firewalld filter_IN_policy_allow-host-ipv6 rule jump filter_IN_policy_allow-host-ipv6_pre (verdict jump filter_IN_policy_allow-host-ipv6_pre)
trace id 1cd90444 inet firewalld filter_IN_policy_allow-host-ipv6_pre verdict continue 
...
trace id 1cd90444 inet firewalld filter_INPUT_POLICIES_post verdict continue                              
trace id 1cd90444 inet firewalld filter_INPUT rule reject with icmpx type admin-prohibited (verdict drop)     

See in ip filter INPUT there is verdict accept then later firewalld dropped it. It looks like accept rule must be last i.e. in chain which is of highest priority. I can make my table of higher priority which will bypass firewalld table, But as I mentioned there can be more than one table which will decide to accept packets and if next tables dont have that same accept, overall result will be drop (Because last table have drop rule).

Please correct me, chains/rules in lower priority tables are effectively useless. I am not able to understand its use. Can someone please example how low priority chains are useful and how to create different tables for different projects.

iptables did not had this problem, there Accept is accept, which projects/firewalls needs nftables kind of designs ?

0

1 Answer 1

2

I'm as surprised as you when I hit the same problem today.

Quick introduction: I work on writing my own system utilizing namespaces and networking on Linux. Due to that I have to manage my own rules inside nftables. Because firewalld is also configured on the system and it blocks traffic I want to allow, initially I thought that the solution might be to create chain of higher priority (lower priority number).

You can't imagine how I was surprised after finding that my traffic is blocked by the firewalld despite doing that. Surprisingly your question is the only one mentioning this problem I found on the internet.

As you said it is so natural to block everything and accept only the traffic you wan't to accept. And then, different applications running on the operating system, managing firewall rules should be independent. It should look like this:

# rules for app X
accept input on port 80
forward 192.168.1.1:80 to 10.10.0.1:8080

# rules for app Y
accept input on port 22

# default action
drop whatever reached this point

It is a nonsense that in the current implementation, rules managed by app Y must accept those managed by app X, because otherwise traffic is dropped. On the other hand, as documentation states, drop action is immediate. It means, that what firewalls usually do: drop everything by default, closes the doors for traffic configured by other apps.

Initially I thought that it is implemented this way by nftables so my idea was to write my own firewall connecting directly to the netfilter module of the kernel, so I could inject my rules before nftables takes the control.

But sadly, the limitation we are discussing comes from the netfilter itself: https://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-4.html#ss4.5

If NF_ACCEPT, the next hook attached to that point will be called.
If NF_DROP, the packet is dropped.

So whenever any hook decides to drop the package it is dropped forever. But if it is accepted, probably it will be dropped later if any other app injects its own logic.

This is crappy, it means that different applications like libvirt, docker, firewalld, iptables or custom apps have to fight for the priority to accept the traffic they need. And if anything in the chain drops unrelated traffic by default, like firewalld does, we have a mess.

The decision to design netfilter this way seems so crappy to me... and looks like there is no workaround. It disables the possibility of having many firewalls on the system managing different aspects. Whatever firewall you install it has a monopoly.

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .