Apache and Fail2ban

Intro

I wanted Apache to show a nice and informative error page to clients that try to access some protected website using wrong credentials repeatedly. Instead of Fail2ban to block these clients at the IP level, e.g. with ipfw, this howto uses a RewriteMap of mod_rewrite and httxt2dbm.

Setup

  1. Create /usr/local/etc/fail2ban/action.d/httxt2dbm.local:
    [Definition]
    actionstart = touch /var/run/fail2ban/<name>.lck
                  echo -n | lockf -kn /var/run/fail2ban/<name>.lck httxt2dbm -f db -i - -o /var/run/fail2ban/<name>.db
                  chmod g+r /var/run/fail2ban/<name>.db
                  chgrp www /var/run/fail2ban/<name>.db
    actionban = echo "<ip> y" | lockf -kn /var/run/fail2ban/<name>.lck httxt2dbm -f db -i - -o /var/run/fail2ban/<name>.db
    actionunban = echo "<ip> n" | lockf -kn /var/run/fail2ban/<name>.lck httxt2dbm -f db -i - -o /var/run/fail2ban/<name>.db
    
    Please note:
  2. Your /usr/local/etc/fail2ban/jail.local now might contain this jail:
    [website-apache]
    enabled = yes
    filter = apache-auth
    action = httxt2dbm
    logpath = /var/log/httpd-error.log
    
    Of course you might specify multiple actions:
    ...
    action = sendmail-whois-lines
             httxt2dbm
    ...
    
    If you have multiple jails that feed the same ip database, then provide the same name to each httxt2dbm action as the filenames of both the database and the lockfile in /var/run/fail2ban are derived from the jail's name by default:
    [website1-apache]
    ...
    action = httxt2dbm[name=website-apache]
    ...
    [website2-apache]
    ...
    action = httxt2dbm[name=website-apache]
    ...
    
  3. Your /usr/local/etc/apache24/httpd.conf should contain something like this:
    ...
    LoadModule rewrite_module libexec/apache24/mod_rewrite.so
    ...
    RewriteEngine on
    RewriteMap fail2ban-website "dbm=db:/var/run/fail2ban/website-apache.db"
    RewriteCond ${fail2ban-website:%{REMOTE_ADDR}|n} =y
    RewriteRule .* /access-denied.html [PT]
    
    The PT flag of the above RewriteRule allows you to provide the error page as a CGI script or so.