How to make fail2ban bans persistent

I've recently started using fail2ban more to ban suspicious traffic on my web servers. It's great because it looks at logs and if an entry matches a regular expression it will perform an action on the IP address from the log. You can make the actions do pretty much anything, typically the action is an iptables rule that will ban the user. The problem is when you restart the fail2ban service fail2ban clears the chain for the filter and parses the current log for matches, not the rotated logs. So you don't ban any IPs that were banned before logrotate rotated the old log.

You can make the bans persistent by setting up a blacklist and automatically loading them when fail2ban is restarted. First, you need to create a file to store blacklisted IPs.

sudo touch /etc/fail2ban/ip.blacklist

Then you can either make a copy or edit the /etc/fail2ban/action.d/iptables-multiport.conf file. I prefer to make a copy of it because I version all of my configs.

In the action config file you have a few different directives, we want to focus on 2, the actionstart and actionban. First, when fail2ban bans an IP we want to not only ban it, but we want to add the IP address to the ip.blacklist file.

actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
            echo <ip> >> /etc/fail2ban/ip.blacklist

Then we want to be sure that the iptables rule is added when fail2ban is started, so we add the following lines of code to the actionstart directive:

actionstart = iptables -N fail2ban-<name>
              iptables -A fail2ban-<name> -j RETURN
              iptables -I INPUT -p <protocol> -m multiport --dports <port> -j fail2ban-<name>
              cat /etc/fail2ban/ip.blacklist | while read IP; do iptables -I fail2ban-<name> 1 -s $IP -j DROP; done

That's it, once you restart fail2ban it will automatically ban all of the IPs in your ip.blacklist file.

Comments

If you wanted to include unban action:

actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
sed -i /<ip>/d ip.blacklist

Excellent info - thank you.....

Wow!Thanks!

ow can I get the same thing on groups of ip?
for example 222.18.0.0/16

Yes you can, you're basically adding an iptables rule for each offending IP address.

THanks!

So on a debian box, for some strange reason, when i reboot the server or restart the fail2ban service, it's not automatically applying the bans from the ip.blacklist

Anyone else experience this issue?

That's odd, are you sure you've added the line in the configuration file in the /action.d/ folder? It should populate the iptables rules when you start/stop the fail2ban service.

not working for me either.

Could this be used to write/remove IPs currently banned to a web-accessible text file, that can then be read by a network firewall?
Our PFsense firewall can dynamically update its rules based on web-accessible text files. Currently it pulls lists from Spamhaus and a few others once a day. This seems like a great way to block naughty IPs from the entire network, rather than just the server that spotted the behavior.

I don't see why it couldn't, I'm basically running a command inside of the fail2ban action so you should be able to do something along the same lines.

Thanks for the insight on this one; I did a Google search for 'fail2ban persistent' and yours was the first result. Works great, even with my modified configuration using ipset. Brilliant!

For anyone curious, here's my ipset-friendly actionstart directive for saving to /etc/fail2ban/ip.blacklist:
for banned_addr in $(cat /etc/fail2ban/ip.blacklist); do ipset -! add fail2ban-<name> $banned_addr; done

(Forgive my little substitution; I have a for-loop addiction. ;)

Cheers,
Chris

Hi, I followed your instructions (I am on ubuntu 14.04, with iredmail install 0.8.7) and I noticed 2 problems:

1. Duplicates are being added to the ip blacklist
2. Blacklist is being completely ignored on restart of fail2ban (but recidive is working)

Any suggestions? Thanks!

I can help with #1.
Modify the line that starts:
cat /etc/fail2ban/ip.blacklist
to include |sort |uniq so it will look like this:
cat /etc/fail2ban/ip.blacklist |sort |uniq
This will sort them and then grab only the unique IPs

I am not sure with #2, but I did see a post earlier stating the same thing, Did you double check that? I am just now working with fail2ban, so I would hate to hazard a guess, but I've lot's of Unix and Linux. Hope this helps!

This worked for me:
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' /etc/fail2ban/ip.blacklist | while read IP; do iptables -I fail2ban-<name> 1 -s $IP -j DROP; done

Would be better if actionstop is added and dump existing lists to the ip.blacklist file incase someone restarted the process.

I have used fail2ban for a while now and love it. I followed your instructions here and my ip.blacklist file is full of bad guys.

My question is this: I have a firewall monitor running so I can visually see live activity, and when someone is hammering my site I will check the logs to see what they are doing. Sometimes (not all) fail2ban will say that it unbanned the IP (with iptables error), and I am not sure why that would be. Here is a couple example from a log:

fail2ban.log:2015-05-25 16:15:02,824 fail2ban.actions: WARNING [ssh] Unban 222.186.21.223
fail2ban.log:2015-05-25 16:15:02,834 fail2ban.actions.action: ERROR iptables -D fail2ban-ssh -s 222.186.21.223 -j REJECT --reject-with icmp-port-unreachable returned 100

fail2ban.log:2015-05-25 07:11:48,053 fail2ban.actions: WARNING [ssh] Ban 193.165.151.139
fail2ban.log:2015-05-25 16:15:06,977 fail2ban.actions: WARNING [ssh] Unban 193.165.151.139
fail2ban.log:2015-05-25 16:15:06,989 fail2ban.actions.action: ERROR iptables -D fail2ban-ssh -s 193.165.151.139 -j REJECT --reject-with icmp-port-unreachable returned 100

Any ideas?

As the actions can be used by many jails there is a risk the IP list would be applied to the wrong jail. This is not checked, but you should be able to change the file name /etc/fail2ban/ip.blacklist to something like /etc/fail2ban/fail2ban-<name>-ip.blacklist.

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.