Protect CentOS from unwanted SSH failed login attempts with Fail2Ban

Protect CentOS from unwanted SSH failed login attempts with Fail2Ban

SSH is most likely the most secure way to remotely connect to a LINUX-based server machine. However, the fact that the SSH daemon service needs to be reached from the Internet and is usually configured to listen to a well-known TCP port has always been a major security flaw: it allows attackers to relentlessly spam it with a huge number login attempts, hoping to find a hole in your UAC setup.

To better understand what we're talking about, let's take a look at the following screenshot:

Protect CentOS from unwanted SSH failed login attempts with Fail2Ban

Those 150 failed login attempts have been attempted on one of our CentOS7 servers in a fifteen-minute range: we're easily talking about thousands of them every single day, which would eventually break any non-strong password, other than flooding our beloved port 22.

It would be a good thing if we could do something about this nasty problem, for example issuing some throttling rules that could force these login attempts to respect a time limit each time they issue a wrong password. Luckily enough, there's more than something we can do about that.

UPDATE: if you have the same problem with the Windows Server RDP service, read here to fix it.

Changing SSH port

The first thing you should do, if you can afford that, is to change the SSH port from the default (22) to a different one: here's a great guide explaining how to do it with CentOS (if you aren't running CentOS, look here instead).

However, doing this could be not enough to fend off less-than-trivial brute-force scenarios, not to mention the fact that you would need to have the required permissions to the server machine. If you don't, of if you want to take a different approach, here's another way to mitigate the issue.

Introducing Fail2ban

The service is called Fail2ban and features a great amount of useful and highly-configurable features that can help us to mitigate these brute-force attacks. In this post we'll briefly describe how we can setup and configure it by summarizing a great post taken from DigitalOcean: for additional info on the project itself, we strongly suggest to visit the Fail2ban official page.


The first thing we have to do is to add a reference to the EPEL project, since the Fail2ban package is not available (yet) in the official CentOS package repo. EPEL is an acronym for Extra Packages for Enterprise Linux and can be installed via YUM with the following line:

Answer y  when prompted for confirmation and the package will be installed.

Once done, you'll be able to install Fail2ban with the following command:

Again, answer y  to confirm and wait for the package installation to complete.

Once installed, issue the following command to enable the Fail2ban service upon system start:


The great thing about Fail2ban is that it comes with a default set of options that are already ok to cover all your basic needs. However, it can't hurt to tune them a little: to do that, you have several options:

  • Change the default settings by editing the   /etc/fail2ban/jail.conf  file directly.
  • Create the /etc/fail2ban/jail.local configuration file and use it to override the default settings you want to change.

The former option is easier, as the default configuration file feature a lot of useful comments about the various available settings. However, it could also be overwritten whenever you update the package or perform other operations, so we suggest to go with the latter.

Here's a good jail.local  file that you could use to fine-tune the most useful settings:

We decorated each relevant setting with a comment explaining what it does, so you should have no problems understaing what each one of them will do.

Cascading rules

It's worth noting that the jail.conf  file can also be overridden by any .conf file present in the /etc/fail2ban/jail.d/  folder: similarly, the jail.local  file we just added can also be overridden by any .local file present in that same folder. Here's the cascading order:

  1. /etc/fail2ban/jail.conf
  2. /etc/fail2ban/jail.d/*.conf (from first to last, sorted alphabetically)
  3. /etc/fail2ban/jail.local
  4. /etc/fail2ban/jail.d/*.local (from first to last, sorted alphabetically)

Regardless how you choose to configure it, be sure to restart the Fail2ban services after you change any of these files:


The following commands can be used to ensure that Fail2ban services is working properly and to check what it actually does.

This command gives some basic real-time info regarding the service status:

This command allows the admin to check the Fail2ban log file since the last startup:

This command can be used to list the number of available jails:

This command can be used to check the status of a specific jail (number of bans, banned IP list & more):

In the above example we're checking the sshd jail, but you can input any existing jail name available from the previous command.

Last but not least, this command will use tail to read the Fail2ban log file (press Ctrl-C to exit):

That's it for now. If you're curious about how Fail2ban works under the hood, we strongly suggest to take a look at this other awesome post on DigitalOcean that explains just that.


About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

One Comment on “Protect CentOS from unwanted SSH failed login attempts with Fail2Ban”

  1. Pingback: How to stop (or prevent) massive login attempts to Remote Desktop RDP on Windows Server

Leave a Reply

Your email address will not be published. Required fields are marked *

The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.