Secure Your Linux Server with Fail2BansteemCreated with Sketch.

in cybersecurity •  last year

Fail2Ban monitors log files to determine if someone who is trying to gain access is a legitimate user. If they aren't, they get banned temporarily by their IP address. Policies can be setup in conjunction with a firewall to log failed access attempts and drop traffic for a period of time, preventing a would-be attacker from even attempting to access your services.



This is a continuation from 3 previous parts:


sudo apt-get update

sudo apt-get install fail2ban

sudo apt-get install sendmail (optional)

Together: sudo apt-get install fail2ban sendmail

Given the previous guide for UFW being done, turn it on and allow ssh as an example.

ufw enable
ufw allow ssh


Here is where the config is located:


We don't edit that file though. We make a copy and comment out the contents like so:

awk '{ printf "# "; print; }' /etc/fail2ban/jail.conf | sudo tee /etc/fail2ban/jail.local

This file jail.local will override the defaults in jail.conf, so we just add any changes there instead.

Let's see how the original file looks:

sudo nano /etc/fail2ban/jail.conf

Editing configuration

If you want to exempt your own IP from multiple login security, open:

sudo nano /etc/fail2ban/jail.local

and add somewhere in the the following (or you can uncomment each section by removing the #):

ignoreip =

127... is for the local server itself, and then 123... is an example of your own IP. This applies to all jails for all programs. If you want to whitelist an IP per jail section, like ssh, use the command: fail2ban-client set ssh addignoreip


If you want to change how long an IP is banned for, the time interval to check for login attempt failures, or the maximum login attempt limit, then add and change the bantime, findtime and maxretry parameters.


If you want to setup email delivery of alerts from Fail2ban:


destemail =
sendername = Fail2Ban
sender =
mta = sendmail

Then add:

action = $(action_)s

where you replace action_ with either:

  • action_mw for email alerts
  • action_mwl for w/ relevant log lines

Jail Configuration

Apart from those main settings, are the individual service settings, like for SSH. You can look through to see what services are filtered by default.

Failregexs - these are custom filters you can make with regular expression matches that scan log files for attempted intruders. I suggest you google more into this feature and regex to learn more if you want to. Regex is powerful.

This command will tell you if fail2ban is running:

sudo fail2ban-client status

Apart from status, there is also the stop and start command on the service, or restart to reload the configuration alone.

And then reload the changes made in the config file with:

sudo fail2ban-client reload


That's it. Now if anyone tries to login to your ssh configured port, and fail to enter the password three times, their IP will be banned. If you didn't add your own IP to the configuration earlier, then you will also get banned if you fail to login after 3 attempts.

Recap summary:

sudo apt-get update
sudo apt-get -y install fail2ban sendmail
awk '{ printf "# "; print; }' /etc/fail2ban/jail.conf | sudo tee /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Add exemption for your IP (either add the lines or uncomment, and edit), and the email if you want to receive:

ignoreip =
destemail =
sendername = Fail2Ban
sender =
mta = sendmail

Reload and Done

sudo fail2ban-client reload
sudo fail2ban-client status

You should see:

krnel@steembuntu:~$ sudo fail2ban-client status
|- Number of jail:      1
`- Jail list:   sshd

If not, go back into the original /etc/fail2ban/jail.conf and add a line under the [ssh] section:

enabled = true

Then do this again:

sudo fail2ban-client reload
sudo fail2ban-client status

That should do it. If not, try to troubleshoot with the below section:

If that doesn't work... or for whatever reason you want only what you need in the file, put in all these values in a new config /etc/fail2ban/jail.local:

before = paths-debian.conf

ignoreip =
ignorecommand =
bantime  = 600
findtime  = 600
maxretry = 5
backend = auto
usedns = warn
logencoding = auto
enabled = false
filter = %(__name__)s

Add your email if you want:

destemail =
sendername = Fail2Ban
sender =
mta = sendmail
protocol = tcp
chain = INPUT
port = 0:65535
banaction = iptables-multiport

action_ = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]

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, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

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, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
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"]

action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                 %(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
action_blocklist_de  = blocklist_de[email="%(sender)s", service=%(filter)s, apikey="%(blocklist_de_apikey)s"]

action_badips =[category="%(name)s", banaction="%(banaction)s"]

action = %(action_mw)s
enabled  = true
port    = ssh
logpath = %(sshd_log)s

# This jail corresponds to the standard configuration in Fail2ban.
# The mail-whois action send a notification e-mail with a whois request
# in the body.
port    = ssh
logpath = %(sshd_log)s

If you want to enable jailing on individual services, for example in the [ssh] section, add that section to the jail.local file and add or uncomment the section as well.

Uncomment any section you want to have fail2ban enabled on, or copy and paste it at the end with the other additions, if that's what you already did.

Reload and Done

sudo fail2ban-client reload
sudo fail2ban-client status

Ok. That's it. The last section was only required if you want a cleaner file, with less filters running. You will have to add the filters you need as you need them though, since they won't be enabled by default any longer, such as HTTP for a web server fail2ban protection.

I hope the tutorial was of use to you.

Thank you for your time and attention! I appreciate the knowledge reaching more people. Take care. Peace.

Payout Selected

[References: 1, 2, 3]

If you appreciate and value the content, please consider:
Upvoting upvote91a69.png ,    Sharing share2195b.png and   Reblogging reblog33b5f.png below.

Follow me for more content to come!

2016-12-04, 10am

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  Trending


Beautiful man! I wrote about creating a lambda server the other day but avoided the server hardening stuff. This guide could be used in conjunction to do so.

I see a lot of agressive e.g. 2-3 failed attempt configurations that forgot to whitelist their own IP, so good job there and I just wanted to reiterate that point because it is very easy to hit 3 failed attempts.

What I did not see is what I consider the best part of fail 2 ban: with minimal knowledge of regex you can create custom filters, which means you can monitor any file for specific lines and leave it up to a simple fail2ban setting (in /etc/fail2ban/filter.d which is uneditable by the apache/nginx user) for deciding whether the offending IP has done enough to warrant a ban.

Protect drupal or wordpress installations without use of yet another plugin requiring several updates per year? Yes please.

Even more powerful, any time a web developer is sanitizing input they can simply log it when the code detects a condition they would never expect. For instance, a log line might look like "SUSPICIOUS BEHAVIOR by [IP]: submitting data to a dropdown box that is not one of the dropdown items" And the rest -- monitoring a user for how frequently they conduct a suspicious act and banning when appropriate -- is all handled by fail2ban. Instead what I frequently see is a developer writing the entire logging, checking, banning, and cleanup sequence into every page load. Just look at popular security plugins for wordpress/drupal. If you have control of the server, fail2ban and a custom filter makes for a far better option with a fraction of the effort.


Thanks for the feedback and extra suggestions. Much appreciated :)

Very good. I knew there was a reason to follow you. As I move away from windows OS and into Linux, security has been at the top of my list.

Thanks for this post, fail2ban is up one my witness server now!
Just a little mistake, it is not action = $(action_)s but action = %(action_)s