I have setup a few servers with Ubuntu Server and one of the common security tools I use is Fail2Ban.
One of the common requirements that comes with Fail2Ban is the need to provide other administrative personnel with a place they can quickly check which IP’s have been banned. Using a cool program called incron and a short shell script (which I will provide below) I was able to push the contents of the fail2ban log file in more-or-less real time to a plain text file in the web directory. Hence anyone can just visit that page and view a list of banned and unbanned IP addresses.
I had read about the incron program a few weeks back and had been looking for an excuse to try it out and jumped on it for this small project.
What is Incron?
Well, first I should talk about Cron. Cron is a utility on most (all?) variations of linux that allows you to schedule jobs. So for example you could setup a job that will run a command to clean up a temp directory once a week. It can also be used to kick of scripts for more elaborate scheduled work. I use cron and some scripts to do all of my web file and database backup. You can read about that here:
MySQL Database Backup – Shell Scripts That Can Be Run as Cron Jobs
Incron is just like cron in that it can kick off jobs, however rather than being based on a schedule, Incron can be set to monitor directories or individual files for any kind of change and then based on what change occurs it will kick off a job.
What is Fail2Ban?
Fail2Ban is a little program that can monitor log files and then update your IPtables (read, “host firewall”) on your server. It is commonly used to monitor access logs for failed logins, and then ban the public IP address from which those login attempts were coming, often for only a period of time.
Fail2Ban is, therefore, a very easy way to prevent someone from “brute forcing” a login page in your web application because it severely limits how many passwords a malicious agent can try to guess in a given period of time.
Okay, so here is the script I devised.
lastlinelog=$(tail -n 1 $logfile)
lastlinepage=$(tail -n 1 $pagefile)
if [ "$lastlinelog" = "$lastlinepage" ]; then
echo "last lines match"
echo "last lines do not match, appending file"
tail -n +2 $logfile > $pagefile
So first I declare four variables. The first two contain the full path to my log file and a plain text file called “bannedips” in a folder in my web directory. The next two variables contain the output from a tail command on each of those files. In this case, tail is grabbing the very last line (which means the most recent line in a log file) from each file. Next I have an if-then statement that compares the last line of both files and if they match it exits, if it doesn’t match then it goes to the tail command again, this time I am grabbing every line in the log file except for the very first one and then spitting that out into the plain text document in my web directory. This effectively provides a publicly accessible list of all of the IP’s that have been banned.
I saved my script at:
Setting Up incron
I would advise you to go read this excellent article here:
But I will give the readers digest version.
apt-get install incron
Configure incron so that only “root” can use it:
Finally tell incron to run the script whenever the log file changes.
This should open up the root user’s incrontab in the nano text editor. Add the following line to the file and then save and close:
And all done! Every time the fail2ban.log is modified, incron will run my script which will copy the information to a publicly available page.
In this example that page would be something like: http://www.somewebsite.com/bannedips
This isn’t fancy. It is simple and effective though, which I like.
UPDATE: If you want something fancy though… I looked into this:
Ultimately I stepped away from that though as it was still a bit “beta.”
Tailing a Log: