How to Protect Your Server with Fail2ban on CentOS 8
Fail2ban is a free, open-source and most widely used IPS (Intrusion Prevention System) application that can be used to protect your server against brute force password login attacks. Fail2ban continuosly scans SSH and Apache log files (/var/log/secure, /var/log/httpd/) for malicious IP addresses with many failed password attemts and block them immidiately. It is written in the Python and able to runs on POSIX systems where iptables or TCP Wrapper installed locally.
In this tutorial, we will show you how to install Fail2ban on CentOS 8 server. We will also demonstrate how to configure Fail2ban to secure SSH and Apache server.
Requirements
- A server running CentOS 8.
- A root password is configured.
Install Fail2ban
By default, Fail2ban is not available in the CentOS 8 default repository. So you will need to install the EPEL repository in your system.
You can install the EPEL repository with the following command:
dnf install epel-release -y
Once installed, you can install the Fail2ban using the following command:
dnf install fail2ban -y
Once the installation is completed, start the Fail2ban service and enable it to start after system reboot:
systemctl start fail2ban
systemctl enable fail2ban
You can check the status of Fail2ban with the following command:
systemctl status fail2ban
You should get the following output:
fail2ban.service - Fail2Ban Service
Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-01-18 04:44:31 EST; 38s ago
Docs: man:fail2ban(1)
Process: 1381 ExecStartPre=/bin/mkdir -p /var/run/fail2ban (code=exited, status=0/SUCCESS)
Main PID: 1382 (fail2ban-server)
Tasks: 1 (limit: 6102)
Memory: 10.3M
CGroup: /system.slice/fail2ban.service
└─1382 /usr/bin/python3.6 -s /usr/bin/fail2ban-server -xf start
Jan 18 04:44:31 centos8 systemd[1]: Starting Fail2Ban Service...
Jan 18 04:44:31 centos8 systemd[1]: Started Fail2Ban Service.
Jan 18 04:44:31 centos8 fail2ban-server[1382]: Server ready
At this point, Fail2ban is installed and running.
Secure SSH with Fail2ban
The Fail2ban global configuration file is located at /etc/fail2ban/jail.conf. It is a good idea to make the modifications in a separate file jail.local which will override the jail.conf file.
You can create a separate jail.local file for SSH with the following command:
nano /etc/fail2ban/jail.local
Add the following lines:
[DEFAULT]
ignoreip = Your-server-ip
bantime = 300
findtime = 300
maxretry = 3
banaction = iptables-multiport
backend = systemd
[sshd]
enabled = true
Save and close the file when you are finished.
Here’s a brief explanation of each parameter:
- Ignoreip : Whitelist IP addresses that fail2ban does not ban.
- Bantime : Specify the time in second to ban a host.
- Findtime : Specify the time in seconds in which we’re counting “retries”.
- Maxretry : Specify the number of failures before a host gets banned.
- Banaction : Specify the action that will be used when the threshold is reached.
- Backend : This entry specifies how fail2ban will monitor log files.
- Enabled : Used to enable or disable the Fail2ban.
Now, restart the Fail2ban service to implement the changes:
systemctl restart fail2ban
Next, check whether the SSH jail is enabled or not with the following command:
fail2ban-client status
You should get the following output:
Status
|- Number of jail: 1
`- Jail list: sshd
Test SSH Against Failed Login Attempts
At this point, your SSH server is secured with Fail2ban. Now, it's time to test it against failed password login attempts.
Login to the remote system, open your command-line terminal and try to ssh to the server IP address:
ssh 104.245.36.109
You will be prompt to enter the root password. Type the wrong password repeatedly. Once you reached the failed login maxretry threshold limit. Your IP address will be blocked for 300 seconds.
You can now check your SSH banning status with the following command:
fail2ban-client status sshd
You should see your banned IP in the following output:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 3
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: 27.61.154.16
You can also track the SSH failed login entries using the log file as shown below:
tails -10 /var/log/secure | grep 'Failed password'
You should get the following output:
Jan 18 05:23:28 centos8 login[651]: ROOT LOGIN ON tty1
Jan 18 05:24:38 centos8 sshd[1792]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=27.61.154.16 user=root
Jan 18 05:24:38 centos8 sshd[1792]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Jan 18 05:24:40 centos8 sshd[1792]: Failed password for root from 27.61.154.16 port 2164 ssh2
Jan 18 05:24:42 centos8 sshd[1792]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Jan 18 05:24:44 centos8 sshd[1792]: Failed password for root from 27.61.154.16 port 2164 ssh2
Jan 18 05:24:47 centos8 sshd[1792]: pam_succeed_if(sshd:auth): requirement "uid >= 1000" not met by user "root"
Jan 18 05:24:49 centos8 sshd[1792]: Failed password for root from 27.61.154.16 port 2164 ssh2
Jan 18 05:24:50 centos8 sshd[1792]: Connection closed by authenticating user root 27.61.154.16 port 2164 [preauth]
Jan 18 05:24:50 centos8 sshd[1792]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=27.61.154.16 user=root
Secure Apache with Fail2ban
You can also secure your Apache webserver from different kinds of attacks including, apache-auth, apache-badbots, apache-noscript and apache-overflows.
You can achieve this by editing /etc/fail2ban/jail.local file:
nano /etc/fail2ban/jail.local
Add the following lines:
[apache-auth]
enabled = true
port = http,https
logpath = %(apache_error_log)s
[apache-badbots]
enabled = true
port = http,https
logpath = %(apache_access_log)s
bantime = 48h
maxretry = 1
[apache-noscript]
enabled = true
port = http,https
logpath = %(apache_error_log)s
[apache-overflows]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 2
Save and close the file when you are finished. Then, restart the Fail2ban service to activate the Apache jail.
systemctl restart fail2ban
You can now check the status of all active jail with the following command:
fail2ban-client status
You should get the following output:
Status
|- Number of jail: 5
`- Jail list: apache-auth, apache-badbots, apache-noscript, apache-overflows, sshd
At this point, your Apache web server is protected from several attacks with Fail2ban.
Ban and Unban IP Manually
You can also ban and unban a specific IP address for specific jail manually with Fail2ban.
For example, to ban the IP 192.168.0.101 for sshd jail run the following command:
fail2ban-client set sshd banip 192.168.0.101
To unban the IP 192.168.0.200 for apache-auth jail run the following command:
fail2ban-client set apache-auth unbanip 192.168.0.200
Conclusion
In the above tutorial, we learned how to protect your SSH and Apache webserver from different kinds of attacks with Fail2ban. I hope you have now enough knowledge to protect other services like, FTP, Webmail, MySQL and many more using Fail2ban.