Fail2ban

In this article you will learn how to install and configure fail2ban, a security tool that can help protecting your slice from brute force attacks.


Introduction

Securing your slice is very important. Each slice comes with an ssh server installed by default. Since most Linux servers run the ssh service, it is not surprising that attackers try to hack ssh servers more than others.

In our slice we not only have an ssh server but we might have a web server, a mail server and an ftp server as well. Analysing all of the logs can be difficult and time consuming.

However, fail2ban makes system administrators' lives a lot easier. Fail2ban scans log files like /var/log/pwdfail or /var/log/apache/error_log and bans IP addresses that make too many failed password guesses. It updates the firewall rules to reject or drop traffic from the attacking IP addresses.

Why fail2ban

There are some other software packages that also analyze log files and ban offensive machines. However, fail2ban has the following features which make it more appealing:

  • client/server
  • multithreaded
  • autodetection of the date/time format
  • wildcard support in logpath option
  • support for a lot of services (sshd, apache, qmail, proftpd, sasl, etc)
  • support for several actions (iptables, tcp-wrapper, shorewall, mail notifications, etc)

    Installation

    I am using Ubuntu 8.10, however the installation steps will be similar for other Linux distros.

    This command will install fail2ban under Ubuntu:

     sudo apt-get install fail2ban 

    Now we need to modify its configuration files. They are under the /etc/fail2ban.

    Let's check jail.conf. You will see the developer's warning about not modifying this file and rather putting our changes in /etc/fail2ban/jail.local.

    So let's copy the /etc/fail2ban/jail.conf to the /etc/fail2ban/jail.local and open the jail.local with your favorite text editor

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

    Configuration

    If you look at the jail.local you will see lots of options. Here are their explanations:

    enabled

    Defines if a given section is enabled or not. Possible values are 'true' or 'false'.

    filter

    Name of the filter to be used by the jail to detect matches.

    This name corresponds to a file name in '/etc/fail2ban/filter.d'; without the '.conf' extension. For example: 'filter = sshd' refers to '/etc/fail2ban/filter.d/sshd.conf'.

    action

    This option tells fail2ban which action to take once a filter matches.

    logpath

    Path to the log file which is provided to the filter

    ignoreip

    If you set this option to some IPs then those IPs won't be banned no matter how many times a user fails to login from them

    maxretry

    Number of matches to trigger a ban action on an IP. For example, if this value were set to 6 for ssh, after 6 unsuccessful attempts, fail2ban would block the offensive machine's IP.

    bantime

    Duration (in seconds) for an IP to be banned for.

    destmail

    Use this option to set the email of the person who should receive alerts when an IP is banned

    banaction

    Use this option to instruct with action will be taken in order to ban an offending IP.

    This name corresponds to a file name in '/etc/fail2ban/action.d'; without the '.conf' extension. For example: 'action = iptables-allports' refers to '/etc/fail2ban/action.d/iptables-allports.conf'.

    Protocol

    Sets the default protocol to ban, TCP or UDP

    In the following example, we want fail2ban to ban offensive machines' IPs and send an e-mail with whois report and relevant log lines to our email address (demo@example.com).

    We also would like to ban that IP for 5 minutes. (If you don't have a mail server on your slice, fail2ban cannot send emails, you can check here to set up a postfix mail server). We need to make the following changes to be able to have this feature with fail2ban:

    [DEFAULT]
    
    bantime  = 600
    destemail = demo@example.com
    action = %(action_mwl)s
    
    
    [ssh]
    
    enabled = true
    port    = ssh
    filter  = sshd
    logpath  = /var/log/auth.log
    maxretry = 5
    
    
    We now need to restart fail2ban service.
     sudo /etc/init.d/fail2ban restart 
    By default, only the ssh section is enabled in jail.conf. This means fail2ban only analyzes /var/log/auth.log and bans offensive IPs. If you have a web, mail, dns or ftp server, you can set the enabled value to true and activate fail2ban filter for those services.

    Testing

    Let's test our fail2ban. We have two machines: one of them is the offensive machine and other one is our slice.

    Offensive machine's IP: 123.45.67.89

    The Slice's IP: 98.76.54.32
    e-mail address: demo@example.com

    I did 5 unsuccessful login attempts from the offensive machine.

    First we check our e-mail to see if we get an e-mail from fail2ban

    
    From fail2ban@ITSecurity  Thu Jul 16 04:59:24 2009
    Subject: [Fail2Ban] ssh: banned 123.45.67.89
    Hi,
    
    The ip 123.45.67.89 has just been banned by Fail2Ban after
    5 attempts against ssh.
    
    
    Here are more information about 123.45.67.89:
    
    {whois info}
    
    Lines containing IP:123.45.67.89 in /var/log/auth.log
    
    
    Jul 16 04:59:16 example.com sshd[10390]: Failed password for root from 123.45.67.89 port 46023 ssh2
    Jul 16 04:59:18 example.com sshd[10390]: Failed password for root from 123.45.67.89 port 46023 ssh2
    Jul 16 04:59:20 example.com sshd[10390]: Failed password for root from 123.45.67.89 port 46023 ssh2
    Jul 16 04:59:21 example.comsshd[10394]: reverse mapping checking getaddrinfo for 123.45.67.89.example.com [123.45.67.89] failed - POSSIBLE BREAK-IN ATTEMPT!
    Jul 16 04:59:22 example.com sshd[10394]: Failed password for root from 123.45.67.89 port 46024 ssh2
    Regards,
    
    Fail2Ban
    

    Nice!

    Let's look at the new iptables

    iptables -L 
    
    Chain fail2ban-ssh (1 references)
    target     prot opt source               destination
    DROP       all  --  208-78-96-200.realinfosec.com  anywhere
    
    

    Fail2ban works perfectly!

    Summary

    Fail2ban is one of the best tools for securing our slice. In this article, we learned how to install and configure fail2ban for our needs. It can block attacks by banning offensive machines' IPs and email their whois information along with relevant log files. In other words, you can contact an attacker's ISP and file a complaint about them which will decrease the chance of future attacks from the same IP.

    Ismail
  • Article Comments:

    Yang commented Thu Sep 03 01:42:25 UTC 2009:

    How does fail2ban compare to denyhosts? I'm pretty new to this. Currently my server is installed with denyhosts and I can see it's automatically started at server boot. Do I need to switch to fail2ban? Apparently you are recommending it but I find other folks like denyhosts more.

    Completely clueless...

    Ismail commented Wed Sep 09 22:32:45 UTC 2009:

    Hey Yang,

    Fail2ban is similar to DenyHosts ... but unlike DenyHosts which focuses on SSH, fail2ban can be configured to monitor any service that writes login attempts to a log file, and instead of using /etc/hosts.deny only to block IP addresses/hosts, fail2ban can use Netfilter/iptables and TCP Wrappers /etc/hosts.deny.

    Vic commented Fri Dec 25 08:40:59 UTC 2009:

    I followed the instructions verbatim, yet when I restart the service, I get the following error messages:

    $ sudo /etc/init.d/fail2ban restart

    • Restarting authentication failure monitor fail2ban Traceback (most recent call last): File "/usr/bin/fail2ban-client", line 401, in <module> if client.start(sys.argv): File "/usr/bin/fail2ban-client", line 370, in start return self.__processCommand(args) File "/usr/bin/fail2ban-client", line 180, in __processCommand ret = self.__readConfig() File "/usr/bin/fail2ban-client", line 375, in __readConfig ret = self.__configurator.getOptions() File "/usr/share/fail2ban/client/configurator.py", line 65, in getOptions return self.__jails.getOptions(jail) File "/usr/share/fail2ban/client/jailsreader.py", line 64, in getOptions ret = jail.getOptions() File "/usr/share/fail2ban/client/jailreader.py", line 70, in getOptions self.opts = ConfigReader.getOptions(self, self.name, opts) File "/usr/share/fail2ban/client/configreader.py", line 84, in getOptions v = self.get(sec, option[1]) File "/usr/lib/python2.5/ConfigParser.py", line 525, in get return self._interpolate(section, option, value, d) File "/usr/lib/python2.5/ConfigParser.py", line 593, in _interpolate self.interpolatesome(option, L, rawval, section, vars, 1) File "/usr/lib/python2.5/ConfigParser.py", line 625, in interpolatesome option, section, rest, var) ConfigParser.InterpolationMissingOptionError: Bad value substitution: section: [apache-noscript] option : action key : action_mw1 rawval :

                                                                                     [fail]
      

    I am supposed to delete other sections of the config file?

    Brad commented Wed Jan 13 18:23:59 UTC 2010:

    How can I be sure that installation of fail2ban is working properly with existing iptabes and shorewall setup rules?

    nicolas block commented Mon Jan 18 22:51:08 UTC 2010:

    regarding Vic's comment above, i noticed the same thing. i was being lazy and i just copy/pasted the config into my local config file. maybe:

    [DEFAULT]
    
    bantime  = 600
    destemail = demo@example.com
    action = %(action_mw1)s
    

    ...should be...

    [DEFAULT]
    
    bantime  = 600
    destemail = demo@example.com
    action = %(action_mwl)s
    

    ... where the letter L replaces the number 1 in action_mw1

    Ismail commented Tue Jan 19 15:50:10 UTC 2010:

    Nicolas, You are right. I updated the article.

    Brad, you can test it. Just try to login your slice and enter wrong password intentionally. After you have 5 unsuccessful attempt (assuming you set maxretry to 5), check the iptables with iptables -L command. You should see your IP is listed in there.

    Jon Stephens commented Wed Mar 03 08:12:51 UTC 2010:

    I have CentOS and if you want to install it yum doesn't seem to find it. But DAG has it. Requires gamin-python.x86_64. Then you can go here to get the package: http://dag.wieers.com/rpm/packages/fail2ban/

    Jon Stephens commented Tue Mar 16 06:20:49 UTC 2010:

    After actually getting it to work for just ssh I should mention that you have to make two changes aside from enabling ssh-iptables in /etc/fail2ban/jail.conf. I also had to install jwhois (for the more ip info to work) and edit the logpath to /var/log/secure since that's the correct CentOS path for ssh errors.

    Ulf commented Wed Aug 25 15:36:21 UTC 2010:

    Thanks for the once again great writeup!

    Just FYI (if like me you don't feel like completing the lengthy task of configuring Sendmail or Postfix):

    Fail2ban works great with ssmtp, which you can easily set up to relay messages to say Gmail. Then configure your jail.local like so:

    [DEFAULT]

    [...]

    mta = ssmtp

    [...]

    Just replace %(mta) with "sendmail"

    action_mw = %(banaction)s[name=%(name)s, port="%(port)s", protocol="%(protocol)s] sendmail-whois[name=%(name)s, dest="%(destemail)s", protocol="%(protocol)s]

    action_mwl = %(banaction)s[name=%(name)s, port="%(port)s", protocol="%(protocol)s] sendmail-whois-lines[name=%(name)s, dest="%(destemail)s", sender=alert@ulfmoehring.net, logpath=%(logpath)s]

    Jered commented Mon Aug 30 17:27:40 UTC 2010:

    Poking around Ubuntu Hardy 8.04 using updated apache2 and fail2ban packages, I noticed that while the error logging changed a bit for apache2 and PHP5 for that distro, fail2ban's apache-noscript.conf file was not updated to reflect the change.

    If you run into a similar situation (e.g. you visit a bunch of non-existent PHP files on your site but fail2ban doesn't ban you), add an extra line to the apache-noscript filter, as in:

     failregex = [[]client <HOST>[]] (File does not exist|script not found or unable to stat): .*(.php|.asp|.exe|.pl)
            [[]client <HOST>[]] script '/\S*(.php|.asp|.exe|.pl)\S*' not found or unable to stat *$
    

    Adding the second line, taken from a later version of fail2ban, does the trick.

    sdebaun commented Tue Sep 21 08:15:47 UTC 2010:

    Hi- action = %(action_mwl)s did not work for me under [default]... (as shown in the example) but worked perfect under [ssh] and others

    example:

    [apache-badbots] enabled = true port = http,https filter = apache-badbots action = %(action_mwl)s logpath = /var/log/apache/access.log maxretry = 2

    candidatefoo commented Mon Mar 28 14:26:50 UTC 2011:

    Worth pointing out that the default configuration for ssh will not work if you've changed the port ssh runs on (as per other slicehost articles). There's a "port" configuration option that could possibly be included in this article.. Just change that to the port number you're using for ssh, and restart fail2ban.

    Rico Leuthold commented Mon Jul 25 12:22:14 UTC 2011:

    I'm running into issues when using fail2ban with svn (svn+ssh). I'm getting banned when I try to checkout a project. If I stop fail2ban, svn+ssh works fine. Any clue? Thank you very much - rico

    Jered commented Mon Jul 25 21:05:25 UTC 2011:

    That's odd, Rico. It should normally only kick in the ban when there's a failed ssh login attempt, and shouldn't care about successful ones. Have you changed any other part of the fail2ban config? Maybe one filter is overlapping the ssh filter and kicking in when you connect.

    Rico Leuthold commented Tue Jul 26 12:42:19 UTC 2011:

    Hi Jered, thank you for the reply. Yes it's really strange. No I didn't mess around with the config. I use it out of the box. The only thing I noticed in auth.log is this message:

    Address xxx.xxx.xxx.xxx maps to xxx.xxxxxx.ch, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!

    Could this one trigger the ban?

    Jered commented Wed Jul 27 21:49:01 UTC 2011:

    Hm...You may need to poke around in /etc/fail2ban to see if there's a filter enabled that's looking for failed reverse DNS lookups. You'll want to look at the jails, filters, and actions - the best documentation to help you read those would be the official doc site for fail2ban.

    Basically, check the jails.conf file to see what's enabled, and try to work your way through the filters in enabled jails to find what could be applying to ssh connections.

    JOGLO Hosting commented Wed Dec 05 16:17:35 UTC 2012:

    is the tutorial work for CentOS as well?

    Jered commented Wed Dec 05 20:56:19 UTC 2012:

    Yes, though you'd want to change a couple commands. To install fail2ban on CentOS, use:

    sudo yum install fail2ban

    And to restart fail2ban after it's configured, run:

    sudo service fail2ban restart

    You might also run "chkconfig --list" to make sure fail2ban gets set up to run at boot time.

    Want to comment?


    (not made public)

    (optional)

    (use plain text or Markdown syntax)