Frustrated by brute force attacks on your server from botnets with ever-changing IP addresses?

Me, too.

I finally got around to assembling a simple Linux active firewall, which I call “slaf”. This PHP script monitors the CentOS secure log and records failed FTP login attempts into a MySQL database. When the failed attempts get to be too numerous from a single IP address, the script adds the offending IP address to an ipset blacklist that is part of the iptables ruleset.

There are other ways to accomplish this, but I found this approach to be easy to code and reliable. It also performs very well, both in terms of how fast it processes the secure log, and how efficiently ipset handles a long list of blocked IP addresses.

The “slaf” utility is comprised of four basic parts:

  1. A php script we’ll call slaf.php. It turns failed FTP login log records into MySQL records for tracking the number of failed logins, including when they happened, and also does the needed queries and record keeping for tracking which IPs we’ve already blocked.
  2. The MySQL database, which we’ll call slaf.
  3. An ipset list called blacklist that we’ll add to our iptables firewall rules.
  4. A cron job that runs slaf.php on whatever schedule suits you.

Here’s slaf.php. It’s fairly heavily commented, so hopefully it’s clear what is happening in each section of code.

Here’s what you’ll need to create the MySQL database I’m calling slaf:

Don’t forget to create a database user and password, and put those values in the PHP script.

Next up, if you don’t already have it, install ipset on your server. For CentOS, that command is:

After ipset is installed, create the ipset list we’re calling blacklist:

Then, add the ipset blacklist as a rule to our iptables firewall:

You’re ready to run slaf.php manually:

You can examine the ipset blacklist to see what IP addresses have been blocked:

You can also review the records in the log_entries and drop_log tables in the slaf MySQL database.

Once slaf is tuned to your liking, add a cron job to run it on a schedule that suits you. If your server can handle it, running it every few minutes will stop a lot of brute force attempts while they are in process. If you aren’t comfortable running it that often, you may miss attacks while they are in progress, but your server will still benefit from blocking IPs that are obviously compromised.

This utility should be fairly easy to adapt to other log files, including Apache access logs. Making it work for other services is really just a matter of adapting the log file parsing: Find the conditions that look like illicit attempts to access server resources, log the IP in the database, and then apply some logic via the database query for how much of that nonsense you are willing to tolerate.

There are, of course, other ways to do this. Here’s a helpful article on how to stop FTP hacking using proftpd’s configuration file and various shell tools.

If you are familiar with iptables but have not used ipset, I highly recommend you read up on ipset. It’s straightforward, and a great tool for blocking long lists of IP addresses without taxing your server.