OS: CentOS 7

Configure fail2ban


Configure Fail2ban

Fail2ban reads .conf configuration files first, then .local files override any settings. Because of this, all changes to the configuration are generally done in .local files, leaving the .conf files untouched.

Configure fail2ban.local
  1. fail2ban.conf contains the default configuration profile. The default settings will give you a reasonable working setup. If you want to make any changes, it’s best to do it in a separate file, fail2ban.local, which overrides fail2ban.conf. Rename a copy fail2ban.conf to fail2ban.local.
    cp /etc/fail2ban/fail2ban.conf /etc/fail2ban/fail2ban.local
  2. From here, you can opt to edit the definitions in fail2ban.local to match your desired configuration. The values that can be changed are:
    • loglevel: The level of detail that Fail2ban’s logs provide can be set to 1 (error), 2 (warn), 3 (info), or 4 (debug).
    • logtarget: Logs actions into a specific file. The default value of /var/log/fail2ban.log puts all logging into the defined file. Alternately, you can change the value to:
      • STDOUT: output any data
      • STDERR: output any errors
      • SYSLOG: message-based logging
      • FILE: output to a file
    • socket: The location of the socket file.
    • pidfile: The location of the PID file.
Configure jail.local Settings

The jail.conf file will enable Fail2ban for SSH by default for Debian and Ubuntu, but not CentOS. All other protocols and configurations (HTTP, FTP, etc.) are commented out. If you want to change this, create a jail.local for editing:

cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
If using CentOS or Fedora you will need to change the backend option in jail.local from auto to systemd. This is not necessary on Debian 8 or Ubuntu 16.04, even though both use systemd as well.


# "backend" specifies the backend used to get files modification.
# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
# This option can be overridden in each jail as well.

. . .

backend = systemd

To enable the SSH daemon jail, uncomment the following lines in jail.local:


enabled = true
Whitelist IP


To ignore specific IPs, add them to the ignoreip line. By default, this command will not ban the localhost. If you work from a single IP address often, it may be beneficial to add it to the ignore list:



# "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 =

If you wish to whitelist IPs only for certain jails, this can be done with the fail2ban-client command. Replace JAIL with the name of your jail, and with the IP you wish to whitelist.


fail2ban-client set JAIL addignoreip
Ban Time and Retry AmountPermalink

Set bantime, findtime, and maxretry to define the circumstances and the length of time of a ban:


# "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 = 3

bantime: The length of time in seconds for which an IP is banned. If set to a negative number, the ban will be permanent. The default value of 600 is set to ban an IP for a 10-minute duration.

findtime: The length of time between login attempts before a ban is set. For example, if Fail2ban is set to ban an IP after five (5) failed log-in attempts, those 5 attempts must occur within the set 10-minute findtime limit. The findtime value should be a set number of seconds.

maxretry: How many attempts can be made to access the server from a single IP before a ban is imposed. The default is set to 3.

Email Alerts


To receive email when fail2ban is triggered, adjust the email settings:

destemail: The email address where you would like to receive the emails.

sendername: The name under which the email shows up.

sender: The email address from which Fail2ban will send emails.

Email action in the JAILS module:



# To use more aggressive sshd filter (inclusive sshd-ddos failregex):
#filter = sshd-aggressive
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
action = %(banaction)s[name=%(__name__)s-tcp, port="%(port)s", protocol="tcp", chain="%(chain)s", actname=%(banaction)s-tcp]
 %(banaction)s[name=%(__name__)s-udp, port="%(port)s", protocol="udp", chain="%(chain)s", actname=%(banaction)s-udp]
 %(mta)s-whois[name=%(__name__)s, dest="%(destemail)s"]
Email template:



Sendmail integration with SMTP relay



yum update && yum install epel-release
yum install fail2ban sendmail sendmail-cf

Enable and start the services:

systemctl start fail2ban
systemctl enable fail2ban
systemctl start sendmail
systemctl enable sendmail


First login as Root user.

1. Create Auth File

First create directory for storing authentication files.

sudo mkdir /etc/mail/authinfo
sudo chmod 700 /etc/mail/authinfo

Now, create an auth file with any name like smtp-auth and add the following content. Replace the above email with your gmail or google apps email.

sudo vi /etc/mail/authinfo/smtp-auth
AuthInfo: "U:root" "I:user@gmail.com" "P:PASSWORD"

Now create a hash map file of above created auth file.

sudo makemap hash /etc/mail/authinfo/smtp-auth < /etc/mail/authinfo/smtp-auth

If you come across any error like below, switch to root user and try again.

sudo makemap hash /etc/mail/authinfo/smtp-auth < /etc/mail/authinfo/smtp-auth
-bash: /etc/mail/authinfo/smtp-auth: Permission denied


2. Configure Sendmail with SMART_HOST

Put bellow lines into your sendmail.mc configuration file right above first “MAILER” definition line:

define(`RELAY_MAILER_ARGS', `TCP $h 587')dnl
define(`ESMTP_MAILER_ARGS', `TCP $h 587')dnl
define(`confAUTH_OPTIONS', `A p')dnl
FEATURE(`authinfo',`hash -o /etc/mail/authinfo/smtp-auth.db')dnl

dnl MAILER(cyrusv2)dnl

Do not put the above lines on the top of your sendmail.mc configuration file !

In the next step we will need to re-build sendmail’s configuration. To do that execute:

[root@localhost ~]# sudo vi /etc/mail/authinfo/smtp-auth
[root@localhost ~]# sudo makemap hash /etc/mail/authinfo/smtp-auth < /etc/mail/authinfo/smtp-auth

Now you should see a new file: smtp-auth.db

[root@localhost ~]# ls /etc/mail/authinfo/smtp-auth
 smtp-auth smtp-auth.db


re-build sendmail’s configuration

[root@localhost ~]# sudo make -C /etc/mail
 make: Entering directory `/etc/mail'
 make: Leaving directory `/etc/mail'

Reload the sendmail service

[root@localhost ~]# sudo service sendmail restart
 Redirecting to /bin/systemctl restart sendmail.service
3. Test with a email:
[root@localhost ~]# echo "Just a teset" | mail -s "test" test@recepient.com

Check the log:

[root@localhost ~]# tail /var/log/maillog
 Oct 25 11:25:32 localhost sendmail[58929]: x9P0PV3e058929: to=test@recepient.com, ctladdr=xxxx@gmail.com (0/0), delay=00:00:01, xdelay=00:00:01, mailer=relay, pri=30323, relay=[] [], dsn=2.0.0, stat=Sent (x9P0PVwc058930 Message accepted for delivery)
 Oct 25 11:25:33 localhost sendmail[58933]: STARTTLS=client, relay=smtp.gmail.com., version=TLSv1/SSLv3, verify=FAIL, cipher=ECDHE-RSA-AES128-GCM-SHA256, bits=128/128
 Oct 25 11:25:36 localhost sendmail[58933]: x9P0PVwc058930: to=<fuchenggang@icloud.com>, delay=00:00:05, xdelay=00:00:04, mailer=relay, pri=120483, relay=smtp.gmail.com. [], dsn=2.0.0, stat=Sent (OK 1571963136 p11sm175545pgs.51 - gsmtp)
 Oct 25 11:28:48 localhost sendmail[59067]: starting daemon (8.14.7): SMTP+queueing@01:00:00
 Oct 25 11:28:48 localhost sm-msp-queue[59086]: starting daemon (8.14.7): queueing@01:00:00
 Oct 25 11:29:16 localhost sendmail[59095]: x9P0TGpY059095: from=root, size=225, class=0, nrcpts=1, msgid=<201910250029.x9P0TGpY059095@localhost.localdomain>, relay=root@localhost
 Oct 25 11:29:16 localhost sendmail[59096]: x9P0TGl8059096: from=<root@localhost.localdomain>, size=489, class=0, nrcpts=1, msgid=<201910250029.x9P0TGpY059095@localhost.localdomain>, proto=ESMTP, daemon=MTA, relay=localhost []
 Oct 25 11:29:16 localhost sendmail[59095]: x9P0TGpY059095: to=test@recepient.com, ctladdr=root (0/0), delay=00:00:00, xdelay=00:00:00, mailer=relay, pri=30225, relay=[] [], dsn=2.0.0, stat=Sent (x9P0TGl8059096 Message accepted for delivery)
 Oct 25 11:29:18 localhost sendmail[59098]: STARTTLS=client, relay=smtp.gmail.com., version=TLSv1/SSLv3, verify=FAIL, cipher=ECDHE-RSA-AES128-GCM-SHA256, bits=128/128
 Oct 25 11:29:20 localhost sendmail[59098]: x9P0TGl8059096: to=<test@recepient.com>, ctladdr=<root@localhost.localdomain> (0/0), delay=00:00:04, xdelay=00:00:04, mailer=relay, pri=120489, relay=smtp.gmail.com. [], dsn=2.0.0, stat=Sent (OK 1571963360 d1sm129991pfc.98 - gsmtp)


protect Apache / Nginx / Varnis / Squid / lighthttpd from DOS

As you can see, this method will work for any server you have in front of your real web server, or to the actual web server itself, actually this will mainly protect your port 80.

Consider that you will have to adjust the path to your web server, I’ll use varnish in my case.

Edit your /etc/fail2ban/jail.conf file and add this section:

my apache is installed on CentOS 7 with SSL enabled, so the access log is /var/log/httpd/ssl_request_log

enabled = true
port = http,https
filter = http-get-dos
logpath = /var/log/httpd/ssl_request_log
maxretry = 300
findtime = 300
#ban for 5 minutes
bantime = 600
action = iptables[name=HTTP, port=http, protocol=tcp]

Now we need to create the filter, to do that, create the file /etc/fail2ban/filter.d/http-get-dos.conf and copy the text below in it:

# Fail2Ban configuration file
# Author: http://www.go2linux.org

# Option: failregex
# Note: This regex will match any GET entry in your logs, so basically all valid and not valid entries are a match.
# You should set up in the jail.conf file, the maxretry and findtime carefully in order to avoid false positives.

failregex = ^ -.*GET

# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
ignoreregex =


Be sure to adjust maxretry and findtime to some values that fits your needs.

  • maxretry Is the maximum times of tries before the originating IP gets blocked.
  • findtiem Is the time window (in seconds) where the maxretry times should occur, for the IP to get blocked.

As you can see in my example, I have set up 300 maxretry and 300 for findtime, so, we need to have 300 GETs from the same IP in a time window of 300 seconds to have the originating IP blocked.

Consider that you will have one GET for each css, js, html, ico and other files that are part of your webpage, so if you have 20 components, some client needs only to load 15 pages in 5 minutes to get blocked. Be sure to adjust those values to fit your needs.