Fail2ban

From Gentoo Wiki
Jump to:navigation Jump to:search

Fail2ban is a system denying hosts causing multiple authentication errors access to a service.

The 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.

Features

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 (maxretry) of attempts is detected within a particular time window (findtime) then a blocking rule (such as through iptables) is automatically set for a given time period (bantime).

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

FILE /etc/fail2ban/jail.confExample code for SSH jail
[DEFAULT]
ignoreip = 127.0.0.1
ignoreip = 192.168.100.24 # Management network
bantime = 86400 # 1 day (in seconds)
findtime = 300 # 5 minutes (in seconds)
maxretry = 3 # default repeat count

# Jail entry for SSH, using iptables for firewall
[ssh-iptables]
enabled = true  # Note that it is by default disabled
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/auth.log
maxretry = 5 # Override the default of 3

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 jail.d/*.conf syntax, so moving sshd.conf to sshd.conf.backup will disable the jail.

FILE /etc/fail2ban/jail.d/sshd.confsyslog-ng & ufw example
[ssh-iptables]
enabled  = true
filter = sshd
action = ufw[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/messages
maxretry = 5 # Override the default of 3

Filter expressions

Inside /etc/fail2ban/filter.d 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 /etc/fail2ban/action.d 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, nftables, tcpwrappers, shorewall and more.

Log scanning

The fail2ban service supports both file polling or more efficient file modification notifications; when dev-python/pyinotify or app-admin/gamin is installed and the user did not change the backend directive, then pyinotify or gamin will be used, otherwise polling is done. This can of course be configured in /etc/fail2ban/jail.conf.

Using fail2ban

Installation

Installing net-analyzer/fail2ban is as simple as:

root #emerge --ask net-analyzer/fail2ban

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).

To use the sqlite backend, enable the sqlite use flag for dev-lang/python.

Configuration

To configure fail2ban, go to /etc/fail2ban.

Start with jail.conf as that contains which rules to use (and which services to control) and only override the appropriate settings and enable the rules in jail.d/*.conf. If necessary, create new filters or actions if the included configuration does not satisfy requirements.

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

FILE /etc/fail2ban/jail.d/sshd.confrsyslog
[sshd]
enabled  = true

Or for syslog-ng users:

FILE /etc/fail2ban/jail.d/sshd.confsyslog-ng
[sshd]
enabled  = true
logpath = /var/log/messages


When finished, start the fail2ban service and to add it to the default runlevel.

root #rc-service fail2ban start
root #rc-update add fail2ban default

Interacting

As part of the fail2ban service, there is also a fail2ban-client available that can query the fail2ban service.

For instance, to see the running jails:

root #fail2ban-client status
Status
|- Number of jail:    1
`- Jail list:         sshd

To obtain specific information about each jail, such as the list of currently banned addresses, executed filters, etc:

root #fail2ban-client status sshd
Status for the jail: sshd
|- filter
|  |- File list:	/var/log/auth.log 
|  |- Currently failed:	1
|  `- Total failed:	12
`- action
   |- Currently banned:	1
   |  `- IP list:	192.168.100.50 
   `- Total banned:	2

To get a compact version for all jails, including banned IPs:

root #fail2ban-client banned
[{'sshd': ['192.168.100.50']}, {'apache-auth': []}]

Troubleshooting

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

root #fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Running tests
=============

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


Results
=======

Failregex
|- Regular expressions:
|  [1] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*(?:error: PAM: )?Authentication failure for .* from <HOST>\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 <HOST>\s*$
|  [3] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*Failed (?:password|publickey) for .* from <HOST>(?: port \d*)?(?: ssh\d*)?$
|  [4] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*ROOT LOGIN REFUSED.* FROM <HOST>\s*$
|  [5] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*[iI](?:llegal|nvalid) user .* from <HOST>\s*$
|  [6] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*User \S+ from <HOST> 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=<HOST>(?:\s+user=.*)?\s*$
|  [8] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*refused connect from \S+ \(<HOST>\)\s*$
|  [9] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*reverse mapping checking getaddrinfo for .* \[<HOST>\] .* POSSIBLE BREAK-IN ATTEMPT\!\s*
|  [10] ^\s*(?:\S+ )?(?:@vserver_\S+ )?(?:(?:\[\d+\])?:\s+[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?|[\[\(]?sshd(?:\(\S+\))?[\]\)]?:?(?:\[\d+\])?:)?\s*User \S+ from <HOST> not allowed because none of user's groups are listed in AllowGroups$
|
`- 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)

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

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): <Month/Day/Year@Hour:Minute:Second>

Success, the total number of match is 30

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