What's new

Blocklist ipset logging

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Denna

Senior Member
When creating an iptables rule that adds an address to a blocklist ipset, is there a way to know when the maxelem value has been exceeded ?

Below is an example rule:
Code:
iptables -t mangle -I PREROUTING -i eth0 -m state --state NEW -j SET --add-set BLOCKLIST src
At the command-line, when attempting to add one too many address to an ipset, you would receive the following error:
Code:
ipset v6.29: Hash is full, cannot add more elements
Is there a way for this error to be logged ?
 
There is a maxelem setting that you can specify when creating a set to allow more than 64k addresses.
 
An example for above;

Code:
ipset create Blacklist iphash --maxelem 500000

Would give the new set a 500,000 limit, this can be defined to anything as long as your IPSet version is above v4.5
 
When the maxelem limit is reached, the rule above stops adding addresses to the ipset.

Does the iptables rule log an error ?

Setting a timeout value on the ipset helps age out some of the elements, but that might not be enough to allow the rule to function.

Increasing the maxelem value will increase CPU utilization.
 
Does the iptables rule log an error ?
You could check the return code from the iptables command ($?) or the output going to stderr. This is basic shell scripting stuff. There are plenty of sites on the internet that do good tutorials if you need help.
 
When the maxelem limit is reached, the rule above stops adding addresses to the ipset.

Does the iptables rule log an error ?

Setting a timeout value on the ipset helps age out some of the elements, but that might not be enough to allow the rule to function.

Increasing the maxelem value will increase CPU utilization.

I have a few hundred thousand entries and yet to see its effect on the CPU. Theoretically speaking, there should be an increase, but if there is one, I can't see it.

You can also do your own IP count, and create additional buckets as needed if you are concerned with the CPU load.
 
@vk101,

The problem is the rule not being able to add addresses to the ipset.

It would be good to have a way to know when that happens.​
 
You could check the return code from the iptables command ($?) or the output going to stderr. This is basic shell scripting stuff. There are plenty of sites on the internet that do good tutorials if you need help.
@ColinTaylor,

How is this for a possible solution ?
Code:
iptables -t mangle -I PREROUTING -i eth0 -m state --state NEW -j SET --add-set BLOCKLIST src
if [ $? != 0 ]
 then
    logger -t Firewall-start "ERROR - Problem with iptables rule adding address to BLOCKLIST ipset"
 else
fi
 
Last edited:
@ColinTaylor,

How is this for a possible solution ?
Code:
iptables -t mangle -I PREROUTING -i eth0 -m state --state NEW -j SET --add-set BLOCKLIST src
if [ $? != 0 ]
 then
    logger -t Firewall-start "Problem with iptables rule adding address to BLOCKLIST ipset"
 else
fi

That won't work nor will the idea in general, that is checking for the exit status of adding the IPTables rule, the passing of an IP is then handled independently by IPTables once something matches said rule.

There is no reason not to define a higher maxelem value, the CPU impact is unnoticeable, ipset was designed around having large lists, the default value of 65k only exists for backwards compatibility with pre 4.5 versions.
 
@Adamm,

All I want to do is be informed when the ipset's maxelem value has been reached.

When an ipset's maxelem value has been reached, this rule won't do what it was intended to do.

Otherwise, until the timeout value ages out addresses in the ipset, I wouldn't know this rule was functioning correctly.​
 
@Adamm,

All I want to do is be informed when the ipset's maxelem value has been reached.

When an ipset's maxelem value has been reached, this rule won't do what it was intended to do.

Otherwise, until the timeout value ages out addresses in the ipset, I wouldn't know this rule was functioning correctly.​

In this situation the only way that could be done would be with a cronjob manually checking the list size on a defined interval.

Also you are defining all new connections with the rule above, that will add all traffic on eth0 to the ipset
 
Possible ipset member count solution:

How would you code subtracting 7 with one command ?
Code:
if [ (wc -1 /path/BLOCKLIST.sav) -7 ] => 65536
   then
      logger -t Firewall-start "ERROR - BLOCKLIST ipset maxelem limit reached"
   else
fi
As for the rule, it only blocks connections originating from the Internet on the WAN port.

Since the router isn't providing services to the Internet, the only traffic coming from the Internet should be replies to LAN originated connections.

One unattractive option would be to create the ipset with the forceadd option.
 
Last edited:
Code:
#!/bin/sh
if [ "$(ipset -L BLOCKLIST | wc -l)" -ge "65542" ]; then
      logger -t Firewall-start "ERROR - BLOCKLIST ipset maxelem limit reached"
fi

Although if you wanted to block all traffic wouldn't it be easier to specify a IPTables rule todo it and avoid IPSet all together?

Right now this requires 3 IPTable's rules plus the overhead of ipset and continuously checking the set amount value;

1) Drop any matching IP's
2) Add new IPs to ipset
3) Check again for matching ips to drop

Or you could simply do;

1) Drop all traffic
 
Last edited:
@Adamm,

Thanks for the code. How does the subtraction occur on the if line ?​

The rule doesn't drop all traffic.

The first rule (OP) adds the IP address of NEW state connections originating from the Internet to an ipset.

LAN originated connections pass through the WAN interface as do replies from Internet hosts.

Not shown in the OP, the next rule DROPs any connection whose IP address is in the ipset.​
 
Last edited:
Thanks for the code. How does the subtraction occur on the if line ?

It doesn't subtract the 7, it just accounts for 7 more lines of text then the maxelem value we are expecting.

"If value of "$(ipset -L BLOCKLIST | wc -l)" is greater or equal (-ge) to 65542 then execute code"

The first rule (OP) adds the IP address of NEW state connections originating from the Internet to an ipset

I assume your rules look something like;

Code:
iptables -t mangle -I PREROUTING -i eth0 -m set --match-set BLOCKLIST src -j DROP
iptables -t mangle -I PREROUTING -i eth0 -m state --state NEW -j SET --add-set BLOCKLIST src
iptables -t mangle -I PREROUTING -i eth0 -m state --state NEW -j DROP

(You would want too have two DROP rules otherwise you will be attempting to add IP's upon every new connection even if they already exist in the set. They would also need to be listed in reverse as -I inserts it to the top of the chain)

This exact same functionality can be replicated with 1 rule and without ipset via;

Code:
iptables-t mangle -I PREROUTING -i eth0 -m state --state NEW -j DROP
 
Last edited:
@Adamm

If the maxelem value has maxxed out at 65536, wouldn't the conditional test be ... ?
Code:
if [ "$(ipset -L BLOCKLIST | wc -l)" -e "65543" ]
The reason I was using the iptables rules was to reduce resource utilization caused by Internet hosts that attempted repeat connections from the same address.

I only mentioned the rule in the OP to show where the addresses were being added and to see if the rule could report a failure code that could be acted upon.

So here's the BLOCKLIST related rules.

Code:
#This rule drops BLOCKLIST members before connection tracking is available
#This prevents unnecessary netfilter processing and connection tracking table usage
iptables -t raw -I PREROUTING -m set --set BLOCKLIST src -j DROP

#This rule adds addresses to an ipset where a NEW state connection originates from the Internet
iptables -t mangle -I PREROUTING -i eth0 -m state --state NEW -j SET --add-set BLOCKLIST src

#This rule drops connection for addresses in the ipset
iptables -t mangle -A PREROUTING -m set --set BLOCKLIST src -j DROP

#Further connections from the same addresses are DROPped by the first rule
 
Last edited:
@Adamm

If the maxelem value has maxxed out at 65536, wouldn't the conditional test be ... ?
Code:
if [ "$(ipset -L BLOCKLIST | wc -l)" -e "65543" ]

I used ge because I vaguely remember there being issues adding a 65536th value sometimes, I can't remember the exact circumstances though so you can probably go for the exact number. Also use "=" not "-e". What you posted means "Return true if the file exists"

Code:
if [ "$(ipset -L BLOCKLIST | wc -l)" = "65543" ]

Again, I hope you read over my other solution above, IPSet is not needed in this case unless you specifically want to keep a list of whats being blocked.
 
@Adamm,

If a variable was used to specify an ipset's maxelem value, would this be the correct syntax ?
Code:
BLOCKLIST_MAXEL="65536"
if [ "$(ipset -L BLOCKLIST | wc -l)" = "echo $(($BLOCKLIST_MAXEL + 7))" ]; then
 
@Adamm,

If a variable was used to specify an ipset's maxelem value, would this be the correct syntax ?
Code:
BLOCKLIST_MAXEL="65536"
if [ "$(ipset -L BLOCKLIST | wc -l)" = "echo $(($BLOCKLIST_MAXEL + 7))" ]; then

Close, when using $(()) var names don't need to begin with a $. Also that's an unnecessary (and literal) echo, and vars should also always be lower case.

Code:
blocklist_maxel="65536"
if [ "$(ipset -L BLOCKLIST | wc -l)" = "$((blocklist_maxel + 7))" ]; then

I suggest against using a var here, its unneeded and "bloat" so to speak as you are requiring an extra calculation to be made and it could be defined just once in the if statement.
 

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top