Online Services

Fail2Ban + centralized database

Read attacker IPs from your central store, push them into Fail2Ban and keep every service consistently protected with cron-driven automation.

Fail2Ban console

Overview

This second part explains how to read the attacker IP chain that was written into the central database (see part one) and instruct Fail2Ban to block every listed host. Think of it as a thought-out automation recipe you can adapt to your environment.

System requirements

  • Functional Fail2Ban, iptables and PHP on the host
  • Database credentials with read access to the attacker table
  • Writable /etc/fail2ban/empty.log for blocklist triggers
root@devserv3:~# sudo apt-get install php7.4 fail2ban iptables
                            

Fail2Ban blocklist jail

Monitor a lightweight log file and block every IP once. The jail uses banaction iptables-allports so every service is protected.

[blocklist]
enabled  = true
port     = ssh
filter   = sshd
logpath  = /etc/fail2ban/empty.log
maxretry = 1
banaction = iptables-allports
action   = %(action_)s
                            

Reload & test

After editing jail.local restart Fail2Ban and feed an example IP via fail2ban-client in combination with an empty-flag file change.

root@devserv3:~# service fail2ban restart
root@devserv3:~# fail2ban-client set blocklist banip 1.168.100.1
echo "-" > /etc/fail2ban/empty.log
                            

Verify iptables to ensure the drop rule exists for the blocked IP.

root@devserv3:~# iptables -L fail2ban-blocklist
                            

PHP synchronizer

The script fetches IPs added within the last 60 seconds and triggers Fail2Ban for every entry while touching the empty log.

#!/usr/bin/php -n
<?php
$link = mysql_connect('devserv3', 'fail2ban', 'password');
mysql_select_db('fail2ban');
$query = 'SELECT ip FROM fail2ban WHERE created>DATE_ADD(NOW(), INTERVAL -60 SECOND)';
$result = mysql_query($query);
$cmd = '';
while ($row = mysql_fetch_object($result)) {
    $cmd .= 'fail2ban-client set blocklist banip ' . $row->ip . ' && ';
}
if ($cmd) {
    $cmd .= "echo "-" > /etc/fail2ban/empty.log";
    $cmd .= ' >/dev/null 2>/dev/null &';
    exec($cmd);
}
mysql_close($link);
exit;
                            

Cron scheduling

Trigger the PHP script every minute to keep Fail2Ban in sync with the central database. Adjust the interval inside the query if you need a different cadence.

*/1 * * * * root nice -n 19 /usr/bin/php -c /etc/php/7.4/cli/php.ini -f /root/fail2ban.get.php > /dev/null 2>&1
                    

Stay ahead of attackers

Use database signals to automatically feed Fail2Ban and keep every node aware of active blocks.

Ask our team