Recidivists (repeat offenders)
Sometimes, people just can't take a hint and in some cases, the same systems will continue probing your system even after being banned several times. I choose to call these 'recidivists' and setup a special jail for them. The recidivist jail scans the fail2ban log to search for systems that have been issued a certain threshold number of bans already. If any are found, they are issued a longer-term ban. Let's go though the configuration:
Recidivist jail (jail.d/recidivist.conf)
The beginning of the file should already be familiar to you along with the fact that the 'ignoreip' parameter is optional. Remember that we are searching for repeat offenders. In other words, they have already been issued a ban by F2B so their IP will already appear in F2B's log, which is why we are searching that file.
logpath = /var/log/fail2ban.log
Timeframes here present a bit of a twist in thinking. In this case, 'maxretry' refers to how many previous bans have been issued in 'findtime' period.
maxretry = 3
findtime = 86400
In this example, I'm saying that if a particular host has already been banned 3 times in the last 24 hours (86400 seconds), then they need to be put in this jail! You should adjust these values to reflect your tolerance levels for repeat offenders. Note: The 'dbpurgeage' you specified in your fail2ban.conf file must be at least as long as your 'findtime' parameter here so there's enough history for F2B to review!
The entire point of this jail is to levy longer bantimes than ordinary jails which generally use the default set in 'jail.conf'. Therefore, we explictly specify a time here, 3 days in this case (86,400 seconds = 1 day x 3 = 259,200 seconds):
bantime = 259200
Finally, we need to let F2B know what filter to use when parsing it's own log file. We'll use the recidive filter provided by F2B for exactly this purpose. Since we are calling this filter from a jail with a different name (i.e. the jail is not also called 'recidive'), we have to make that clear to the filter. Finally, we also enable the jail.
filter = recidive[_jailname="recidivist"]
enabled = true
Apply the extended ban via iptables directly
You'll notice that the 'recidivist' jail configuration contains the following line:
banaction = iptables-allports
This means that the ban is generated by creating a rule directly applied to your iptables configuration and not through UFW. This is because UFW has no facility to tag or otherwise distinguish rules apart from their index number. As such, it's possible for the UFW-probe jail unban process to erase the longer-term recidivist ban and vice versa. To avoid this conflict, we have the longer-term rule apply to iptables directly as a separate rule so UFW-probe can ban/unban independently as needed without any risk of conflicts.