Fail2ban

The fail2ban service scans log files for patterns of specific repeated attempts (for instance, unsuccessful SSH authentication attempts or high volume GET/POST requests on a web server) and, when detected, automatically creates a firewall or TCP wrappers drop or deny rule to ensure the service availability is not jeopardized.

Although the service supports many services out-of-the-box, it is very versatile in its configuration and can easily be enhanced.

Jailing
The primary purpose of fail2ban is to jail services. When a service, such as SSHd, is jailed, then fail2ban will continuously look in the log(s) of that service for possible repeated attempts. The moment that a given number of attempts is detected within a particular time window  then a blocking rule (such as through iptables) is automatically set for a given time period.

The settings of these jails is done through. By default, fail2ban already provides a nice file, but all jails are by default disabled so that the service, when started by the administrator, wouldn't accidentally filter out valid requests.

jail.d
Jails can and should be broken into individual jail files. Individual jails are easier to sort through, and disable or enable. Fail2ban uses syntax, so moving  to  will disable the jail.

Filter expressions
Inside various filtering definitions can be created. Generally, these files contain regular expressions that match attempts. When a regular expression is matched on a file, then the counter for that jail and the offending host is increased.

Actions
Inside various action definitions can be created. These files contain commands to execute to ban and unban a given host. By default, rules exist for iptables, tcpwrappers, shorewall and more.

Log scanning
The fail2ban service supports both file polling or more efficient file modification notifications; when or  is installed and the user did not change the   directive, then pyinotify or gamin will be used, otherwise polling is done. This can of course be configured in.

Installation
Installing is as simple as:

At the time of writing, no USE flags are to be set (the SELinux USE flag is not selectable and is for use by SELinux-enabled systems). If you want to use gamin, install too:

Configuration
To configure fail2ban, go to.

Start with as that contains which rules you want to use (and which services to control) and only override the appropriate settings and enable the rules in. If necessary, you can create your own filters or actions.

For example to enable the default SSH filters for rsyslog users:

Or for syslog-ng users:

When you are finished, start the fail2ban service. You probably also want to add it to the default runlevel.

Interacting
As part of the fail2ban service, there is also a fail2ban-client available. With this application you can query the fail2ban service.

For instance, to see the running jails:

You can obtain specific information about each jail, such as the list of currently banned addresses, executed filters, etc.

Troubleshooting
When you think the filters are not working properly, you can use fail2ban-regex to try them out. You pass it the log file to check and the filter to run, and it will give back what it found.

{{RootCmd|fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf|output= Running tests

=
Use regex file : /etc/fail2ban/filter.d/sshd.conf Use log file  : /var/log/auth.log

Results

=
Failregex `- Number of matches: [1] 30 match(es) [2] 0 match(es) [3] 0 match(es) [4] 0 match(es) [5] 0 match(es) [6] 0 match(es) [7] 0 match(es) [8] 0 match(es) [9] 0 match(es) [10] 0 match(es)
 * - Regular expressions:
 * [1] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*(?:error: PAM: )?Authentication failure for .* from \s*$
 * [2] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*(?:error: PAM: )?User not known to the underlying authentication module for .* from \s*$
 * [3] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*Failed (?:password|publickey) for .* from (?: port \d*)?(?: ssh\d*)?$
 * [4] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*ROOT LOGIN REFUSED.* FROM \s*$
 * [5] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*[iI](?:llegal|nvalid) user .* from \s*$
 * [6] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*User \S+ from  not allowed because not listed in AllowUsers$
 * [7] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*authentication failure; logname=\S* uid=\S* euid=\S* tty=\S* ruser=\S* rhost=(?:\s+user=.*)?\s*$
 * [8] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*refused connect from \S+ \(\)\s*$
 * [9] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*reverse mapping checking getaddrinfo for .* \[\] .* POSSIBLE BREAK-IN ATTEMPT\!\s*
 * [10] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*User \S+ from  not allowed because none of user's groups are listed in AllowGroups$

Ignoreregex `- Number of matches:
 * - Regular expressions:

Summary

=
Addresses found: [1]   192.168.100.50 (Wed Dec 28 12:46:56 2011) 192.168.100.50 (Wed Dec 28 12:47:00 2011) 192.168.100.50 (Wed Dec 28 12:47:03 2011) 192.168.100.50 (Wed Dec 28 12:47:15 2011) 192.168.100.50 (Wed Dec 28 12:47:18 2011) 192.168.100.50 (Wed Dec 28 12:47:21 2011) 192.168.100.50 (Wed Dec 28 14:23:08 2011) 192.168.100.50 (Wed Dec 28 14:23:12 2011) 192.168.100.50 (Wed Dec 28 14:23:23 2011) 192.168.100.50 (Wed Dec 28 14:23:28 2011) 192.168.100.50 (Wed Dec 28 14:23:31 2011) 192.168.100.50 (Wed Dec 28 14:23:35 2011) 192.168.100.50 (Wed Dec 28 15:15:09 2011) 192.168.100.50 (Wed Dec 28 15:15:12 2011) 192.168.100.50 (Wed Dec 28 15:15:14 2011) 192.168.100.50 (Wed Dec 28 15:15:17 2011) 192.168.100.50 (Wed Dec 28 15:15:20 2011) 192.168.100.50 (Wed Dec 28 15:15:23 2011) 192.168.100.50 (Wed Dec 28 15:21:29 2011) 192.168.100.50 (Wed Dec 28 15:21:32 2011) 192.168.100.50 (Wed Dec 28 15:21:34 2011) 192.168.100.50 (Wed Dec 28 15:21:38 2011) 192.168.100.50 (Wed Dec 28 15:21:41 2011) 192.168.100.50 (Wed Dec 28 15:21:43 2011) 192.168.100.50 (Wed Dec 28 17:36:00 2011) 192.168.100.50 (Wed Dec 28 17:36:03 2011) 192.168.100.50 (Wed Dec 28 17:36:05 2011) 192.168.100.50 (Wed Dec 28 17:36:10 2011) 192.168.100.50 (Wed Dec 28 17:36:13 2011) 192.168.100.50 (Wed Dec 28 17:36:16 2011) [2] [3] [4] [5] [6] [7] [8] [9] [10]

Date template hits: 2120 hit(s): MONTH Day Hour:Minute:Second 0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second Year 0 hit(s): WEEKDAY MONTH Day Hour:Minute:Second 0 hit(s): Year/Month/Day Hour:Minute:Second 0 hit(s): Day/Month/Year Hour:Minute:Second 0 hit(s): Day/MONTH/Year:Hour:Minute:Second 0 hit(s): Month/Day/Year:Hour:Minute:Second 0 hit(s): Year-Month-Day Hour:Minute:Second 0 hit(s): Day-MONTH-Year Hour:Minute:Second[.Millisecond] 0 hit(s): Day-Month-Year Hour:Minute:Second 0 hit(s): TAI64N 0 hit(s): Epoch 0 hit(s): ISO 8601 0 hit(s): Hour:Minute:Second 0 hit(s): 

Success, the total number of match is 30

However, look at the above section 'Running tests' which could contain important information. }}