Fail2ban (Admin Guide)
Fail2ban: Stop Brute-Force Attacks on Exposed Services
Fail2ban monitors log files of various services to block individual IPs after too many failed login attempts.
It is transparent to the user, as long as the correct credentials are used to log in. With wrong credentials and multiple login attempts, the users IP will be blocked for a certain time. This time period may increase every time when this IP is blocked.
An administrator has to configure Fail2ban for every exposed service. After initial configuration, the service works autonomously. The Fail2ban service can be used to (un-)ban IPs manually.
How Fail2ban works:
- Parse log files for password/login failure reports
- Define Jails:
- A Jail consists of Filters and Actions
- Can be created for every network-facing process
- Check
man jail.conf
for more details
- Filters:
- Python regex in
/etc/fail2ban/filter.d
- Defines how to detect authentication failures
- Python regex in
- Action:
- Usually (un-)banning via
/etc/hosts.deny
, firewallcmd, iptables, pfsense etc. - Can execute arbitrary code (everything python scriptable)
- Stored in
/etc/fail2ban/action.d
- Usually (un-)banning via
- Defaults for apache, sshd, lighttpd, vsftpd, qmail, postfix, courier, …
- General config in
/etc/fail2ban/fail2ban.conf
- Contains typical ban times
- Fail2ban logging level & target
- Check
man fail2ban
for more details
- Recommendations:
- keep
*.conf
files unchanged and add custom modifications in*.local
files (parsed after .conf files), e.g.:fail2ban.d/01_custom_log.conf
jail.d/01_enable.conf
jail.d/02_custom_port.conf
- keep
Challenges / Problems
Be aware of what Fail2ban doesn’t protect against:
- Distributed denial of service attacks
- IPs are only banned after multiple failed attempts per IP
- Cannot eliminate risk of weak authentication
- Unchanged default passwords and easy to guess phrases are still more likely to be breached
- Local users with write access to logs can block IPs
- Grant access accordingly
Installation
Just go through your package manager. For example on CentOS7: yum install fail2ban
Example
Let's activate the sshd jail that ships with Fail2ban:
# service fail2ban start
Starting fail2ban: [ OK ]
# fail2ban-client status
Status
|- Number of jail: 0
`- Jail list:
# vim /etc/fail2ban/jail.conf
Enable the sshd jail:
[sshd] enabled = true port = ssh logpath = %(sshd_log)s backend = %(sshd_backend)s
sshd_log
(here /var/log/auth.log
) and sshd_backend
(here auto
) are defined in /etc/fail2ban/paths-common.conf
. The backend (pyinotify, gamin, polling, systemd or auto) specifies the way in which Fail2ban retrieves modification of log files.
After this change, we have to reload the Fail2ban service:
# fail2ban-client reload
# fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
There are a couple of things here that could look different for your distribution (log paths, service handling etc.), but the general approach is similar.
Unban IPs
Looking up what IPs are currently blocked depends on your backend. With iptables you could run iptables -L -n
and fail2ban-client status
to match ban rules to a jail name.
Next, run
fail2ban-client set <JAILNAME> unbanip www.xxx.yyy.zzz
to unban the IP in said jail.
Tips
Restrict connection only to local network
As always: only expose ports that are meant to be accessed through the network.
You even may want to differentiate between access from within your local network and outside of it (assuming IPs like 123.123.XXX.YYY
are local):
# cat /etc/hosts.allow sshd: 123.123.0.0/255.255.0.0 portmap: 123.123.123.0/255.255.254.0 rpcbind: 123.123.123.0/255.255.254.0 # cat /etc/hosts.deny sshd: ALL portmap: ALL rpcbind: ALL
Block lists
You could use a block list, (e.g. blocklist.de) to block malicious IPs.
ISPs might give the same IP to multiple users at the same time, so using blocklists might lead to false positives.