public inbox for netfilter@vger.kernel.org
 help / color / mirror / Atom feed
From: Mathias Dufresne <mathias.dufresne@gmail.com>
To: Florian Westphal <fw@strlen.de>
Cc: netfilter@vger.kernel.org
Subject: Re: Fwd: [nftables] is it possible to declare multiple tables for a given family type?
Date: Mon, 2 Mar 2026 16:32:03 +0100	[thread overview]
Message-ID: <cce93ef0-8b7e-4732-9fcd-25c5d935aca4@gmail.com> (raw)
In-Reply-To: <aaTRgeXDaznuZvgh@strlen.de>


Le 2026-03-02 à 00:53, Florian Westphal a écrit :
> Mathias Dufresne <mathias.dufresne@gmail.com> wrote:
>> Le 2026-03-01 à 14:52, Florian Westphal a écrit :
>> The goal would have been to have one table per service containing
>> everything related to that specific service and nothing else.
> I see.  One way to do it is to include such sub-configurations
> from a central ruleset file.
>
>>> Just like in iptables, 'accept' in raw table just means packets
>>> continue to travel through the stack, you need to accept them in mangle
>>> and again in filter table.
>> Do you meant the network stack or the nftables' rules stack?
> The former.  E.g. (staying with iptables, its same in nftables):
>
> if a packet is accepted in mangle prerouting, it will continue and will
> eventually make it to mangle input or forward.

A packet accepted in a hook is removed from that hook and it does pass 
through the rules after the one it matched?

And this same packet will have to pass through the potentially remaining 
hooks.

>
>>> Also, base chains (those with a line like
>>> 'type filter hook input priority filter; policy accept;') always cause a
>>> slow-down: they divert all packets into the nftables vm, so its a good idea to
>>> minimize the amount of times this happens per packet.
>> Again, I'm lost there... I'm certainly lacking the basic knowledge to
>> understand :/
> No problem.  Consider an nftables ruleset that has ONLY
> chain foo {
> 	some rule ..
> }
>
> This ruleset is very fast.  And useless.  Because it never processes
> any packets.
>
> In iptables, this isn't possible, because all tables have
> builtin-chains: PREROUTING, INPUT, and so on.
>
> In nftables, one has to manually declare which chains are the 'starting
> point' for packets passing through the networking stack.
>
> E.g. type filter hook input priority filter; policy accept;
>
> tells that you'd like semantics that are identical to iptables filter
> INPUT chain: it will see incoming packets that have passed through the
> routing step and are destined for the local host.
>
> Makes sense so far?
>
> This means, ALL incoming local packets will appear in this chain
> (minus those that were dropped earlier on in the stack of course).
>
> Example:
> 	chain myinput {
> 		type filter hook input priority filter; policy accept;
>
> 		tcp dport 22 jump ssh
> 		tcp dport { 80, 433 } jump httpd
> 	}
> 	...
>
> ... will be faster than making
> 'ssh' and 'httpd' two independent 'type filter hook input' chains.
>
> Why?  Because in the case above, all incoming packets pass though
> 'myinput', then only a small subset gets passed on to ssh and httpd,
> respectively.
>
> If you make the two user chains base chains ('type filter...', both reveive
> all the traffic).  In case you haven't tried it: See if 'nft list hooks'
> provies some assistance to you.
I'll try that very soon as my understanding is that a packet matching a 
rule with jump is removed from the hook and passed to the jump chain. If 
I understand correctly this will be an efficient way to accelerate the 
filtering process while obtaining readable rules with hooks sorting 
packets per service and service chains dealing with targets to accept or 
refuse them. I love that : )
>> --------------------------------------------------------------------
>>
>> Here is a working single table to SSH the firewall and one LAN through
>> that firewall:
>>
>> table ip filter_them_all {
>>     chain ip_log_svc_administrative_services/ssh {
>>       counter packets 0 bytes 0 log prefix "Accept ip SVC for
>> 'administrative services/ssh': " group 2
>>       counter packets 0 bytes 0 accept
>>     }
>>     chain input {
>>       type filter hook input priority filter; policy accept;
>>       ct state {established,related} counter log prefix "ACCEPT CT for
>> INPUT" group 2
>>       ct state {established,related} accept
>>       iif vdi-lan ip daddr 10.9.9.252/32 tcp dport 22 ct state new jump ip_log_svc_administrative_services/ssh
>>       iif vdi-lan oif svc-web ip daddr 10.54.80.0/24 tcp dport 22 ct state new jump ip_log_svc_administrative_services/ssh
>>       counter packets 0 bytes 0 log prefix "REFUSED INPUT packet as it reached the end of filtering rules stack." group 2
>>       counter packets 0 bytes 0 drop
>>     }
>>     chain forward {
>>       type filter hook forward priority filter; policy accept;
>>       ct state {established,related} counter log prefix "ACCEPT CT for > FORWARD"  group 2
> I'd suggest to add some rate limiting for your log lines.
I'll think about it but those logs yesterday were mainly there to help 
me understand what was happening with my packets.
>
>>       # these two are working and can't be omitted
>>       iif vdi-lan oif svc-web ip daddr 10.54.80.0/24 tcp dport 22  log prefix "ACCEPT FORWARD for ssh" group 2
>>       iif vdi-lan oif svc-web ip daddr 10.54.80.0/24 tcp dport 22 accept
> If you don't want to limit, you can combine this into one line, you can
> 'log prefix ... accept' in nftables.
Did you proposed that merging for cosmetic or performance reason?
>
>>     chain output {
>>       type filter hook output priority filter; policy accept;
>>       ct state {established,related} counter log prefix "ACCEPT CT for
>> OUTPUT" group 2
>>       ct state {established,related} accept
>>       counter packets 0 bytes 0 log prefix "REFUSED OUTPUT packet as it
>> reached the end of filtering rules stack." group 2
>>       counter packets 0 bytes 0 drop
> Are you sure you need output filtering?  This prevents e.g. dns
> resolution, ntp (time) refresh etc.
As my goal is to automate nftables rules I'll try to manage a tool 
capable of filtering everything. For my home servers, most certainly I 
won't...
>
>> table ip tracked_packets {
>>     chain input {
>>       type filter hook input priority 300; policy accept;
>>       ct state {established,related} counter log prefix "ACCEPT CT for
>> INPUT" group 2
>>       ct state {established,related} accept
>>     }
>>     chain input {
>>       type filter hook input priority 310; policy accept;
>>       iif vdi-lan             ip daddr 10.9.9.252/32 tcp dport 22 ct
>> state new jump ip_log_svc_administrative_services/ssh
>>       iif vdi-lan oif svc-web ip daddr 10.54.80.0/24 tcp dport 22 ct
>> state new jump ip_log_svc_administrative_services/ssh
>>     }
> This works, but as you found there is no 'memory' and all chains have
> to accept all packets for them to make it though.

OK. Several chain using a given hook, even if a packet if matched in 
early chain it will pass through the others using that same hook (as per 
my understanding)

And so, in your previous example using "jump ssh", this ssh chain shall 
not use hook at all (again, as per my understanding ; )

>
>> His this approach - several filtering tables - valid? I mean I could
>> easily have made errors in the syntax...
> Yes, but I don't consider it a good idea, I also don't think its suited
> for what you have in mind.
>
> If this is about enabling / disabling services, I would use a set for
> that.
>
> set s {
> 	typeof iif . oif . ip daddr . meta l4proto . th dport
> 	flags interval
> }
>
>   chain forward {
>        # these two are working and can't be omitted
>        iif . oif . ip saddr . meta l4proto . th dport @s accept
>
> [ totally untested, for illustrative purposes ... ]

That I don't understand at all but I'll keep somewhere and I'll try to 
understand... later :p

Thank you again for all these information and your time.

Best regards,

mathias


      reply	other threads:[~2026-03-02 15:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <752a3ecd-b379-4b82-8ac1-a64450e14167@gmail.com>
2026-03-01 18:59 ` Fwd: [nftables] is it possible to declare multiple tables for a given family type? Mathias Dufresne
2026-03-01 23:53   ` Florian Westphal
2026-03-02 15:32     ` Mathias Dufresne [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cce93ef0-8b7e-4732-9fcd-25c5d935aca4@gmail.com \
    --to=mathias.dufresne@gmail.com \
    --cc=fw@strlen.de \
    --cc=netfilter@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox