Tutorial

How To Protect SSH with fail2ban on CentOS 6

Published on June 15, 2012
How To Protect SSH with fail2ban on CentOS 6
Not using CentOS 6?Choose a different version or distribution.
CentOS 6

Status: Deprecated

This article covers a version of CentOS that is no longer supported. If you are currently operating a server running CentOS 6, we highly recommend upgrading or migrating to a supported version of CentOS.

Reason: CentOS 6 reached end of life (EOL) on November 30th, 2020 and no longer receives security patches or updates. For this reason, this guide is no longer maintained.

See Instead:
This guide might still be useful as a reference, but may not work on other CentOS releases. If available, we strongly recommend using a guide written for the version of CentOS you are using.

The following DigitalOcean tutorial may be of immediate interest, as it outlines how to protect an SSH service daemon with fail2ban on a CentOS 7 server:


About Fail2Ban

Servers do not exist in isolation, and those servers with only the most basic SSH configuration can be vulnerable to brute force attacks. fail2ban provides a way to automatically protect the server from malicious signs. The program works by scanning through log files and reacting to offending actions such as repeated failed login attempts.

Step One—Install Fail2Ban

Because fail2ban is not available from CentOS, we should start by downloading the EPEL repository:

rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

Follow up by installing fail2ban:

yum install fail2ban

Step Two—Copy the Configuration File

The default fail2ban configuration file is location at /etc/fail2ban/jail.conf. The configuration work should not be done in that file, however, and we should instead make a local copy of it.

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

After the file is copied, you can make all of your changes within the new jail.local file. Many of possible services that may need protection are in the file already. Each is located in its own section, configured and turned off.

Step Three—Configure defaults in Jail.Local

Open up the the new fail2ban configuration file:

vi /etc/fail2ban/jail.local

The first section of defaults covers the basic rules that fail2ban will follow. If you want to set up more nuanced protection for your virtual private server, you can customize the details in each section.

You can see the default section below.

[DEFAULT]

# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
# ban a host which matches an address in this list. Several addresses can be
# defined using space separator.
ignoreip = 127.0.0.1

# "bantime" is the number of seconds that a host is banned.
bantime  = 3600

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 600

# "maxretry" is the number of failures before a host get banned.
maxretry = 3

Write your personal IP address into the ignoreip line. You can separate each address with a space. IgnoreIP allows you white list certain IP addresses and make sure that they are not locked out from your VPS. Including your address will guarantee that you do not accidentally ban yourself from your own virtual private server.

The next step is to decide on a bantime, the number of seconds that a host would be blocked from the server if they are found to be in violation of any of the rules. This is especially useful in the case of bots, that once banned, will simply move on to the next target. The default is set for 10 minutes—you may raise this to an hour (or higher) if you like.

Maxretry is the amount of incorrect login attempts that a host may have before they get banned for the length of the ban time.

Findtime refers to the amount of time that a host has to log in. The default setting is 10 minutes; this means that if a host attempts, and fails, to log in more than the maxretry number of times in the designated 10 minutes, they will be banned.

Step Four (Optional)—Configure the ssh-iptables Section in Jail.Local

The SSH details section is just a little further down in the config, and it is already set up and turned on. Although you should not be required to make to make any changes within this section, you can find the details about each line below.

[ssh-iptables]

enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
           sendmail-whois[name=SSH, dest=root, sender=fail2ban@example.com]
logpath  = /var/log/secure
maxretry = 5

Enabled simply refers to the fact that SSH protection is on. You can turn it off with the word "false".

The filter, set by default to sshd, refers to the config file containing the rules that fail2banuses to find matches. The name is a shortened version of the file extension. For example, sshd refers to the /etc/fail2ban/filter.d/sshd.conf.

Action describes the steps that fail2ban will take to ban a matching IP address. Just like the filter entry, each action refers to a file within the action.d directory. The default ban action, "iptables" can be found at /etc/fail2ban/action.d/iptables.conf .

In the "iptables" details, you can customize fail2ban further. For example, if you are using a non-standard port, you can change the port number within the brackets to match, making the line look more like this:

 eg. iptables[name=SSH, port=30000, protocol=tcp]

You can change the protocol from TCP to UDP in this line as well, depending on which one you want fail2ban to monitor.

If you have a mail server set up on your virtual private server, Fail2Ban can email you when it bans an IP address. In the default case, the sendmail-whois refers to the actions located at /etc/fail2ban/action.d/sendmail-whois.conf.

log path refers to the log location that fail2ban will track.

The max retry line within the SSH section has the same definition as the default option. However, if you have enabled multiple services and want to have specific values for each one, you can set the new max retry amount for SSH here.

Step Five—Restart Fail2Ban

After making any changes to the fail2ban config, always be sure to restart Fail2Ban:

sudo service fail2ban restart

You can see the rules that fail2ban puts in effect within the IP table:

iptables -L
By Etel Sverdlov

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Etel Sverdlov
Etel Sverdlov
See author profile
Category:
Tutorial

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
31 Comments
Leave a comment...

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Hi, good article!

If you add third-party repo i recommend using a yum-plugin-priorities! This plugin is particularly useful for anyone who uses one or more third-party repositories, as these repositories may update system files, which can potentially compromise the stability of your CentOS installation. http://wiki.centos.org/PackageManagement/Yum/Priorities

In my opinion is a much better way (easy & safe). Specifically:

STEP 1: Install EPEL repo (eg. for CentOS x64) wget http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm yum install epel-release-6-8.noarch.rpm

STEP 2: Disable EPEL repo by default vi /etc/yum.repos.d/epel.repo change enabled=1 --> enabled=0

STEP 3: Anytime you want to include EPEL repo from command line: yum --enblerepo=epel <your_parameter_as_usual_here>

I hope it helps.

Manos

Please update the link on this post as it is broken.

Also is the a tutorial on how to use fail2ban with vsftp?

@Manos Please explain why you are disabling it and what are the security repercussions if not done

I am afraid that fail2ban is not interacting with my iptables:

$ yum install -y fail2ban $ cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local $ service fail2ban restart $ iptables -L

Chain INPUT (policy ACCEPT) target prot opt source destination

Chain FORWARD (policy ACCEPT) target prot opt source destination

Chain OUTPUT (policy ACCEPT) target prot opt source destination

In the file “jail.local” add “enabled=true” for each jail that you want to enable.

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
September 26, 2013

@victor0110: I believe fail2ban doesn’t modify/add iptables rules right away, it’ll have to process logs first and <em>if</em> anything matches, it’ll create rules and add them to iptables.

I have find an another like for epel repository for centos 64_x rpm -Uvh http://mirror.nus.edu.sg/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

Regards: imran http://aicheapwebhosting.com

One thing missing is to make sure fail2ban starts on server boot, using the following command:

sudo chkconfig fail2ban on

Matt

I got my server on 11/14/2013 rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm Retrieving http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm Preparing… ########################################### [100%] package epel-release-6-8.noarch is already installed

So I just went ahead with yum install fail2ban

hi i have problem in fail2ban i have installed and configure fail2ban configured successfully. iptables -L returns

Chain INPUT (policy ACCEPT) target prot opt source destination
fail2ban-SSH tcp – anywhere anywhere tcp dpt:ssh

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
RETURN all – anywhere anywhere

but it is not blocking my ssh remote access… :(

please help me in this.

regards Rao_Qasim

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
November 28, 2013

@qasim2490: Did you try logging in to your droplet (with invalid credentials)?

Hey Kamaln 7 I got the same problem as Qasim

iptables shows : Chain fail2ban-SSH (1 references) target prot opt source destination
RETURN all – anywhere anywhere

but it is also not blocking my ssh remote access… i tried many times, could you help me?

Is it possible to allow a port like 80,443 etc? So lets say the user is blocked on port 22 (SSH) because of too many failed login attempts could i still allow them to connect on 80 and 443 but block all other ports?

Thanks.

Correction and more details:

Is it possible to allow some ports like 80,443, etc but block all the others? So lets say the user is blocked because of too many failed login attempts on SSH could i still allow them to connect on 80 and 443 but block all other ports?

This is in case a genuine user gets blocked and they could still connect to the server via HTTP/HTTPS.

Thanks.

Thank you. Working without any hassle!

In several articles I saw : ulimit -s 256 - to limit memory usage… Where should I add it to?

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
April 10, 2014

@Igor: ulimit is a bash built-in, which means it will only be applied to process that are started from the bash session that you ran the ulimit command in. I’m not sure where you need to limit memory usage.

I make some mistakes in jail.local and now I want to recovery fail2ban but I didn’t write the command. Which one is the command ?

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
August 6, 2014

@petrelupu80: You can revert jail.local to the defaults by copying the default file to it:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

You can also remove the lines that are causing this issue in jail.local and then start fail2ban:

sudo service fail2ban restart

Whats the difference between these two ?

iptables -A INPUT -p tcp -s 111.111.111.111 -m tcp --dport 22 -j ACCEPT

and fail2ban ignoreip = 111.111.111.111

I find that if I specifically allow an IP thru IPTABLES then fail2ban has NO effect :-(

Kamal Nasser
DigitalOcean Employee
DigitalOcean Employee badge
August 10, 2014

@sanjaysubramanian: fail2ban works by blacklisting IP addresses using IPTables. IPTables processes rules in the same order they’re added in, so if you add an ACCEPT rule for 111.111.111.111, it’ll process it and ignore fail2ban’s rule.

Hi I have installed fail2ban, modified the config files for all ftp servers to true but when i try to start the server I get the following error messages. Help please

[root@mail ~]# sudo /etc/init.d/fail2ban start Starting fail2ban: WARNING ‘findtime’ not defined in ‘couriersmtp’. Using default one: 600 WARNING ‘usedns’ not defined in ‘couriersmtp’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘apache-noscript’. Using default one: 600 WARNING ‘usedns’ not defined in ‘apache-noscript’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘pam-generic’. Using default one: 600 WARNING ‘usedns’ not defined in ‘pam-generic’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘vsftpd’. Using default one: 600 WARNING ‘usedns’ not defined in ‘vsftpd’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘xinetd-fail’. Using default one: 600 WARNING ‘usedns’ not defined in ‘xinetd-fail’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘dovecot’. Using default one: 600 WARNING ‘usedns’ not defined in ‘dovecot’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘ssh-ddos’. Using default one: 600 WARNING ‘usedns’ not defined in ‘ssh-ddos’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘apache-multiport’. Using default one: 600 WARNING ‘usedns’ not defined in ‘apache-multiport’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘courierauth’. Using default one: 600 WARNING ‘usedns’ not defined in ‘courierauth’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘dropbear’. Using default one: 600 WARNING ‘usedns’ not defined in ‘dropbear’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘wuftpd’. Using default one: 600 WARNING ‘usedns’ not defined in ‘wuftpd’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘apache-overflows’. Using default one: 600 WARNING ‘usedns’ not defined in ‘apache-overflows’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘ssh’. Using default one: 600 WARNING ‘usedns’ not defined in ‘ssh’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘postfix’. Using default one: 600 WARNING ‘usedns’ not defined in ‘postfix’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘sasl’. Using default one: 600 WARNING ‘usedns’ not defined in ‘sasl’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘apache’. Using default one: 600 WARNING ‘usedns’ not defined in ‘apache’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘pure-ftpd’. Using default one: 600 WARNING ‘usedns’ not defined in ‘pure-ftpd’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘proftpd’. Using default one: 600 WARNING ‘usedns’ not defined in ‘proftpd’. Using default one: ‘warn’ WARNING ‘findtime’ not defined in ‘named-refused-tcp’. Using default one: 600 WARNING ‘usedns’ not defined in ‘named-refused-tcp’. Using default one: ‘warn’ ERROR No file(s) found for glob /var/log/vsftpd.log ERROR Failed during configuration: Have not found any log file for vsftpd jail [FAILED]

Worked perfectly! Thanks kamaln7 for supporting this board - now lets have some hackers for dinner. :)

Is there an updated guide for CentOS 7 ? Can i install Fail2Ban without install Postfix? I’ve to install it on my main Mail Server VPS :)

I agree - could we get an updated tut? Put Justin on the job - he writes great tuts.

Or you could do this:

You will need to install the EPEL repository by issuing the following command (as root or a root enabled account):

$ sudo yum install epel-release

The above should install EPEL and give you access to many new packages. One of those packages is fail2ban whcih you can install by running:

$ sudo yum install fail2ban

By default there are no jails configured, therefore to configure a basic sshd jail:

Create/edit the file /etc/fail2ban/jail.local and add:

[sshd] enabled = true

Start it with:

$ sudo systemctl start fail2ban

Make it start at boot time:

$ sudo systemctl enable fail2ban

There used to be a known bug where SELinux would block fail2ban from accessing the log files it needed to do its job. This seems to be fixed in the most recent version of CentOS 7; you shouldn’t need to make the changes below.

If you do have this issue, symptoms are nothing appearing in the logs and nothing appearing as failed or blocked in the output of fail2ban-client status sshd.

To check for SELinux error, read the journals with:

$ journalctl -lfu fail2ban

Watch them for messages such as:

SELinux is preventing /usr/bin/python2.7 from getattr access on the file . ***** Plugin catchall (100. confidence) suggests ************************** If you believe that python2.7 should be allowed getattr access on the file by default. Then you should report this as a bug. You can generate a local policy module to allow this access. Do allow this access for now by executing: # grep fail2ban-server /var/log/audit/audit.log | audit2allow -M mypol # semodule -i mypol.pp

If you see entries in the log journal run the below command:

$ grep fail2ban-server /var/log/audit/audit.log | audit2allow -M mypol semodule -i mypol.pp

Then, to be safe, restart fail2ban:

$ sudo systemctl restart fail2ban

also issue the below command just to be safe:

$ sudo systemctl restart rsyslog

You may have to repeat the process above until no more error messages appear in the journal.

If your server is on the internet then monitor fail2ban-client status sshd.

$ sudo fail2ban-client status sshd

It will soon start to show failed and banned counts if you’ve caught all the SELinux issues. Please note that you will need to keep an eye on your SELinux policy updates. If a selinux-policy package update appears, it may overwrite the above and you may need to run the above commands again. You’ll know this since fail2ban will stop working again - so be a good sysadmin and keep an eye on your droplet.

Peace

Great article if you are running centos 6. Not so great if you are running centos7. If you are running centos 7 my recommendation is to change the backend to systemd in jail.local, seemed to get my system working finally after days of banging my head against a wall. I would love to see an updated article

Thanks. I created a config to ban brute force attacks against Wordpress:

# Ban bots that try to attack Wordpress xmlrpc.php
[apache-wordpress]
enabled  = true
filter   = apache-wp
action   = iptables-multiport[name=apache-wordpress,port="80,443"]
logpath  = /var/log/httpd/access_log

filter.d/apache-wp.conf:

# Fail2Ban configuration file for blocking Wordpress XMLRPC brute force attacks.
#
# Example of web requests in Apache access log:
# 185.62.188.91 - - [16/May/2015:14:53:36 -0400] "POST /xmlrpc.php HTTP/1.0" 200 370 "-" "Mozilla/5.0 (compatible; Googlebot/2.1;  http://www.google.com/bot.html)"

[Definition]

failregex = ^<HOST> -.*"POST /xmlrpc.php HTTP.*".*$
#failregex = ^<HOST> -.*"(GET|POST).*\?.*\=http\:\/\/.* HTTP\/.*$

ignoreregex =

# DEV Notes:
# Author: Chloe

Thanks for guiding properly.

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.