Here is the addition to fail2ban mit xt_recent.
Fail2ban can ban ip only until the server restarts.
I therefore add the bans not only in the firewall, but store them also into a mysql database.
Basics
I´ve created the database systemlog which containing two tables – one for the configs and one for the bans. The config table must not be present, but I have so the possibility to change block-times and must not adapt one or more scripts and can therefore read all of the jails with a slip and submit them to the firewall.
Below I leave the table config outside – for those interested in this part it´s avaible on monday at the end of this post.
The table systemlog.fail2ban contains some entrys:
source
port
jail
hits
last_hit
So i can simple reinitialice the firewall and have also a quick and easy way for some statistics.
Setup
setup mysql
login into mysql as root and run:
CREATE DATABASE systemlog;
CREATE USER 'systemlog'@'localhost' IDENTIFIED BY 'MYPASSWORD';
GRANT ALL ON systemlog.* TO 'systemlog'@'localhost' IDENTIFIED BY 'MYPASSWORD';
FLUSH PRIVILEGES;
QUIT;
Import the table-structure:
mysql systemlog < fail2ban.sql
Adjust fail2ban
To add a ban not only to the firewall but also to the database, i extended ‘actionban’. I take as an example iptables.conf.
/etc/fail2ban/action.d/iptables.conf:
actionban = iptables -I fail2ban-<name> 1 -s <ip> -j DROP
actionunban = iptables -D fail2ban-<name> -s <ip> -j DROP
changes to
actionban = echo +<ip> > /proc/net/xt_recent/fail2ban-<name>
/usr/bin/mysql -usystemlog -pMYPASSWORD systemlog -e "INSERT INTO fail2ban VALUES(INET_ATON('<ip>'),<port>,'fail2ban-<name>',1,now()) ON DUPLICATE KEY UPDATE hits=hits+1;"
actionunban = echo -<ip> > /proc/net/xt_recent/fail2ban-<name>
/usr/bin/mysql -usystemlog -pMYPASSWORD systemlog -e "DELETE FROM fail2ban WHERE source=INET_ATON('<ip>') AND jail='fail2ban-<name>;"
Our new /etc/fail2ban/action.d/iptables.conf looks like (download availabe at the end of this post):
#
# Author: Cyril Jaquier
#
# $Revision: 658 $
#[Definition]
# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
#
actionstart =
actionstart = sleep `echo ${RANDOM:0:1}`
if [ -z `iptables -L fail2ban-<name> | grep "^Chain fail2ban-<name> "` ]; then /usr/local/sbin/iptables -N fail2ban-<name>; fi
if [ -z `iptables -L INPUT | grep "^fail2ban-<name> "` ]; then /usr/local/sbin/iptables -I INPUT -p <protocol> --dport <port> -j fail2ban-<name>; fi
if [ -z `iptables -L fail2ban-<name> | grep "^DROP .* recent: UPDATE"` ]; then /usr/local/sbin/iptables -I fail2ban-<name> -m recent --name fail2ban-<name> --update --seconds <bantime> -j DROP; fi# Option: actionstop
# Notes.: command executed once at the end of Fail2Ban
# Values: CMD
#
actionstop =# Option: actioncheck
# Notes.: command executed once before each actionban command
# Values: CMD
#
actioncheck =# Option: actionban
# Notes.: command executed when banning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionban = echo +<ip> > /proc/net/xt_recent/fail2ban-<name>
/usr/bin/mysql -usystemlog -pMYPASSWORD systemlog -e "INSERT INTO fail2ban VALUES(INET_ATON('<ip>'),<port>,'fail2ban-<name>',1,now()) ON DUPLICATE KEY UPDATE hits=hits+1;"# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: <ip> IP address
# <failures> number of failures
# <time> unix timestamp of the ban time
# Values: CMD
#
actionunban = echo -<ip> > /proc/net/xt_recent/fail2ban-<name>
/usr/bin/mysql -usystemlog -pMYPASSWORD systemlog -e "DELETE FROM fail2ban WHERE source=INET_ATON('<ip>') AND jail='fail2ban-<name>;"[Init]
# Defaut name of the chain
#
name = default# Option: port
# Notes.: specifies port to monitor
# Values: [ NUM | STRING ] Default:
#
port = ssh# Option: protocol
# Notes.: internally used by config reader for interpolations.
# Values: [ tcp | udp | icmp | all ] Default: tcp
#
protocol = tcpbantime = 14400
(The value for ‘actionunban’ isn´t realy needed since xt_recent will do the job be let a ip pass by if the ban-time is over.
To restore the bans, i use simple shell-script:
#!/bin/bash
/usr/bin/mysql -usystemlog -pMYPASSWORD systemlog -e "SELECT INET_NTOA(source) FROM fail2ban WHERE (DATE_SUB(NOW(),INTERVAL $1 hour) <= last_hit) AND jail = '$2';"|grep -v source|while read IP; do
echo +$IP > /proc/net/xt_recent/$2
done
You must run this script for each jail. That´s why i added the table config. 😉
./script.sh fail2ban-pure-ftpd 2
2 is the ban-time in hours.
Woah this weblog is excellent i like studying your posts. Stay up the great paintings! You understand, lots of persons are hunting round for this information, you could help them greatly.