Cannot get ipset to work in firewall

I want to block access to certain websites and I'm following this guide https://openwrt.org/docs/guide-user/firewall/fw3_configurations/fw3_config_ipset
In this case, I'm testing the config with 104.31.67.136
So I added the following config in /etc/config/firewall:

config ipset
    option name 'drop_addr'
    option match 'src_net'
    option storage 'hash'
    option enabled '1'
    list entry '104.31.67.136'

config rule
    option dest '*'
    option ipset 'drop_addr'
    option target 'DROP'
    option name 'DROP-104.31.67.136'
    option enabled '1'

But it doesn't block access to the address after having the firewall reloaded. ipset is installed on my device. What could be wrong and what is option match 'src_net'?

Try these instead:

option match 'dst_net'

and

option src 'lan'

Ok, I tried this config

config ipset
	option name 'drop_addr'
	option match 'dst_net'
	option storage 'hash'
	option enabled '1'
	list entry '104.31.67.136'

config rule
	option src 'lan'
	option ipset 'drop_addr'
	option target 'DROP'
	option name 'DROP-WAN-LAN'

But didn't work out either. I can still access that IP. Does it matter where I should put config ipset set?
I put config rule in the very end. Maybe something's wrong with the order?

Using

  • dest '*' without src creates your rule in the OUTPUT chain.
  • dest 'wan' without src creates your rule in the zone_wan_output chain
  • src '*' without dest creates your rule in the INPUT chain.
  • src 'lan' without dest creates your rule in the zone_lan_input chain.

But you want to drop traffic that is forwarded so you have to specify
dest and src and the same time.

Try (creates rule in zone_lan_forward):

config ipset
	option name 'drop_addr'
	option storage 'hash'
	option match 'dst_ip'
	list entry '104.31.67.136'

config rule
	option name 'DROP-104.31.67.136'
	option family 'ipv4'
	option proto 'any'
	option src 'lan'
	option dest 'wan'
	option ipset 'drop_addr'
	option target 'DROP'

I guess

dest '*'
src '*'

does also work. (Creates the rule in the FORWARD chain)

Thanks.
I'm using the router as a wifi repeater and I put dest '*' and src '*', but the IP address can still be accessed.
This rule without ipset works fine.

config rule
	option name 'block 104.31.67.136'
	option src '*'
	option dest '*'
	option dest_ip '104.31.67.136'
	option target 'DROP'
	option enabled '1'

But I need to use ipset. What could be wrong?

Do you have the ipset package installed?

Post the output of

opkg list-installed | grep ipset

please.

Sure it's installed. Here's the output

ipset - 6.24-1
kmod-ipt-ipset - 3.18.27-1

And the output of
ipset list
please.

Name: mwan3_connected
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 9016
References: 2
Members:
192.168.8.255
192.168.0.0
10.8.1.38
192.168.0.34
192.168.8.1
192.168.8.0
192.168.8.0/24
127.255.255.255
192.168.0.255
192.168.0.0/24
192.168.0.10
127.0.0.1
224.0.0.0/3
127.0.0.0/8
127.0.0.0
104.244.75.220

Name: mwan3_track_wwan
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 8312
References: 1
Members:
208.67.222.222
8.8.4.4
208.67.220.220
8.8.8.8

Seems like your ipset (drop_addr) was not created.
Did you restart the firewall after modifying the config?
Can you invoke /etc/init.d/firewall restart in an ssh terminal.
And also post the output of that, please.

1 Like

I applied the new config with the luci interface, so I hoped it worked. But you were right. Here's the output now.

Name: mwan3_connected
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 9016
References: 0
Members:
192.168.8.255
192.168.0.0
10.8.1.38
192.168.0.34
192.168.8.1
192.168.8.0
192.168.8.0/24
127.255.255.255
192.168.0.255
192.168.0.0/24
192.168.0.10
127.0.0.1
224.0.0.0/3
127.0.0.0/8
127.0.0.0
104.244.75.220

Name: mwan3_track_wwan
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 8312
References: 0
Members:
208.67.222.222
8.8.4.4
208.67.220.220
8.8.8.8

Name: drop_addr
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 8248
References: 1
Members:

But the address in still not on the list.

How did you create the ipset through luci?
Can you do a /etc/init.d/firewall restart and post the output please.
Maybe the support for "list entry" was added later but I'm not sure.
Does ipset add drop_addr 104.31.67.136 work?
If yes you can try to put in the custom rules tab in luci firewall.
But that doesn't explain why the entry isn't added directly.
So the output of firewall restart could maybe help.

1 Like

I didn't do that. After copying the file to /etc I clicked reset to make luci pick up the settings from the file and clicked save&apply to apply them. But the content of the file was not changed anyway.

Yes, finally. It worked out. I couldn't access the address anymore.
Here's the output for /etc/init.d/firewall restart:

Warning: Option @ipset[0].entry is unknown
 * Flushing IPv4 filter table
 * Flushing IPv4 nat table
 * Flushing IPv4 mangle table
 * Flushing IPv4 raw table
 * Flushing IPv6 filter table
 * Flushing IPv6 mangle table
 * Flushing IPv6 raw table
 * Deleting ipset drop_addr
 * Flushing conntrack table ...
 * Creating ipset drop_addr
 * Populating IPv4 filter table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'VPN_client'
   * Rule 'Allow-DHCP-Renew'
   * Rule 'Allow-Ping'
   * Rule 'Allow-IGMP'
   * Rule #7
   * Rule #8
   * Rule 'DROP-WAN-LAN'
   * Forward 'lan' -> 'wan'
   * Forward 'lan' -> 'VPN_client'
 * Populating IPv4 nat table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'VPN_client'
 * Populating IPv4 mangle table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'VPN_client'
 * Populating IPv4 raw table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'VPN_client'
 * Populating IPv6 filter table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'VPN_client'
   * Rule 'Allow-DHCPv6'
   * Rule 'Allow-MLD'
   * Rule 'Allow-ICMPv6-Input'
   * Rule 'Allow-ICMPv6-Forward'
   * Rule #7
   * Rule #8
   * Forward 'lan' -> 'wan'
   * Forward 'lan' -> 'VPN_client'
 * Populating IPv6 mangle table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'VPN_client'
 * Populating IPv6 raw table
   * Zone 'lan'
   * Zone 'wan'
   * Zone 'VPN_client'
 * Set tcp_ecn to off
 * Set tcp_syncookies to on
 * Set tcp_window_scaling to on
 * Running script '/etc/firewall.user'
uci: Entry not found
 * Running script '/usr/share/miniupnpd/firewall.include'
 * Running script '/var/etc/shadowsocks.include'
   ! Skipping due to path error: No such file or directory

I'm glad you got it working.

Seems like 'list entry' is indeed not supported by your installation.
Hmm. But I can't tell when support for this was added.
You can add
ipset add drop_addr 104.31.67.136
to /etc/firewall.user

There is also the option loadfile.
But I also don't know when support for this was added.
Maybe it is worth a try.
I think you have to save your ipset (after adding the entries) with
ipset save drop_addr > /etc/ipsets/drop_addr.set

Then use option loadfile '/etc/ipsets/drop_addr.set' in your uci firewall ipset section.
Adjust path as you see fit.

Originally, I was going to use option loadfile, but decided to start off with list entry first.
Can I use comments in the file?

Just tried it. loadfile is unknown as well, unfortunately. Seems like I will have to input all the IPs through ipset add

EDIT: I've just put this line in the custom rules section via LuCI to start the script each time firewall starts:

while read IP; do ipset add block_ip $IP; done < "/etc/block_ip.txt"

The file contains a list of IPs that are put on the block_ip list one by one.

Nice approach.
But isn't it easier to use ipset save and ipset restore?

1 Like

I have around 5000 addresses. So I guess my way is faster. And both would take 1 line of code in the end anyway. Just to read from file and load the whole list into RAM. But I think your way is better if I want to put new IPs on the list, so thank you.
The only question I have now is what should be the value of the hash size when creating a set and why?

https://blog.n0dy.radio/2013/05/19/faster-ipset-loading/

For hashsize.
I'm not entirely sure.
But I think this option defines how much ram for the set is preallocated on creation. (max size of the set)
If you choose a too small value the hashsize automatically grows.(But i guess that is "slow"?)
After you filled the set you can see the hashsize with ipset list and use that value.

2 Likes