Wiki source for ReportingToAbuseIPDBWithFail2Ban

Show raw source

====== Reporting to """" with ""Fail2ban"" ======

This is a guide to integrating [[|Fail2ban]] and [[|]] so that each time your system blocks an attacker, it also reports the incident to ""AbuseIPDB."" //This document is a work in progress.// In lieu of registering on this wiki, please send comments and corrections to


===Background - ""Fail2ban"" and ""AbuseIPDB""=== -----
[[|Fail2ban]] is a utility that parses various system and software log files looking for signs of network abuse, and then firewalls out the offending IP addresses. It's becoming more common to crowdsource these incidents to centralized databases, so administrators can watch for patterns of abuse or pre-emptively block known malicious IPs. One of these efforts is [[|AbuseIPDB]], where attack information is compiled into reports [[|like this one]].

In this guide you'll learn how to configure ""Fail2ban"" so that it automatically reports attacks to the ""AbuseIPDB"" database. It's assumed that your system is already running ""Fail2ban.""

===Step 1: Register for ""AbuseIPDB""===-----
First, you'll need an API key from [[|]] to make any reports there. Go to their website, register for an account, and obtain an API key. If you have a large footprint (multiple servers, well-known servers, etc.) and see >1000 ""Fail2ban"" incidents per day, you probably want to register for a webmaster account, as the daily API usage limit is higher. It's free to register either way.

===Step 2: Create ""AbuseIPDB"" action configuration ===-----
Create a new file in your ""Fail2ban"" action.d directory, for example ##/etc/fail2ban/action.d/##, and name it ##abuseipdb.conf##. You **MUST** set your API key at the end of this configuration file.

%%# Fail2ban configuration file
# Action to report IP address to
# You must sign up to obtain an API key from
# Reporting an IP of abuse is a serious complaint. Make sure that it is
# serious. Fail2ban developers and network owners recommend you only use this
# action for:
# * The recidive where the IP has been banned multiple times
# * Where maxretry has been set quite high, beyond the normal user typing
# password incorrectly.
# * For filters that have a low likelihood of receiving human errors


# Option: actionstart
# Notes.: command executed once at the start of Fail2Ban.
# Values: CMD
actionstart =

# 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.
# ** IMPORTANT! **
# By default, this posts directly to AbuseIPDB's API, unfortunately
# this results in a lot of backslashes/escapes appearing in the
# reports. If you have your own web server with PHP available, you can
# use my helper PHP script by commenting out the first #actionban
# line below, uncommenting the second one, and pointing the URL at
# wherever you install the helper script. For the PHP helper script, see
# <>
# --ciphers ecdhe_ecdsa_aes_256_sha is used to workaround a
# "NSS error -12286" from curl as it attempts to connect using
# SSLv3. See
# Tags: See jail.conf(5) man page
# Values: CMD
actionban = curl --fail --ciphers ecdhe_ecdsa_aes_256_sha --data 'key=<abuseipdb_apikey>' --data-urlencode 'comment=<matches>' --data 'ip=<ip>' --data 'category=<abuseipdb_category>' ""
#actionban = curl --fail --data 'key=<abuseipdb_apikey>' --data 'comment=<matches>' --data 'ip=<ip>' --data 'category=<abuseipdb_category>' ""

# Option: actionunban
# Notes.: command executed when unbanning an IP. Take care that the
# command is executed with Fail2Ban user rights.
# Tags: See jail.conf(5) man page
# Values: CMD
actionunban =


# Option: abuseipdb_apikey
# Notes Your API key from
# Values: STRING Default: None


=== Step 3: Edit jail.local ===-----
Edit your ##fail2ban/jail.local## file to define several new actions as below. These should go below the default action definitions (action_mw, etc.) that are already defined in the file.

%%# Actions to report to via API.
# See action.d/abuseipdb.conf
action_abuseipdb_fraud = abuseipdb[abuseipdb_category="3"]
action_abuseipdb_ddos = abuseipdb[abuseipdb_category="4"]
action_abuseipdb_proxy = abuseipdb[abuseipdb_category="9"]
action_abuseipdb_forumspam = abuseipdb[abuseipdb_category="10"]
action_abuseipdb_emailspam = abuseipdb[abuseipdb_category="11"]
action_abuseipdb_blogspam = abuseipdb[abuseipdb_category="12"]
action_abuseipdb_portscan = abuseipdb[abuseipdb_category="14"]
action_abuseipdb_hack = abuseipdb[abuseipdb_category="15"]
action_abuseipdb_sqlinject = abuseipdb[abuseipdb_category="16"]
action_abuseipdb_spoofing = abuseipdb[abuseipdb_category="17"]
action_abuseipdb_sshbrute = abuseipdb[abuseipdb_category="18"]%%

Now add these new actions to each jail wherever appropriate; a jail can have multiple actions, so just add the new ones to complement any existing actions. For example, to report SSH brute force attempts to ""AbuseIPDB"", add ##action_abuseipd_sshbrute## as an action for sshd:

enabled = true
port = ssh
logpath = %(sshd_log)s
action = %(action_mwl)s # <--- This was already set as an action
%(action_abuseipdb_sshbrute)s # <--- Here is the new additional action%%

Restart ""Fail2ban"" (##service fail2ban restart## or perhaps ##fail2ban-client reload##). It will take a few minutes to re-parse all the bans; check its log files to see whether or not it's working properly. Login to your """" account and see if any reports are being submitted.

===Step 4: Optionally, install the PHP Helper Script===-----
Reports posted directly from ""Fail2ban"" to """" will, as of this writing, contain a lot of backslash/escape characters. That's because, for security purposes, ""Fail2ban"" [[|escapes the contents]] of the "matches" variable before passing it on to any action mechanism. In order to clean up my reports, as well as gain some control over filtering their contents, I created a helper script in PHP. ""Fail2ban"" posts to the PHP script instead of to ""AbuseIPDB"". The helper script does some cleaning and then posts to the ""AbuseIPDB"" API.

If you have a web server (Apache, nginx, ...) capable of running PHP, you can place this helper script somewhere on your server, and then point ""Fail2ban's"" ##action.d/abuseipdb.conf## (from Step 2) to it. I recommend restricting it via .htaccess or some other method so that only your server(s) can post to it. You should also edit in your server's own IP address, domain, your username, or anything else you don't want showing up in your reports.


/* Bail if nothing was posted to us */
if (!isset($_POST['ip'])) {

/* Remove backslashes and sensitive information from the report */
$_POST['comment'] = str_replace('\\', '', $_POST['comment']);
$_POST['comment'] = str_replace('', '[munged]', $_POST['comment']);
$_POST['comment'] = preg_replace('||mi', '[munged]', $_POST['comment']);

// If we're reporting spam, further munge any email addresses in the report
if ($_POST['category'] == 11) {
$_POST['comment'] = str_replace('@', '[at]', $_POST['comment']);

/* Post report data to */
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, '');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Required for connecting to a Cloudflare-hosted system...
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'ecdhe_ecdsa_aes_128_sha');

$reply = curl_exec($ch);
$err = curl_error($ch);

/* Send a notification email */
mail ('',
'[abuseipdb] ' . $_POST['ip'],
"Err: {$err}\n\nServer reply: {$reply}\n\nIncoming _POST:\n\n" . var_export($_POST, true) . "\n\nOutgoing post data: " . http_build_query($_POST)

Valid XHTML :: Valid CSS: :: Powered by WikkaWiki