Bridge filter with nftables

Hello. In my 21.02 setup I had a few rules that leveraged physdev-in in order to filter traffic coming from a specific interface inside a bridge, as explained in https://openwrt.org/docs/guide-user/firewall/fw3_configurations/bridge.

Now that I upgraded to 22.03, with fw4 and nftables, they're not working anymore as expected. How should I achieve the same goal, i.e. filter packets coming from a specific interface in a bridge? I already tried specifying the Inbound Device in the rule but it's still not matching.

Create a custom firewall include:

mkdir -p /usr/share/nftables.d/table-pre
cat <<EOT > /usr/share/nftables.d/table-pre/90-my-bridge-filter.nft
chain my_bridge_filter {
    type filter hook forward priority 0;
    iif eth0 oif eth1 drop
}
EOT

Uhm... it seems it's not matching my interfaces still. I read I should use the bridge table in order to match my bridged interfaces?

So, an update. I kinda managed with this table:

table bridge filter_wlan36 { # handle 2
        chain filter_wlan36_to_input { # handle 1
                type filter hook input priority 0; policy accept;
                udp dport { 53, 67, 68 } iifname "wlan36" accept comment "Allow DHCP and DNS from wlan36" # handle 3
                iifname "wlan36" drop comment "Reject other traffic from wlan36" # handle 4
        }

        chain filter_wlan36_to_forward { # handle 5
                type filter hook forward priority 0; policy accept;
                udp dport 10308-10310 iifname "wlan36" accept comment "Allow DCS Broadcast from wlan36" # handle 6
                iifname "wlan36" oifname "eth0.835" accept comment "Allow Outgoing traffic from wlan36" # handle 7
                iifname "wlan36" drop comment "Reject other traffic from wlan36" # handle 8
        }
}

My only issue is that the last rule blocks every traffic coming from wlan36, which is what I want except for the traffic directed to WAN. I thought that the rule above would allow such traffic, but somehow it's not matching. Any hint?

EDIT: These are the rules I had in place with fw3, and they worked fine:

config rule
	option name 'Allow-wlan36-DHCP-and-DNS'
	list proto 'udp'
	option src 'lan'
	option dest_port '53 67 68'
	option target 'ACCEPT'
	option extra '-m physdev --physdev-in wlan36'

config rule
	option name 'Allow-DCS-Broadcast'
	list proto 'udp'
	option src 'lan'
	option dest 'lan'
	option target 'ACCEPT'
	option extra '-m physdev --physdev-in wlan36'
	option src_port '10308-10310'

config rule
	option src 'lan'
	option extra '-m physdev --physdev-in wlan36'
	option name 'Allow-wlan36-lan'
	list proto 'all'
	option dest 'wan'
	option target 'ACCEPT'

config rule
	option src 'lan'
	option extra '-m physdev --physdev-in wlan36'
	option target 'REJECT'
	option dest '*'
	option name 'Deny-wlan36-any'
	list proto 'all'

config rule
	option name 'Deny-wlan36-router'
	option src 'lan'
	option target 'REJECT'
	option extra '-m physdev --physdev-in wlan36'
	list proto 'all'

So, after a bit more debugging, it seems that the real blocker is the drop entry in the filter_wlan36_to_input chain. I think this happens because the filter_wlan36 table, which is a bridge family table, is evaluated well before the whole fw4 table. In contrast, with fw3, since those rules were in the same chains that fw3 already managed, they did not block most of the traffic that shouldn't have been blocked; in fw4, with such rules, everything that is not udp dport { 53, 67, 68 } is dropped, and this may involve other packets that should be allowed instead (ARP requests, broadcasts...).

So I'm a bit at a loss right now. In the meanwhile I had to restore my previous 21.02 setup and I can't upgrade to 22.03. Any hint on how I would reach my goal (which, I remember, is trying to isolate an host that connects to a given bridged interface from the rest of the network and only allow to connect it to the WAN) would be greatly appreciated.

1 Like

To which file did you write the table bridge filter_wlan36 { ... script?

I am trying to do something similar but cannot event create an empty bridge table.

I have /etc/nftables.d/test.nft:

table bridge test {

}

Without this file, I can fw4 reload successfully. But with this file I get:

root@openwrt:/etc/nftables.d# fw4 reload
/etc/nftables.d/test.nft:1:1-5: Error: syntax error, unexpected table
table bridge test {
^^^^^

During my tests I was using command line. Unfortunately I didn't even manage to get to the "I need to persist this" phase :confused:

Move your test.nft file to /usr/share/nftables.d/ruleset-post/ directory.

1 Like

Thanks, it worked! I found some documentation about this