I'm using fail2ban on all servers with publicly visible services and I wonder:
- Is there an easy way to share banned IPs between hosts I control?
- Is there a service out there collecting and publishing that data?
I've been getting countless login attempts since day 1 of setting up this server.
I once saw a system for centralizing fail2ban data on this site, and created a modified version. The database is the same, bu I changed and created some scripts.
My system have 4 components:
fail2ban database
It's a MySQL database containing only one table:
erp_core_fail2ban
:fail2ban.php
Every time a host is banned, it will populate the database:
cron2ban
You put this to run on crontab, every minute. It will retrieve the last added hosts, and ban them.
phpconfig
This file goes to /etc/fail2ban and have database configuration and jail selection.
Create those files and change the configuration from fail2ban:
After the line with
actionban = .....
a new row inserted to invoke the PHP script:/root/fail2ban.php <name> <protocol> <port> <ip>
Using this structure on all your servers will assure that every time one host gets banned on one server, all the other servers will ban it too.
So I did a bunch of research on how to do this after watching the same ip address hit my cluster of web servers one after another. Since I'm using AWS I figured there might be an easy way and its working beautifully in my first two days of testing 5 servers.
First thing I recommend is temporarily disabling SELinux, we will deal with it at the end. I'm not an SELinux expert but what I did works so far.
The primary requirement is a shared file source, I use AWS EFS. Once the new drive is provisioned and mounted, I changed logtarget inside of /etc/fail2ban/fail2ban.conf to a subfolder in the EFS drive.
Then I wrote a simple filter and placed it in /etc/fail2ban/filter.d/fail2ban-log.conf
Added the filter to /etc/fail2ban/jail.local
Then restarted fail2ban
So far so good! No the painful part is SELinux. After I let fail2ban run for a bit I ran this command that would allow fail2ban through the filters.
Audit2allow will tell you to run this command
I am still checking my SELinux logs here and there to see if there are any more denials. If anyone has a tip on how to get that clear SELinux with another method that would be awesome.
At this point I was still getting errors when restarting fail2ban. There is a bug when using action=action_mwl in jail.local. After a bit of googling I found this which is working so far. From what I read its because of the line breaks in the logpath directive pointing to multiple files. I tried with commas, spaces, etc nothing else worked with action_mwl.
Don't forget to turn SELinux back on!
An alternative to
fail2ban
is DenyHosts which comes with a synchronization functionality. Installation is fairly similar tofail2ban
, see Cyberciti's tutorial for more details.The problem is that the synchronization service is centralized and source code of the server side doesn't seem to be available, so you can't easily start your own DenyHosts service and you have to rely on 3rd party (which might be fine for some use cases).
I've just implemented this and so far it seems to be working well. However, I had to update some of the php because the scripts in the original answer use deprecated functions.
Here are the updated scripts
phpconfig.php
fail2ban.php
cron2ban.php
Also, wherever you place the fail2ban.php action, it must be indented as much as the line above it. For example:
Otherwise fail2ban will not start. I hope this helps anyone trying to deploy this.
Yes and yes. Both can be done.
You need to find a suitable mechanism to share the list of IPs. If you're using AWS for example you could take advantage of s3. You could use rsync between Linux hosts, or a database common to all hosts. You could knock up a service with you favourite programming language that provides a restful API the choice is yours.
In terms if sharing the list public ally you could create a website and host a simple text file, some already provide such lists (not crowd sourced that I know of). How to create your own site/service would be outside the scope of an answer, however shouldn't be terribly difficult to do.
A fairly manual setup would be to change the configuration that calls
iptables
to update rules so that it calls a script of your own devising which loops through a list of hosts (read from a file?) and makes theiptables
calls on each via SSH. You would need key-based auth between all the hosts configured for this to work. Admin automation tools like puppet may make setting this up and maintaining it easier. This would not be terribly efficient but unless you see a massive amount of probing traffic (and/or have a massive number of hosts) then I'm sure it would be good enough. If you only have a few hosts then you don't even need to loop through a file: configure each to just call the others in order. The scripting effort will be minimal.There are no doubt many ways. Have the script(s) above drop the data into a DB and have clients read from that, polling for new rules and running them as they come in. The simple "run a rule as you see it" won't be perfect if many hosts are submitting information, for example this case:
but this should not be a significant problem, and if you get a bit more clever with the database you could manage multiple submissions more cleanly if you decided it was worth the effort.
Running that as a public service would open you to a world of admin hassle though: