Can't get firewall rule and ipset with CIDR to work

I'm trying to setup firewall rules using an ipset. I have a test rule that isn't working and I'd appreciate knowing what I'm doing wrong.

In firewall I currently have the rule and ipset:

config rule
option name 'blackhole.ipv4'
option src ''
option ipset 'foo'
option target 'DROP'
option family 'ipv4'
option dest '
'
list proto 'all'

config ipset
option name 'foo'
option family 'ipv4'
list match 'net'
option loadfile '/etc/luci-uploads/bh1'

The bh1 file contains:
167.94.146.0/24

output from nft list sets:

table inet fw4 {
set foo {
type ipv4_addr
flags interval
auto-merge
elements = { 167.94.146.0/24 }
}
}

I expected my rule and ipset to to block 167.94.146.0 through 167.94.146.255, but when I test ping 167.94.146.50 from any machine on the lan or from the router I still get responses:

root@OpenWrt:/etc/config# ping 167.94.146.50
PING 167.94.146.50 (167.94.146.50): 56 data bytes
64 bytes from 167.94.146.50: seq=0 ttl=54 time=24.567 ms
64 bytes from 167.94.146.50: seq=1 ttl=54 time=25.393 ms
64 bytes from 167.94.146.50: seq=2 ttl=54 time=23.788 ms

I'm running [OpenWrt 23.05.3 (r23809-234f1a2efa)] on my router.

TIA

Routing blackhole is well supported, why would you use some alternative tech?

I have an auto generated list of CIDRs i'd like to use. I don't see a way of using an external file for blackhole routing.

You have wildcards in both source and destination zones. Make it more specific, e.g from lan to wan.

Thanks for the suggestion.

I've tried both lan to wan:

config rule
option name 'blackhole.ipv4'
option src 'lan'
option ipset 'foo'
option target 'DROP'
option family 'ipv4'
option dest 'wan'
list proto 'all'

and wan to lan:
config rule
option name 'blackhole.ipv4'
option src 'wan'
option ipset 'foo'
option target 'DROP'
option family 'ipv4'
option dest 'lan'
list proto 'all'

The same result with both changes, pings from the router and local machines still succeed,

Did you restart the firewall service? Also, if you have a persistent ping, be sure you stop it and start a new one after you restart the service.

Will not work like that, one needs to conntrack -D to destroy transient states to be blocked.

Your question did not state you are trying to enter a list but a single subnet. BanIP can also use local file as input.

I've tried restarting the firewall and restarting network. I've started and stopped pings between config changes.

Indeed. I wanted to get a single CIDR to work before moving on to automating the process.

There is a ready package called banip for your purpose, but as long as it is about single list you can add genuine blackhole routes like in a xargs loop.
The established states persist across firewall resets, you need to wait for them to expire (see sysctl net.netfilter) or forcibly destroy eg. via conntrack -D src 10.0.0.0/8)

You must specify a direction (dest_net in your case).

The rule will block LAN clients and you ping from the router itself. Remove the source zone altogether

4 Likes

This alone with From: any zone To any zone stops pings from local network clients.

This is good to know. I've installed conntrack and am now using it to kill connects between tests.

1 Like

This is "different" then.
If you init a connection from the router or a host on LAN to the destination, then either the rules in OUTPUT are checked or within FORWARDING from LAN to WAN, AND the answer falls under "related" and "established" and is usally checked and allowed as one of the first rules in INPUT or FORWARDING chain.

If however 167.94.146.50 connects to WAN or LAN then this connection is new, and should be rejected/blocked regarding your settings/rules in the INPUT or FORWARDING chain. Just to keep this in mind while you are testing.

1 Like

I took a look at banip and this was far easier and quicker to set up for what I wanted to achieve. I may revisit nft later on, but for now banip is working.

Thanks for all the responses.

1 Like