fail2ban icon indicating copy to clipboard operation
fail2ban copied to clipboard

please add actionfound

Open unclesamwk opened this issue 5 years ago • 15 comments

Hey,

very great tool is fail2ban but an feature be very nice. please add "actionfound" to fail2ban. for different usage it may be very nice.

greetings sam

unclesamwk avatar Dec 18 '18 09:12 unclesamwk

What this new parameter actionfound should mean?

sebres avatar Dec 18 '18 10:12 sebres

Do you mean an action for each failure was found? If yes, as workaround you could create similar things, using actionban and maxretry = 1.

sebres avatar Dec 18 '18 10:12 sebres

the actionban execute as example an curl. if alread banned, the curl doesnt execute. the actionfound executes every time if regex matches

unclesamwk avatar Dec 18 '18 11:12 unclesamwk

👍would also really appreciate actionfound for preliminary lookups on login

andrew-morris avatar Feb 22 '20 14:02 andrew-morris

Well indirectly it is possible right now using ignorecommand, which will be invoked by every found failure (unless ignorecache is enabled for the jail, see #2176).

sebres avatar Feb 24 '20 11:02 sebres

Confirmed ignorecommand workaround - works fine for our setup where we do not have to ban locally but to report to a central fail2ban node.

indreias avatar Nov 04 '21 11:11 indreias

Is there a way to do this with ignorecommand and

  1. Run the command after the fail2ban log message
  2. Keep the fail2ban log message saying "found XX.XXX.XX" instead of ignored XX.XX.XX by command

Or even better just a way to run a command on an found/attempt/failure

wrench12435678 avatar Jun 03 '22 00:06 wrench12435678

  1. Run the command after the fail2ban log message

Do you mean [jail] Found <ip>? No, it is not possible. All ignore facilities are invoked before the attempt considered as a failure finding.

  1. Keep the fail2ban log message saying "found XX.XXX.XX" instead of ignored XX.XX.XX by command

Yes. ignorecommand must return not 0, otherwise it will ignore the finding. Read man jail.conf.5 for details. Simply add ; exit 1 at end of script/command and it would work.

Or even better just a way to run a command on an found/attempt/failure

Sure, this RFE exactly about that. The way with ignorecommand is just a workaround, unless it is not implemented.

sebres avatar Jun 03 '22 10:06 sebres

; exit 1

Thanks! ; exit 1 solved the main issue with the workaround

wrench12435678 avatar Jun 03 '22 10:06 wrench12435678

I've tried to hook into ignorecommand this way to note when an IP is found. I'm using it to distribute when an IP is found across nodes and have each node read found IPs from other nodes. This way the found count should be the same across each node. To elaborate:

  1. Node 1 matches an IP and the fail2ban log says ... found <IP> ...
  2. Node 2 has the IP distributed to it into a log file and also has the fail2ban log say ... found <IP> ...
  3. At a later point node 2 matches an IP not from the distributed log file and repeats the process.
  4. Both node 1 and node 2 have found the same IP twice even though each node was contacted by that IP once.

So what is wrong with using ignorecommand?

After several attempts to get things correct I keep running into issues:

  • The jail responsible for reading the distributed IPs should not call the same ignorecommand, otherwise it will create a loop. That one is easy enough by setting ignorecommand = /bin/false for that jail.
  • The node that found the IP will see the same IP in the distributed log unless care is taken to prevent such a loop. This one I can code for so it's mainly for anyone else trying the same thing.
  • When restarting fail2ban it restores previous bans and each one of those will call the ignore command. As a result each restart of fail2ban causes that IP to appear as found again to each node. I can prevent the source node from seeing the restored IP but not the other nodes.
  • I really don't want to process the fail2ban log file output if I can avoid it.

I'm open to suggestions and it seems the hardest one to solve is the restore of IPs so far. Having said that, having something like actionfound = /path/to/script <ip> makes it very clear exactly what is going on. It also makes it clear that this is used only for IPs that are found and not restored.

mcassaniti avatar Mar 01 '24 03:03 mcassaniti

So what is wrong with using ignorecommand?

Basically nothing... ignorecommand will be invoked for any ticket (with <ip> read from log) for any matched failure message and which is not already ignored by processing with other "faster" ignore* lookups (like ignoreself orignoreip) and there is still no cached entry for that related to ignorecache. I don't quite understand your explanation, but it looks like you seem to confuse something there.

That one is easy enough by setting ignorecommand = /bin/false for that jail.

To reset it an empty value (ignorecommand =) would be enough. However I don't really understand why sending of something from node 1 to node 2 with ignorecommand would cause an invocation of ignorecommand on node 2 side again (does exactly this ticket appear in some log that will be monitored? why?)

I'm open to suggestions and it seems the hardest one to solve is the restore of IPs so far.

There is no way at the moment excepting a patching of this with a comment (or an option): https://github.com/fail2ban/fail2ban/blob/dce2c608c19e1907bdeefc81befdd52181930238/fail2ban/server/jail.py#L292-L294 Or with a move of ticket.restored = True (L293-L294) before ignore check (L292), so one'd be able to check with tag <restored> (1/0) whether the ticket was restored or not.

Having said that, having something like actionfound = /path/to/script <ip> makes it very clear exactly what is going on. It also makes it clear that this is used only for IPs that are found and not restored.

Sure, but it'd also need to answer few additional questions, like: should actionfound be executed before or after ignore* facilities (tend to do it after at the moment).

More or less it looks like an attempt to implement #881 (although already on found and not on ban event). However I understand the approach this is a matter of another discussion (RFE).

sebres avatar Mar 01 '24 11:03 sebres

I made the change now in 3047572701cbba0dca4008b00440e9bf03bab24d. Now it is possible to check restored state in ignorecommand and consider it with ignorecache:

# invoke command for non-restored tickets only:
ignorecommand = [ "<restored>" != 1 ] && exit 1
                /do/some/command "<ip>" "<time>" ...
# avoid invocation of ignorecommand too often, considering restored state:
ignorecache = key="<restored>/<ip>", max-count=5000, max-time=5m

sebres avatar Mar 01 '24 11:03 sebres

I apologise, my "what is wrong with ignore command" was more rhetorical for this use case. Thanks for pointing out #881 along with the feedback you've provided. Most of all, thank you for the recent change that I think will close the gap on all of it.

In short, it seems ignorecommand = /path/to/script <ip> <restored> and ignorecommand = on the jail reading the shared log will solve my problems. I can handle making sure there is no loop from the script back to the local node.

mcassaniti avatar Mar 01 '24 12:03 mcassaniti

@sebres When should we expect a release? I can see a lot of changes in master but nothing for over a year.

mcassaniti avatar Mar 01 '24 12:03 mcassaniti

When should we expect a release? I can see a lot of changes in master but nothing for over a year.

Soon, but cannot say an exact date right now (continuously under time pressure professionally). But the chain is long (between release here and release in distro), you can surely patch it by yourself - it is pretty simple.

sebres avatar Mar 01 '24 12:03 sebres