Firewall4 / NFtables Tips and Tricks

A soft link to fw3 is also installed for backward compatibility, so probably safest to refrerence fw3 until more packages are adapted to firewall4.

2 Likes

I just upgraded from a previous snapshot build with iptables to a new snapshot with nftables (firewall4 on an Archer C6 v3, mt7621, IPv4 only).

I did the upgrade while preserving settings using a sysupgrade image I built myself from master (default make menuconfig for the device with the addition of Luci Collection, Wireguard plus some CLI tools such as nano and iperf3).

The upgrade completed successfully, but all network clients lost internet access after the upgrade (however in an ssh session the router itself had internet connection, WAN port was connected, up and running).

I did not have time to troubleshoot, since the rest of the family (wife and daughter) started complaining about internet being offline. I quickly returned to a previous build (iptables) which immediately restored internet connections to all clients.

I will try again another time when I would be able to take the internet connection down for troubleshooting of firewall4.

Meanwhile, is there any sort of migration of the firewall rules from iptables to nftables? I had the assumption that the existing rules would be migrated automatically, but it seems it did not work in my case.

Any tip would be welcome!

1 Like

/etc/config/firewall uses the same syntax for both fw3 and fw4, only additional packages directly calling iptables/ ipset (or maybe /etc/firewall.user) might create issues.

1 Like

Thanks. Would enabling SW/HW flow offload could cause problems? SW flow offload was enabled for iptables before the upgrade.

In theory, no (nftables officially supports flow-offloading, iptables does not (custom patch for OpenWrt)), but I'd nevertheless try it without either (fw4 is new, now is the time to test it and find/ report/ fix any remaining issues).

2 Likes

ongoing and iptables-nft still presents a challenge.

4 Likes

I really would like to do the switch to firewall4 too but since I have multiple upstreams I need mwan3 and there seems to be no mwan4. Is there any alternative that would work with firewall4?

I did the same and everything stopped working. Then I reset it and after setup everything was working.

I still need to further investigate why firewall4(nftables) did not work when upgrading from a previous (but recent) snapshot build with iptables.

For now I was inspecting firewall configurations. Are firewall4 configurations really backward compatible with previous config?

I mean, just looking the "config defaults" section:

My current config (SNAPSHOT r18324-794e8123ce, last with Kernel 5.4):

config defaults
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option synflood_protect '1'
	option flow_offloading '1'
	option flow_offloading_hw '1'

And below is the same section from a snapshot image:

config defaults
	option input ACCEPT
	option output ACCEPT
	option syn_flood 1
	option forward		REJECT
# Uncomment this line to disable ipv6 rules
#	option disable_ipv6	1

At a first glance I noticed for example that the syn flood key is different:

Firewall: option synflood_protect '1'
Firewall 4: option syn_flood 1

I don't think this would be the reason my upgrade did not work, but it raises a flag about how much it is really backwards compatible and it would explain why clean/fresh installs would work.

Thanks!

Are firewall4 configurations really backward compatible with previous config

Yes, they are supposed to. Certain corner case features are still being worked on (wildcard matching, non-contiguous masks - these do not easily map to nftables expressions)

At a first glance I noticed for example that the syn flood key is different:

Both are recognized:
https://git.openwrt.org/?p=project/firewall4.git;a=blob;f=root/usr/share/ucode/fw4.uc;h=8a549e16947cb623398a1fa9d9256276e5b6d8bd;hb=d63cb8950577fd22179423b15cf114e2097bdb05#l1646

2 Likes

I need to add a table for bridge filtering. I can manually add the table and it works, but the syntax to put into /etc/nftables.d/*.nft format isn't documented as far as I can tell.

nft add table bridge filter
nft add chain bridge filter input '{type filter hook input priority 0; }'
nft add chain bridge filter forward '{type filter hook forward priority 0; }'
nft add rule bridge filter input ether type ip udp dport <port #> counter drop
nft add rule bridge filter forward ether type ip udp dport <port #> counter drop

This yields proper blocking of the port. The README in /etc/nftables.d seems to indicate that only chains in inet/fw4 can be added in this manner.

Am I going to need to hotplug a script running the above commands on firewall reload, or is there something else similar to /etc/firewall.user that can be used?

Anything in the *.nft files is inserted into the middle of the table inet fw4 structure, so you can’t have a table in table. I was trying to add a netdev table for ingress, but haven’t decided how to make it sticky.

1 Like

We could add two include statements, one outside of the fw4 table scope and one inside, then let them refer to different paths, e.g. /etc/nftables.d/tables/*.nft and /etc/nftables.d/chains/*.nft

Or perhaps call a nftables.user script at the end of processing that can contain nft add commands to add tables, chains or rules anywhere once the fw4 table is established? More flexible for power users, but maybe more confusing for average users if dealing with two different input syntaxes.

1 Like

Like firewall3's /etc/firewall.user? That is something quite helpful for local modifications, so +1.

1 Like

Like include section in fw3!

I love the way that a script when loaded is atomic, all the rules get put in place all at once. Whereas if you call nft over and over that's not the case. I'd much rather use includes.

2 Likes

Fair enough! I was trying to come up with a way to add advanced custom rules to pre-existing fw4 chains (e.g. mangle_postrouting).

1 Like

I prefer include directories over something like /etc/firewall.user (and other uci-configured includes) because then it is easy to amend the firewall ruleset by just placing files. Given a deep enough directory hierarchy we can also support stuff like pre and post includes, where the former may be useful to setup things used by other chain scoped includes later and the latter could be used to selectively flush/replace/amend parts of the default ruleset without having to patch the firewall templates or disabling the firewall service altogether.

I could imagine a hierarchy like that (the chain includes might be redundant, but I suppose they could be useful):

  • /etc/nftables.d/global-pre/ (before table inet fw4 { ... } declaration)
  • /etc/nftables.d/table-pre/ (before first chain declaration within table inet fw4 { ... })
  • /etc/nftables.d/chain-$name-pre/ (before any rule in chain $name)
  • /etc/nftables.d/chain-$name-post/ (after any rule in chain $name)
  • /etc/nftables.d/table-post/ (after last chain declaration within table inet fw4 { ... })
  • /etc/nftables.d/global-post/ (after table inet fw4 { ... } declaration)

If we're worried about the many include .../*.nft statements cluttering the ruleset we could only conditionally add them if we find related files in /etc/nftables.d/... .

A call to an /etc/firewall.user shell script could be added additionally as well, but as other have pointed out it is less useful due to the non-atomic nature.

1 Like

If the content of that file is changed rarely enough non-atomicity is probably not going to be a big issue... the directory hierarchy thing sounds like for intermediate complexity configurations, but for simple quick and dirty testing having something with the same simplicity as firewall.user would be great (if need be that could be included at a fixed position).