In this article you will learn how to install and configure fail2ban, a security tool that defends against brute force attacks.
Before any attackers can compromise a system they have to find a way in. They might take a brute force approach, trying to get in through your ssh server by guessing at a username and password. Or they could test a web server, or mail server, or database server, or other application for a vulnerability they can exploit.
Those repeated efforts leave a trail in the log files of the services those would-be intruders probe. Analyzing all of those logs can be difficult and time-consuming, and you can't be watching them every minute of every day.
Fortunately fail2ban can make your life a lot easier. Fail2ban scans log files like /var/log/secure or /var/log/apache/error_log and bans IP addresses that make too many failed login attempts or bad server requests. It works by updating the firewall rules to reject or drop traffic from attacking IP addresses.
There are other software packages that also analyze log files and ban offensive machines. However, fail2ban has several appealing features.
In short, fail2ban is versatile and easy to set up.
You can install fail2ban through the package manager for most distributions.
This command will install fail2ban under Ubuntu or Debian:
sudo aptitude install fail2ban
On Red Hat-based systems like CentOS or Fedora you'll use yum:
sudo yum install fail2ban
Once fail2ban is installed we need to modify its configuration files. They are in the directory /etc/fail2ban.
If you look in jail.conf you will see a developer's warning about not modifying that file, advising you to put any changes in a file named jail.local. With that in mind, let's copy /etc/fail2ban/jail.conf to /etc/fail2ban/jail.local.
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Now you can set up that jail.local config file for your environment by enabling and modifying existing blocks or adding new ones for other services.
By default only the ssh section is enabled in fail2ban's jail.conf. That means fail2ban only analyzes the ssh connection log for failed logins.
To monitor another service, like a web, mail, dns or ftp server, you can set the appropriate config block'senabledvalue totrueto activate the fail2ban filter for that service.
You can modify much of the default behavior of fail2ban in the first config block, the one labeled[Default]. You can override a default setting by giving it a different value inside a service's config block.
To make any changes take effect you'll need to restart the fail2ban service. On most systems the command is:
sudo service fail2ban restart
Let's look at directives that tell fail2ban to watch the ssh connection log and set a 5-minute ban on the IP addresses of machines that fail too many login attempts. When this happens it will send an email containing the whois information of the offending machine.
Note: If you don't have a mail server on your machine fail2ban cannot send emails. You can set up a mail server on your machine to send mail directly or relay it through a service like Mailgun.
We can configure ssh monitoring with a very short jail.conf file:
[DEFAULT]
bantime = 600
findtime = 600
[ssh-iptables]
enabled = true
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, dest=demo@example.com]
logpath = /var/log/secure
maxretry = 5
We'll look at the meaning of all the directives shortly. The above configuration would tell fail2ban to watch /var/log/secure for ssh login attempts (on Ubuntu/Debian the log to watch would be /var/log/auth.log). If a machine logs more than 5 attempts in a 5-minute period it will be banned for 5 minutes, and fail2ban will send an email to demo@example.com.
Let's test fail2ban to make sure it behaves the way we want it to. We'll do that by failing a few ssh logins.
We'll use two machines: The server we want to protect and another machine to act as the attacker.
To run the test, simply get on the attacking machine and try to ssh to your server five times. For example:
ssh fakeuser@98.76.54.32
With the sixth try (assuming you have ssh's maxretry set to 5) your connection should time out if you try to ssh in again.
If you have fail2ban set to send you email check to see if you got a message like this one:
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 entry:
iptables -L Chain fail2ban-ssh (1 references) target prot opt source destination DROP all -- 208-78-96-200.realinfosec.com anywhere
Fail2ban works!
There are a lot of options in the jail.local file. Here are brief descriptions for some of them.
Duration (in seconds) of a ban for an IP address.
Use this option to describe how fail2ban will ban an offending IP address. 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'.
If you set this option to an IP address (usually localhost, 127.0.0.1), it won't be banned no matter how many times a user fails to login from it.
This option tells fail2ban which action to take when a filter finds a match.
Use this option to set the email of the person who should receive alerts when an IP address is banned.
Sets the default protocol to monitor, TCP or UDP.
Name of a 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'.
Defines whether or not a given section is enabled. Possible values are true or false.
Path to the log file a filter will monitor.
The port a service is listening to. If you have ssh running on a non-standard port, set this value in the service's config block.
Number of matches to trigger a ban action on an IP address. If this value were set to 6, after 6 filter triggers (like failed logins for ssh) fail2ban should block the offending machine's IP address.
Fail2ban is an extremely useful tool for securing a server. It can block attacks by banning offensive machines' IP addresses then email you their whois information and relevant log files. That means you can contact an attacker's ISP and file a complaint about them, reducing the chance of future attacks from the same address.
Be sure to set up config entries for any new services you install on your server and fail2ban will go a long way toward preventing system intrusions.
Ismail
© 2011-2013 Rackspace US, Inc.
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License

3 Comments
fail2ban restart failed
# Fail2Ban configuration file
#
# Author: Cyril Jaquier
#
# $Revision$
#
# The DEFAULT allows a global definition of the options. They can be overridden
# in each jail afterwards.
[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/8
# "bantime" is the number of seconds that a host is banned.
bantime = 600
# 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
# "backend" specifies the backend used to get files modification. Available
# options are "gamin", "polling" and "auto". This option can be overridden in
# each jail too (use "gamin" for a jail and "polling" for another).
#
# gamin: requires Gamin (a file alteration monitor) to be installed. If Gamin
# is not installed, Fail2ban will use polling.
# polling: uses a polling algorithm which does not require external libraries.
# auto: will choose Gamin if available and polling otherwise.
backend = auto
# This jail corresponds to the standard configuration in Fail2ban 0.6.
# The mail-whois action send a notification e-mail with a whois request
# in the body.
[ssh-iptables]
enabled = false
filter = sshd
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois[name=SSH, dest=you@example.com, sender=fail2ban@example.com]
logpath = /var/log/sshd.log
maxretry = 5
[proftpd-iptables]
enabled = false
filter = proftpd
action = iptables[name=ProFTPD, port=ftp, protocol=tcp]
sendmail-whois[name=ProFTPD, dest=you@example.com]
logpath = /var/log/proftpd/proftpd.log
maxretry = 6
# This jail forces the backend to "polling".
[sasl-iptables]
enabled = false
filter = sasl
backend = polling
action = iptables[name=sasl, port=smtp, protocol=tcp]
sendmail-whois[name=sasl, dest=you@example.com]
logpath = /var/log/mail.log
# Here we use TCP-Wrappers instead of Netfilter/Iptables. "ignoreregex" is
# used to avoid banning the user "myuser".
[ssh-tcpwrapper]
enabled = false
filter = sshd
action = hostsdeny
sendmail-whois[name=SSH, dest=you@example.com]
ignoreregex = for myuser from
logpath = /var/log/sshd.log
# This jail demonstrates the use of wildcards in "logpath".
# Moreover, it is possible to give other files on a new line.
[apache-tcpwrapper]
enabled = false
filter = apache-auth
action = hostsdeny
logpath = /var/log/apache*/*error.log
/home/www/myhomepage/error.log
maxretry = 6
# The hosts.deny path can be defined with the "file" argument if it is
# not in /etc.
[postfix-tcpwrapper]
enabled = false
filter = postfix
action = hostsdeny[file=/not/a/standard/path/hosts.deny]
sendmail[name=Postfix, dest=you@example.com]
logpath = /var/log/postfix.log
bantime = 300
# Do not ban anybody. Just report information about the remote host.
# A notification is sent at most every 600 seconds (bantime).
[vsftpd-notification]
enabled = false
filter = vsftpd
action = sendmail-whois[name=VSFTPD, dest=you@example.com]
logpath = /var/log/vsftpd.log
maxretry = 5
bantime = 1800
# Same as above but with banning the IP address.
[vsftpd-iptables]
enabled = false
filter = vsftpd
action = iptables[name=VSFTPD, port=ftp, protocol=tcp]
sendmail-whois[name=VSFTPD, dest=you@example.com]
logpath = /var/log/vsftpd.log
maxretry = 5
bantime = 1800
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
[apache-badbots]
enabled = false
filter = apache-badbots
action = iptables-multiport[name=BadBots, port="http,https"]
sendmail-buffered[name=BadBots, lines=5, dest=you@example.com]
logpath = /var/www/*/logs/access_log
bantime = 172800
maxretry = 1
# Use shorewall instead of iptables.
[apache-shorewall]
enabled = false
filter = apache-noscript
action = shorewall
sendmail[name=Postfix, dest=you@example.com]
logpath = /var/log/apache2/error_log
# Ban attackers that try to use PHP's URL-fopen() functionality
# through GET/POST variables. - Experimental, with more than a year
# of usage in production environments.
[php-url-fopen]
enabled = false
port = http,https
filter = php-url-fopen
logpath = /var/www/*/logs/access_log
maxretry = 1
# A simple PHP-fastcgi jail which works with lighttpd.
# If you run a lighttpd server, then you probably will
# find these kinds of messages in your error_log:
# ALERT – tried to register forbidden variable ‘GLOBALS’
# through GET variables (attacker '1.2.3.4', file '/var/www/default/htdocs/index.php')
# This jail would block the IP 1.2.3.4.
[lighttpd-fastcgi]
enabled = false
port = http,https
filter = lighttpd-fastcgi
# adapt the following two items as needed
logpath = /var/log/lighttpd/error.log
maxretry = 2
# This jail uses ipfw, the standard firewall on FreeBSD. The "ignoreip"
# option is overridden in this jail. Moreover, the action "mail-whois" defines
# the variable "name" which contains a comma using "". The characters '' are
# valid too.
[ssh-ipfw]
enabled = false
filter = sshd
action = ipfw[localhost=192.168.0.1]
sendmail-whois[name="SSH,IPFW", dest=you@example.com]
logpath = /var/log/auth.log
ignoreip = 168.192.0.1
# These jails block attacks against named (bind9). By default, logging is off
# with bind9 installation. You will need something like this:
#
# logging {
# channel security_file {
# file "/var/log/named/security.log" versions 3 size 30m;
# severity dynamic;
# print-time yes;
# };
# category security {
# security_file;
# };
# };
#
# in your named.conf to provide proper logging.
# This jail blocks UDP traffic for DNS requests.
# !!! WARNING !!!
# Since UDP is connection-less protocol, spoofing of IP and imitation
# of illegal actions is way too simple. Thus enabling of this filter
# might provide an easy way for implementing a DoS against a chosen
# victim. See
# http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
# Please DO NOT USE this jail unless you know what you are doing.
#
# [named-refused-udp]
#
# enabled = false
# filter = named-refused
# action = iptables-multiport[name=Named, port="domain,953", protocol=udp]
# sendmail-whois[name=Named, dest=you@example.com]
# logpath = /var/log/named/security.log
# ignoreip = 168.192.0.1
# This jail blocks TCP traffic for DNS requests.
[named-refused-tcp]
enabled = false
filter = named-refused
action = iptables-multiport[name=Named, port="domain,953", protocol=tcp]
sendmail-whois[name=Named, dest=you@example.com]
logpath = /var/log/named/security.log
ignoreip = 168.192.0.1
re: fail to start
fail2ban restart failed... my comment.
Add new comment