System: Using a Fail2Ban Jail to Whitelist a User
Let's suppose we have a directory /login/ which our users need to connect to using Basic Auth or similar authentication. Most CMS's have an address of this type, and they tend to attract a lot of attention from botnets and other automated scripts.
Leaving aside for now other security options (using a different port, certificate based authentication, port knocking, etc.) let's look at how we can aggressively ban failed login attempts while limiting the chances of also blocking a valid user for mis-typing their login because CAPS was on.
The following has been tested in Fail2Ban 0.9.3. The same approach will also work in 0.8.13, but trying to reload the whitelist jail will hang the process, requiring a messy KILL and restart, so it's not advised. See below for upgrade instructions.
Blocking with Fail2Ban
First the simple part. You should be familiar by now with the basic Fail2Ban configuration for setting up a jail/filter. If not, there are plenty of examples included with a default installation.
First we define the jail apache-loginfail as follows:
[apache-loginfail] enabled = true port = http,https logpath = %(apache_access_log)s maxretry = 5 bantime = 172800
Using Debian, apache_access_log maps to /var/log/apache2/*access.log. Other platforms may use a different path, and earlier versions of Fail2Ban need an explicit path here.
The regular expressions for detecting a failed login go into the filters directory:
[INCLUDES] before = apache-common.conf [Definition] failregex = ^<HOST> .* "(GET|POST) /login/.*" (401|403|404) ignoreregex =
So we're going to catch any requests for the /login/ directory that result in a 40* error, and ban them after five (5) attempts and for a period of 48 hours.
At this point you should run some tests to verify that the jail is set up correctly before you activate it - most easily by just restarting the Fail2Ban daemon:
# systemctl restart fail2ban.service
or more properly using the built-in commands:
# fail2ban-client add apache-loginfail auto # fail2ban-client start apache-loginfail
Make sure that the address you want to protect does not appear on any public pages as a clickable link. If it does, use rel="nofollow" on the link and add /login/ to your robots.txt file. Otherwise you will just end up blocking harmless spiders.
Setting up a whitelist action
Everything to this point is vanilla Fail2Ban. What we want to do next is a bit more complicated.
We know we can 'whitelist' ip addresses using the Fail2Ban configuration files:
ignoreip = 127.0.0.1/8 192.168.0 secure.example.net
Or dynamically using the command-line tool:
# fail2ban-client set apache-loginfail addignoreip 22.214.171.124
But what we want to do is to automatically add users to the whitelist immediately after they perform a successful login. That will protect them from being banned until/unless the whitelisting as expired.
This requires three (3) separate files:
1. Jail definition: /etc/fail2ban/jail.d/apache-whitelist.conf
[apache-whitelist] enabled = true port = http,https logpath = %(apache_access_log)s action = ignoreip[name=apache-loginfail] maxretry = 1 bantime = -1
2. Filter definition: /etc/fail2ban/filter.d/apache-whitelist.conf
[Definition] failregex = ^<HOST> .* "GET /login/.*" 200 ignoreregex =
3. Action definition: /etc/fail2ban/action.d/ignoreip.conf
[Definition] actionstart = actionstop = actioncheck = iptables -n -L <chain> | grep -q 'f2b-<name>[ \t]' actionban = fail2ban-client set <name> addignoreip <ip> actionunban = fail2ban-client set <name> delignoreip <ip> [Init] name = default chain = INPUT
In the Fail2Ban 0.10 we have had to remove the actioncheck condition as Fail2Ban instantiates the f2b-* iptables chains only on demand and not by default.
What's new in the above jail is the action setting. Instead of using one of the built-in actions to manipulate iptables rules we've created a new action ignoreip which instead runs Fail2Ban client commands. Actions can be used to run just about anything from sending emails to restarting services.
You can think of the ignoreip action as a function, taking the name of a jail as the parameter. When the filter is triggered by a successful login (any request to the secure directory returning 200 OK) the ignoreip action is called with the 'name' variable set to 'apache-loginfail'.
What happens next should be obvious. Instead of being added to an iptables chain, the captured ip address will instead be added to the 'ignoreip' list for the 'apache-loginfail' jail. And because we set 'bantime' to '-1' it will stay there indefinitely so the user can no longer run afoul of the failed login jail.
If you want to be notified when anyone is whitelisted, check out the sendmail-whois action. Otherwise you can follow the logs in /var/log/fail2ban.log, or use the command line:
# fail2ban-client get apache-loginfail ignoreip
Our actual settings are as usual a bit more complex, and we don't monitor the access log/s directly, but via an rsyslog filter. More on that later.
If you get this working on your own server, or have questions, get in touch using our Feedback Form.
Installing Fail2Ban 0.9 from 'stretch'
If you're running Debian stable and want to install a newer version of Fail2Ban from testing, you first need to include the 'testing' archived in you apt-sources:
deb ftp://ftp.debian.org/debian/ stretch main deb-src ftp://ftp.debian.org/debian/ stretch main
Then pin the Fail2Ban package so it prefers the 'testing' version:
Package: * Pin: release o=Debian,a=testing Pin-Priority: -1 Package: fail2ban Pin: release o=Debian,a=testing Pin-Priority: 900
And finally run the installer:
# apt-get -u install fail2ban
Be aware that, if you're not doing a clean install, upgrading to Fail2Ban 0.9 involves changes to existing jail definitions as well as to the Fail2Ban file structure.;>
Related Articles - Fail2Ban
- Monitoring the fail2ban log [SYSTEM]
- Optimising your Fail2Ban filters [SYSTEM]
- fail2ban and iptables [SYSTEM]
- Using a Fail2Ban Jail to Whitelist a User [SYSTEM]
- Blocking FTP Hacking Attempts [SYSTEM]
- Fail2Ban 0.8.3 Howto [SYSTEM]
- Using systemd to bind fail2ban to nftables [SYSTEM]
- Implementing Port Knocking with knockd [SYSTEM]
- fail2ban and sendmail [SYSTEM]
Send a message to The Art of Web:
press <Esc> or click outside this box to close