How to protect ssh server from brute force attacks using fail2ban

One common attack on ssh service is brute force attacks where a remote attacker indefinitely attempts to log in with different passwords. Fail2ban is an open-source intrusion prevention framework on Linux that monitors various system log files (e.g., /var/log/auth.log) and triggers various defensive actions upon detecting any suspicious activities. You can use fail2ban to defend against brute force password guessing attacks on ssh server.

In this guide, I will demonstrate how to install and configure fail2ban to protect ssh server against brute force attacks from a remote IP address.

Install Fail2ban on Linux

To install fail2ban on CentOS or RHEL, first set up EPEL repository, and then run the following command.

$ sudo yum install fail2ban

To install fail2ban on Fedora, simply run:

$ sudo yum install fail2ban

To install fail2ban on Ubuntu, Debian or Linux Mint:

$ sudo apt-get install fail2ban

Configure Fail2ban on Linux

Now you are ready to configure fail2ban to harden your ssh server. You need to create the following configuration file. The configuration file contains "DEFAULT" section where you define default parameters for all monitored services, and service-specific sections where you define any service-specific (in this case ssh-related) parameters or overwrite default parameters.

$ sudo vi /etc/fail2ban/jail.local
# a space delimited list of IP addresses, CIDR prefixes, or DNS hostnames
# to bypass fail2ban protection
ignoreip =

# number of seconds during which a client host is blocked
bantime = 86400

# number of failures before a client host is blocked
maxretry = 5

# number of seconds within which "maxentry" failures result in banning
findtime = 600

mta = sendmail

enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
logpath = /var/log/auth.log
# ssh-specific max-retry threshold
maxretry = 5

According to the above configuration, fail2ban will automatically ban any remote IP address from which there have been at least 5 failed login attempts within the last 10 minutes. Once banned, the offending IP address will remain blocked for 24 hours. Such an event will be notified by sendemail to a recipient email address.

Once the configuration file is ready, start fail2ban service as follows.

$ sudo service fail2ban start

To verify fail2ban is running successfully, run fail2ban-client command with "ping" argument. If fail2ban service is running okay, you should see "pong" as a response.

$ sudo fail2ban-client ping
Server replied: pong

Fail2ban Demonstration

A log file called /var/log/messages demonstrates fail2ban in action.

$ sudo tail /var/log/messages
Feb 23 01:13:55 my-host fail2ban.server : INFO   Changed logging
target to SYSLOG for Fail2ban v0.8.8
Feb 23 01:13:55 my-host fail2ban.jail   : INFO   Creating new jail
Feb 23 01:13:55 my-host fail2ban.jail   : INFO   Jail
'ssh-iptables' uses pyinotify
Feb 23 01:13:55 my-host fail2ban.jail   : INFO   Initiated
'pyinotify' backend
Feb 23 01:13:55 my-host fail2ban.filter : INFO   Added logfile =
Feb 23 01:13:55 my-host fail2ban.filter : INFO   Set maxRetry = 5
Feb 23 01:13:55 my-host fail2ban.filter : INFO   Set findtime = 600
Feb 23 01:13:55 my-host fail2ban.actions: INFO   Set banTime = 86400
Feb 23 01:13:56 my-host fail2ban.jail   : INFO   Jail 'ssh-iptables' started
Feb 23 01:14:27 my-host fail2ban.actions: WARNING [ssh-iptables]

According to the log file above, fail2ban has banned an IP address, upon detecting multiple failed ssh login attempts from the IP address. You can verify the ban by checking current iptables rules.

$ sudo iptables --list -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
fail2ban-SSH  tcp  --             tcp dpt:22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain fail2ban-SSH (1 references)
target     prot opt source               destination
DROP       all  --
RETURN     all  --  

If you want to unblock the IP address from fail2ban, run the following command.

$ sudo iptables -D fail2ban-SSH -s -j DROP

Note that fail2ban itself is stateless. So if you restart fail2ban, all blocked IP addresses will be unblocked.

While fail2ban can mitigate brute-force password guessing attacks, it cannot protect ssh servers against sophisticated distributed brute-force campaigns, where an attacker bypasses fail2ban by using many thousands of bot-controlled IP addresses.

Subscribe to Xmodulo

Do you want to receive Linux FAQs, detailed tutorials and tips published at Xmodulo? Enter your email address below, and we will deliver our Linux posts straight to your email box, for free. Delivery powered by Google Feedburner.

The following two tabs change content below.
Dan Nanni is the founder and also a regular contributor of He is a Linux/FOSS enthusiast who loves to get his hands dirty with his Linux box. He likes to procrastinate when he is supposed to be busy and productive. When he is otherwise free, he likes to watch movies and shop for the coolest gadgets.
Your name can also be listed here. Write for us as a freelancer.

13 thoughts on “How to protect ssh server from brute force attacks using fail2ban

  1. I ran multiple hosts, one a honeypot to detect and initiate blocking at my router. This looks less satisfying, but far easier.

  2. I always install Fail2ban DIRECTLY when I receive a hosted server...

    But, what is the difference between
    - bantime
    - findtime ?

    I always use only bantime.

  3. I tweaked my firewall - max x attempts in 60 issues since. Keys instead of passwords of course. :)

  4. I have been using fail2ban for years. You should install it on any computer that has an SSH port exposed to the internet. You can generally just set it up and forget about it.

  5. fail2ban and denyhosts log AND BLOCK IP addresses that failed to login, even on other servers using them (worldwide database updates).

Leave a comment

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

Current ye@r *