Fail2ban Documentation
Linode Fail2ban Guide

sudo yum install fail2ban  
sudo apt install fail2ban
sudo pacman -Syu fail2ban


Configuration Files


To modify configs, copy any fail2ban.conf to fail2ban.local and modify the copied fail2ban.local configuration file. Fail2ban will automatically override the settings in fail2ban.conf with those in fail2ban.local

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

This file is not intended to be modified directly. Run the command below to create a local configuration to edit -

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

This file holds all of your local fail2ban settings for this host. Some of the important lines and settings to look at are seen below

  • ignoreip
    • An IP address for fail2ban to ignore
  • maxrety
    • Number of retries before being locked out
#... File Reduced ...

# Destination email address used solely for the interpolations in
# jail.{conf,local,d/*} configuration files.
destemail =

# Sender email address used solely for some actions
sender = admin@hostname

# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
# mailing. Change mta configuration parameter to mail if you want to
# revert to conventional 'mail'.
mta = mail

# Default protocol
protocol = tcp

#... File Reduced ...

# Choose default action.  To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_mwl)s


# SSH servers

# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and[Definition]

failregex = ^<HOST> -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\.scgi)

ignoreregex = details.
#mode   = normal
enabled = true
port    = 22
logpath = %(sshd_log)s
backend = %(sshd_backend)s

#... File Reduced ...


enabled = true
port    = http,https
logpath = %(nginx_error_log)s

# To use 'nginx-limit-req' jail you should have `ngx_http_limit_req_module` 
# and define `limit_req` and `limit_req_zone` as described in nginx documentation
# or for example see in 'config/filter.d/nginx-limit-req.conf'
port    = http,https
logpath = %(nginx_error_log)s


enabled = true
port     = http,https
logpath  = %(nginx_error_log)s
maxretry = 2

#... File Reduced ...

its important to notice the line action = %(action_mwl)s - this line defines which default action we will take when a fail2ban is broken. These actions are defined within our jail.local, but Ill paste them here as well

# Action shortcuts. To be used to define action parameter

# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
banaction = iptables-multiport
banaction_allports = iptables-allports

# The simplest action to take: ban only
action_ = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report to the destemail.
action_mw = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
            %(mta)s-whois[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban & send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
             %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]

# See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
# ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines
# to the destemail.
action_xarf = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath=%(logpath)s, port="%(port)s"]

# ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
# to the destemail.
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]

# Report block via fail2ban reporting service API
# See the IMPORTANT note in action.d/blocklist_de.conf for when to use this action.
# Specify expected parameters in file action.d/blocklist_de.local or if the interpolation
# `action_blocklist_de` used for the action, set value of `blocklist_de_apikey`
# in your `jail.local` globally (section [DEFAULT]) or per specific jail section (resp. in 
# corresponding jail.d/my-jail.local file).
action_blocklist_de  = blocklist_de[email="%(sender)s", service=%(filter)s, apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]

# Report ban via, and use as blacklist
# See BadIPsAction docstring in config/action.d/ for
# documentation for this action.
# NOTE: This action relies on banaction being present on start and therefore
# should be last action defined for a jail.
action_badips =[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]
# Report ban via (uses action.d/badips.conf for reporting only)
action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]

# Report ban via
# See action.d/abuseipdb.conf for usage example and details.
action_abuseipdb = abuseipdb

You can use any action above that you'd like, and even create your own or modify them as you see fit.

Custom Jails

Using Regex and fail2ban's filters, we can create our own jails within fail2ban to define rules specific to requests we may be recieving on our application. For example, add the below to /etc/fail2ban/jail.local to define a rule to block attempts to run scripts on the webserver.

# Add these lines to /etc/fail2ban/jail.local

enabled  = true
port     = http,https
filter   = nginx-noscript
logpath  = /var/log/nginx/access.log
maxretry = 6

Now, we need to define the filter for the jail we just created. Fail2ban stores these within /etc/fail2ban/filter.d/. So, for our example we will create the nginx-noscript.conf file within this directory. Its important that the name we choose here corresponds with what we named our jail in jail.local.

# New definition for /etc/fail2ban/filter.d/nginx-noscript.conf jail

failregex = ^<HOST> -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\.scgi)

ignoreregex =

To check on the status of running jails, see the command below

sudo fail2ban-client status

When users are banned under a jail, you can see a list of them by running the following, where nginx-http-auth can be changed out for any name of a running jail.

sudo fail2ban-client status nginx-http-auth

To unban an IP from a jail, run the below

sudo fail2ban-client set nginx-http-auth unbanip

Log Files


Shows all failed log attemps, config changes