Fail2ban

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen

fail2ban is a tool designed to block suspicious server visits:

  • Log files are real-time scanned for suspicious behaviour. (Apache, PHP, SSH, etc.)
  • Scanning is done according to configurable filters. This is done through Python
  • Selected lines are added to iptables - So, the actual blocking is done through iptables, which seems like an efficient approach to blocking
  • Duration of these blocking rules is configurable. E.g., an hour for repeated inlog failures, or a month for an known unwanted crawler.

Overview

What it does

  • Monitors Log Files: Fail2ban scans log files for specific patterns that indicate suspicious activity, such as failed login attempts or other anomalies
  • Blocks IP Addresses: When it detects repeated failed attempts from a particular IP address, it can temporarily or permanently block that IP address using firewall rules (such as with iptables, nftables, or firewalld)
  • Configurable: You can customize Fail2ban to monitor different services and define what constitutes "bad behavior." It can protect various services like SSH, FTP, HTTP, and more.

How it works

  • Jails: Fail2ban uses "jails," which are configurations specifying which log files to monitor, what patterns to look for, and what actions to take. Each jail is associated with a particular service or application
  • Filters: Filters are used within jails to define the patterns of failed attempts. These are often specified using regular expressions
  • Actions: When a pattern is detected, Fail2ban can execute various actions, typically involving updating firewall rules to block the offending IP addresses.

Configuration

  • Main Configuration File: /etc/fail2ban/jail.conf (though it's a good practice to create and modify /etc/fail2ban/jail.local to avoid overwriting the default settings)
  • Filters Directory: /etc/fail2ban/filter.d/ contains filter definitions
  • Actions Directory: /etc/fail2ban/action.d/ contains predefined actions for blocking IPs.

Benefits

  • Flexible: Fail2ban can probably be configured for any network function that maintains a log file
  • Makes WordPress security plugins superfluous? Would be nice if I can dump WordFence
  • Efficient: Fail2ban has been written in Python, while the actual banning is (in our case) done by iptables. Using a low-level tool like iptables for filtering, is much more efficient than using WordPress plugins like WordFence
  • Temporary blocking: It's really nice that blocks can be temporary, so in case someone genuinely makes 20 mistakes in a row, or if a hacked IP address eventually gets unhacked, that they regain access.

Disadvantages

Fail2ban basically does what it says on the package, but it does come with quite some challenges:

Aspect Remarks
Learning curve
  • Quite hard to sufficiently understand how it works
  • Reminds me of configuring systems like Sendmail, Asterisk or DIY VPN
  • I probably wouldn't have been able to deploy fail2ban without ChatGPT
Risky The high learning curve makes it risky to deploy fail2ban: New suprises might lurk everywhere
High maintenance
  • AFAIK, I need to regularly update filter settings myself
  • E.g., update apache-badbots signatures every week or month or so
  • This has organisational consequences - The kind that I don't really like

Alternatives

Alternative Remarks
CrowdSec Probably the most obvious alternative to Fail2ban
  • Community-driven: banned IP addresses can be shared across users
  • More complex than Fail2ban
Own scripts Have own scripts that parse Apache logs and derives firewall rules - We actually use this concurrency with Fail2ban right now
  • Seems easy and manageable right now
  • Probably not so easy and manageable anymore when scaling
Manual blocks
  • Occasionally, I go more-or-less manually through Apache Access logs to extract user agents for blocking through Apache-badbots. Part of this has been automated, including parsing Apache log files using awk
  • This takes too much time and feels amateurishly - This is rather an indication that I should master tools like Fail2ban better
  • Impossible to be sufficiently accurate - badbots has been blocking 80,000 bots within a couple of hours. That's not something to replicate manually

Additional measures

In follow-up to the alternatives mentioned before: Some ideas about additional measures, as it is never a good idea to rely on just one tool.

Measure Remarks
Apache user
agent blocks
  • Apache operates at the application level of the network model, so it can directly inspect user agent strings, which a firewall can't
  • Use this to block badbots
  • Preferably through a server-wide configuration file, rather than through individual AVHCFs or individual .htaccess files
  • If this works, remove similar settings that are currently deployed at AVHCFs
Robots.txt
  • Some badbots adhere to robots.txt directives, including supposingly ClaudeBot
  • Preferably, maintain just one robots.txt file and link from there to various sites
  • Use the existing Fail2ban filter signatures - As single source of truth
External
firewalls
Use external firewalls like Cloudflare - This could be an excellent solution:
  • Scalable: It doesn't take performance of our own web server
  • Easy to outsource: Very clear what such a service would entail
  • Including maintenance: This too could easily be done

Note: Existing rules flushed on restart

By default, when fail2ban is restarted, it flushes the existing iptables rules that it manages. This happens because fail2ban is designed to reinitialize its own firewall rules upon starting or restarting. Specifically, it clears and rebuilds the rules in the chains it manages (typically named f2b-*), which means any existing bans applied by fail2ban will be removed and need to be re-added as fail2ban reads the log files and re-applies bans.

Note that fail2ban probably doesn't flush rules outside the f2b-* chains: Those might get flushed when restarting a webserver, as iptables' rules are not persistent across restarts of iptables.

Start & stop

Basic commands

sudo systemctl stop fail2ban
sudo systemctl disable fail2ban
sudo systemctl enable fail2ban

Restart

To restart Fail2Ban on a systemd-based system like Ubuntu Server:

sudo systemctl restart fail2ban

To verify that it restarted correctly:

sudo systemctl status fail2ban

Or check logs in real-time:

sudo journalctl -u fail2ban -f

Restarting Fail2ban, has quite some consequences:

  • The Fail2Ban daemon (fail2ban-server) stops and restarts
  • For all jails, the stop actions that are defined within them, are called
  • All f2b chains are flushed and deleted. Also jumps from INPUT to these chains, get deleted
  • It reloads its configuration files: fail2ban.conf, jail.conf, jail.local, and any custom filters in filter.d/.
  • All jails are re-initialized: f2b- chains are newly created
  • Jumps will be inserted to these f2b- chains, typically in table INPUT, by default using iptables -I INPUT 1, which might be quite a problem. This is usually defined through iptables-common.conf but can be overriden or replaced, etc. - See elsewhere
  • All IPs previously banned by Fail2Ban are unbanned, unless banaction has been configured to include external persistence.

Reload

You can reload Fail2Ban's configuration without a full restart using

sudo fail2ban-client reload

This is much lighter than a full systemctl restart fail2ban. Here's what it does:

  • Re-reads all configuration files (jail.conf, jail.local, jail.d/*.conf, etc.)
  • Reloads all jails with the new config
  • Preserves currently banned IPs; In-memory retry counters; Running log monitors
  • Rebuilds the f2b-* chains if the jail’s action config changed

Use reload when:

  • You've modified jail/filter config files
  • You want the changes to take effect
  • But you don’t want to drop active bans or trigger a full restart.

Reload individual jails

Reload a single jail:

sudo fail2ban-client reload apache-badbots

Status & overview

There are different ways to check status and to get an overview of how Fail2ban is doing.

Summary:

sudo systemctl status fail2ban
sudo fail2ban-client -d
sudo fail2ban-client status
sudo fail2ban-client status apache-badbots
sudo fail2ban-client get apache-badbots logpath
sudo fail2ban-client get apache-badbots filter
sudo fail2ban-client get apache-badbots action
sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-badbots-custom.conf

Check daemon status

Example of an active instance:

$ sudo systemctl status fail2ban

● fail2ban.service - Fail2Ban Service
     Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
     Active: active (running) since Wed 2024-09-18 04:05:35 CEST; 3 weeks 2 days ago
       Docs: man:fail2ban(1)
   Main PID: 2350 (fail2ban-server)
      Tasks: 15 (limit: 115387)
     Memory: 30.4M (peak: 49.2M swap: 2.3M swap peak: 2.3M)
        CPU: 2h 48min 56.177s
     CGroup: /system.slice/fail2ban.service
             └─2350 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

Notice: journal has been rotated since unit was started, output may be incomplete.

Example of a paused instance:

$ sudo systemctl status fail2ban

○ fail2ban.service - Fail2Ban Service
     Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
     Active: inactive (dead) since Fri 2024-10-11 12:41:25 CEST; 54s ago
   Duration: 3w 2d 8h 35min 48.694s
       Docs: man:fail2ban(1)
    Process: 2350 ExecStart=/usr/bin/fail2ban-server -xf start (code=killed, signal=TERM)
    Process: 2407962 ExecStop=/usr/bin/fail2ban-client stop (code=exited, status=0/SUCCESS)
   Main PID: 2350 (code=killed, signal=TERM)
        CPU: 2h 48min 56.608s

Oct 11 12:41:24 server2 systemd[1]: Stopping fail2ban.service - Fail2Ban Service...
Oct 11 12:41:25 server2 fail2ban-client[2407962]: Shutdown successful
Oct 11 12:41:25 server2 systemd[1]: fail2ban.service: Deactivated successfully.
Oct 11 12:41:25 server2 systemd[1]: Stopped fail2ban.service - Fail2Ban Service.
Oct 11 12:41:25 server2 systemd[1]: fail2ban.service: Consumed 2h 48min 56.608s CPU time, 49.2M memory peak, 2.3M memory >
Notice: journal has been rotated since unit was started, output may be incomplete.

Check & dump complete configuration

I quite like

sudo fail2ban-client -d

because it checks the syntax of the configuration files, prior to dump it in a Jason-like format.

What it can't do:

  • Tell from which configuration files it got its information
  • Limit output to a specific jail, but this seems to work fine using grep.

Example:

$ sudo fail2ban-client -d | grep apache-badbots

2025-05-11 20:28:19,673 fail2ban.configreader   [1835052]: WARNING 'allowipv6' not defined in 'Definition'. Using default one: 'auto'
['add', 'apache-badbots', 'polling']
['set', 'apache-badbots', 'usedns', 'warn']
['set', 'apache-badbots', 'addfailregex', '^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"(?:AliyunSecBot|ALittle Client|AwarioBot|Axios|Barkrowler|BitSightBot|Bloglines|bne\\.es_bot|Bulid|Bytedance|CensysInspect|ClaudeBot|coccocbot|curl|Custom-AsyncHttpClient|DataForSeoBot|DomainStatsBot|DotBot|Expanse|facebookcatalog|facebookexternalhit|Foregenix|Go-http-client|Google-Firebase|google-xrawler|GRequests|GuzzleHttp|GPTBot|Hello World|hello-world|heritrix|idealo-bot|ImagesiftBot|imagor|InternetMeasurement|ips-agent|ivre-masscan|Java|jorgee|Keydrop\\.io|KlarnaBot|Konqueror/4\\.2|l9explore|l9tcpid|LG-GC900|libwww-perl|Links \\(2\\.1|Linux Mozilla|masscan|meta-externalagent|MJ12bot|Moblie|ModatScanner|mozilla/2|mozilla/3|mozillia/4|Mozlila|MS Search 6|MSIE ?\\(?(4|5|6|7|8|9|10)|Nicecrawler|NT 11)|OI-Crawler|petalbot|PHP|presto|python-requests|reqwest|robertdavidgraham|Safari 1\\.2\\.4|SemrushBot|SEOkicks|serpstatbot|Slackbot|Slackware/13\\.0|sogou|tchelebi|VelenPublicWebCrawler|WebwikiBot|Wikistats|Win 9x|Win32|WinNT4|Windows (_?95|98|CE|ME|NT (4|5|6\\.0|6\\.1|6\\.2)|Mobile|Phone)|Windows NT (4|5|6\\.0|6\\.1|6\\.2)|yandex|yie9|YisouSpider|Zend_Http_Client|ZoominfoBot)"$']
['set', 'apache-badbots', 'datepattern', '^[^\\[]*\\[({DATE})\n{^LN-BEG}']
['set', 'apache-badbots', 'maxretry', 1]
['set', 'apache-badbots', 'maxmatches', 1]
['set', 'apache-badbots', 'findtime', '3600']
['set', 'apache-badbots', 'bantime', '2592000']
['set', 'apache-badbots', 'ignorecommand', '']
['set', 'apache-badbots', 'addignoreip', '127.0.0.1/8', '::1', '178.128.44.198', 'file:/etc/fail2ban/whitelist.conf']
['set', 'apache-badbots', 'logencoding', 'auto']
['set', 'apache-badbots', 'addlogpath', '/var/log/apache2/access.log', '\\']
['set', 'apache-badbots', 'addlogpath', '/var/log/apache2/example_com_access.log', '\\']
['set', 'apache-badbots', 'addlogpath', '/var/log/apache2/other_vhosts_access.log', 'head']
['set', 'apache-badbots', 'addaction', 'iptables-multiport']
['multi-set', 'apache-badbots', 'action', 'iptables-multiport', [['actionstart', "{ <iptables> -C f2b-apache-badbots -j RETURN >/dev/null 2>&1; } || { <iptables> -N f2b-apache-badbots || true; <iptables> -A f2b-apache-badbots -j RETURN; }\nfor proto in $(echo 'tcp' | sed 's/,/ /g'); do\n{ <iptables> -C INPUT -p $proto -m multiport --dports http,https -j f2b-apache-badbots >/dev/null 2>&1; } || { <iptables> -A INPUT -p $proto -m multiport --dports http,https -j f2b-apache-badbots; }\ndone"], ['actionstop', "for proto in $(echo 'tcp' | sed 's/,/ /g'); do\n<iptables> -D INPUT -p $proto -m multiport --dports http,https -j f2b-apache-badbots\ndone\n<iptables> -F f2b-apache-badbots\n<iptables> -X f2b-apache-badbots"], ['actionflush', '<iptables> -F f2b-apache-badbots'], ['actioncheck', "for proto in $(echo 'tcp' | sed 's/,/ /g'); do\n<iptables> -C INPUT -p $proto -m multiport --dports http,https -j f2b-apache-badbots\ndone"], ['actionban', '<iptables> -I f2b-apache-badbots 1 -s <ip> -j <blocktype>'], ['actionunban', '<iptables> -D f2b-apache-badbots -s <ip> -j <blocktype>'], ['port', 'http,https'], ['protocol', 'tcp'], ['chain', '<known/chain>'], ['name', 'apache-badbots'], ['actname', 'iptables-multiport'], ['blocktype', 'REJECT --reject-with icmp-port-unreachable'], ['returntype', 'RETURN'], ['lockingopt', '-w'], ['iptables', 'iptables <lockingopt>'], ['blocktype?family=inet6', 'REJECT --reject-with icmp6-port-unreachable'], ['iptables?family=inet6', 'ip6tables <lockingopt>']]]
['start', 'apache-badbots']

List active jails

fail2ban-client is basically a CLI to communicate with the fail2ban daemon (fail2ban-server), maybe similarly to how the CLI command mysql is effectively a tool to communicate with a MySQL-server.

What you can do with fail2ban-client:

  • Check status (fail2ban-client status)
  • Enable or disable jails
  • Ban or unban IPs manually
  • Reload or restart the server
  • Test filters
  • Debug configurations.

Example:

$ sudo fail2ban-client status

Status
|- Number of jail:	7
`- Jail list:	apache-auth, apache-badbots, apache-get-dos, apache-noscript, apache-overflows, php-url-fopen, sshd

See detailed info per jail

Use

sudo fail2ban-client status <jailname>

without the f2b- prefix.

Example (1)

$ sudo fail2ban-client status apache-auth

Status for the jail: apache-auth
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	3017
|  `- File list:	/var/log/apache2/error.log
`- Actions
   |- Currently banned:	44
   |- Total banned:	2752
   `- Banned IP list:	76.167.231.121 185.50.25.3 89.253.240.73 5.188.159.153 54.36.208.50 185.194.217.18 194.163.151.88 23.92.26.113 101.58.155.111 83.166.133.74 157.230.24.5 46.36.217.232 91.134.248.211 185.50.25.42 217.160.207.42 195.225.221.2 125.23.86.26 54.66.48.110 181.214.164.79 212.56.54.91 43.243.60.101 206.189.18.26 158.255.6.93 173.236.254.75 193.70.39.165 51.68.11.199 159.65.137.64 85.128.143.16 170.81.42.166 34.13.135.125 212.227.50.191 149.50.149.75 151.80.19.225 43.153.98.152 40.90.184.1 78.193.66.197 162.241.2.41 45.156.184.39 141.8.192.164 188.165.192.229 92.205.64.128 162.241.217.171 212.125.4.212 111.119.194.119

Example (2)

Yes, apache-badbots has 76.000 IP adresses. And it's only active for about 36 hours. Bans are for a month, hence the number of currently banned and total banned are the same.

$ sudo fail2ban-client status apache-badbots

Status for the jail: apache-badbots
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	109218
|  `- File list:	/var/log/apache2/access.log
`- Actions
   |- Currently banned:	76452
   |- Total banned:	76452
   `- Banned IP list:	18.223.125.111 1.162.78.248 1.178.223.215 1.179.75.62 1.180.121.47 1.181.171.55 1.182.19.171 1.182.23.129 1.183.100.133 1.187.217.55 1.187.226.253 1.187.227.47 1.187.232.232 1.187.239.214 1.188.128.157 1.188.146.57 1.189.181.163 1.191.10.147...

More details per jail

Returns an array with IP addresses:

sudo fail2ban-client get apache-badbots banned

See what logpath is being used:

$ sudo fail2ban-client get apache-badbots logpath

Current monitored log file(s):
`- /var/log/apache2/access.log

Number of retries, findtime & bantime:

$ sudo fail2ban-client get apache-badbots maxretry
1

$ sudo fail2ban-client get apache-badbots findtime
3600

$ sudo fail2ban-client get apache-badbots bantime
2592000

This approach doesn't work to retrieve the value for filter, enabled or port.

Check fail2ban log

Fail2ban maintains a log file, typically to be found at /var/log/fail2ban.log. Probably my favourite way to check this log:

sudo tail -f /var/log/fail2ban.log

or

sudo tail -n 50 /var/log/fail2ban.log

An example of the output of the first command:

$ sudo tail -f /var/log/fail2ban.log

2025-05-08 12:02:00,644 fail2ban.filter    [2341]: INFO    [apache-auth] Found 111.119.194.119 - 2025-05-08 12:02:00
2025-05-08 12:02:00,856 fail2ban.actions   [2341]: NOTICE  [apache-auth] Ban 111.119.194.119
2025-05-08 12:03:11,944 fail2ban.filter    [2341]: INFO    [apache-get-dos] Found 20.236.227.53 - 2025-05-08 12:03:11
2025-05-08 12:06:00,122 fail2ban.actions   [2341]: NOTICE  [apache-auth] Unban 76.167.231.121
2025-05-08 12:06:00,146 fail2ban.actions   [2341]: NOTICE  [apache-auth] Unban 185.50.25.3

Appearantly, tail -f automatically shows the most recent 10 lines and subsequently adds lines in real-time when they appear.

f2s

f2s, an abbreviation of Fail2ban Status is an own script, that displays info about all inidividual jails. It's included in the usual Git account - not an alias in .bashrc

System of configuration files

It probably helps to have a good overview of the system of configuration files, to know where to look for stuff. This is just an impression:

File Remarks
paths-common.conf
  • Global configuration file
  • E.g.: apache_access_log = /var/log/apache2/*access.log
paths-debian.conf Similar to paths-common.conf but less used
jail.conf
  • General defaults and jail-specific defaults
  • You're not supposed to edit this file. Use jail.local or jail.d/ for this
  • Example of a general default: banaction = iptables-multiport

Example of a jail default - Note that it doesn't specify a banaction, but resorts to the default jail-independent value:

# [apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
#
# Commented-out - 2025.05.09
#
# port     = http,https
# logpath  = %(apache_access_log)s
# bantime  = 48h
# maxretry = 1
jail.local
  • Overrules jail.conf
  • OK to edit this file
  • I prefer to use separate files for each jail in directory jail.d/
jail.d/
(directory)
My preferred location for jail configuration files + commenting-out earlier definitions in jail.conf and jail.local
jail.d/custom.conf Contains default values for bantime, findtime and banaction. I'm not sure if this file is actually used
filter.d/
(directory)
  • Contains some 95 default filters: Configuration files to filter out some traffic. E.g., for Apache, Asterisk, Drupal, etc.
  • I prefer to create own filter files with -custom in their name. E.g.: apache-badbots-custom.conf
action.d/
(directory)
Contains some 64 default actions
action.d/iptables.conf
  • This is the file that is actually invoked for banaction iptables-multiport * File iptables-multiport.conf is obsolete

Within this file, specific actions are defined (in addition to other things) - and customized:

  • actionflush
  • actionstart
  • actionstop
  • actioncheck
  • actionban - Customized to insert iptables rules, rather than append
  • actionunban

Jails

A jail is a combination of three things:

Thing Remarks
log The log file to be read
filter
  • A set of regex rules to catch suspicious patterns, like failed login attemps
  • There are some 96 predefined filters, defined in directory /etc/fail2ban/filder.d
action What to do when a rule is triggered. Usually banning with a certain bantime

Appearantly, there is no such thing as a default set of jails. The list of jails at the server I'm currently looking at:

  • apache-auth
  • apache-badbots
  • apache-get-dos
  • apache-noscript
  • apache-overflows
  • php-url-fopen
  • sshd

Jail configuration options

Jails can be configured at different levels:

Jail configuration file Remarks
/etc/fail2ban/jail.conf Contains default configurations for a bunch of jails. However: Don't edit this file, as it might get overwritten with updates
/etc/fail2ban/jail.local Better: Incorporate jail configuration overrides in this file
/etc/fail2ban/jail.d/ (directory) Store jail overrides in this directory, with a separate file for each jail.

Example of the content of this directory (2025.04):

  • apache-get-dos.conf
  • custom.conf
  • defaults-debian.conf
  • sshd.conf

Jail configuration files

Of the various options mentioned above, I prefer to use separate files for each jail in directory /jail.d.

Examples of these files:

File name Content and/or remarks
apache-get-dos.conf
[apache-get-dos]
enabled  = true
port     = http,https
filter   = apache-get-dos
logpath  = /var/log/apache2/*access.log
datepattern = %%d/%%b/%%Y:%%H:%%M:%%S %%z
maxretry = 300
findtime = 5m
bantime  = 1h
custom.conf
[DEFAULT]
bantime  = 300
findtime = 300
banaction = iptables-allports
defaults-debian.conf Empty
sshd.conf slightly censored version of the actual file - Looks like a regular simple jail configuration file:
[sshd]
enabled = true
port: 20
logpath = %(sshd_log)s
backend = %(sshd_backend)s
bantime = 600
findtime = 650
maxretry = 5

Configuring filters

Default filters are available at /etc/fail2ban/filter.d/

Configuring iptables for fail2ban

Since April 2025, we use the folling structure for iptables' INPUT chain:

Chain Remarks
WHITELIST At the top: Stuff that always has to be accepted, starting with SSH access for administrators to the server
BLOCKBOT Ad-hoc fail2ban-like script that we're using while configuring fail2ban
f2b chains E.g.: f2b-apache-auth
PUBLIC
  • Finally: Traffic that made it so far, is hopefully legitimate traffic, so let's accept it: HTML at :80 & :443
  • This chain is needed because the default policy for INPUT is drop.

Fail2ban creates its own chains for the INPUT table, if not present. It's quite picky with the exact name and characteristics of chains. If the exactly needed chain isn't present, fail2ban will create it, and there might be two chains with a seemingly identical name.

apache-badbots jail

For apache-badbots, see the separate chapter later on.

apache-nohome jail

apache-nohome jail is designed to catch bots or scanners that try to access non-existent user directories or homepages, especially those that follow patterns like:

  • GET /~admin/
  • GET /~root/
  • GET /~user/

These requests target legacy Apache behavior where user directories could be accessed via http://example.com/~username/. Most modern servers don’t support this anymore, so these requests almost always return 404.

apache-noscript jail

The apache-noscript jail in Fail2ban is designed to catch bots (or humans) trying to access script files that shouldn’t exist, like:

  • /login.php
  • /wp-login.php
  • /admin.asp
  • /shell.cgi
  • /xmlrpc.php
  • /phpMyAdmin

These requests are typical of malicious crawlers, automated vulnerability scanners, or botnets looking for common CMS or admin panels to exploit.

Case: Configure apache-badbots (2025.05)

apache-badbots, is the usual jail for catching known unwanted bots and crawlers, based on their user-agent strings. They are immediately banned, as soon as they appear

Part Remarks
log The log file to be read
filter /etc/fail2ban/filter.d/apache-badbots.conf: Basically a list of user-agent strings
action What to do when a rule is triggered. Usually banning with a certain bantime

We used to include these in AVHCFs, but probably better to include them in Fail2Ban:

  • More flexible to configure them in fail2ban: One specification for the whole server, rather than for each individual AVHCF
  • More intuitive to configure them in fail2ban, as this is a more obvious place to look for such things
  • Lower treshhold for updating them - Again, because it's only one place where to do this
  • Probably more CPU-efficient, as this results in iptable records, and those are surely more efficient than whatever Apache uses.

See also

Sources