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:
- Secure Your Linux Server with a Firewall
- Setting Up A Linux VPS Securely (Pt.2)
- Setting Up A Linux VPS Securely (Pt.1)
Installation
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
Configuration
Here is where the config is located:
/etc/fail2ban/jail.conf
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 #):
[DEFAULT]
ignoreip = 127.0.0.1/8 123.45.67.89
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 123.45.67.89
Bans
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.
Emails
If you want to setup email delivery of alerts from Fail2ban:
# ACTIONS
destemail = [email protected]
sendername = Fail2Ban
sender = [email protected]
mta = sendmail
Then add:
action = $(action_)s
where you replace action_
with either:
action_mw
for email alerts
oraction_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
Done
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:
[DEFAULT]
ignoreip = 127.0.0.1/8 123.45.67.89
destemail = [email protected]
sendername = Fail2Ban
sender = [email protected]
mta = sendmail
Reload and Done
sudo fail2ban-client reload
sudo fail2ban-client status
You should see:
krnel@steembuntu:~$ sudo fail2ban-client status
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
:
[INCLUDES]
before = paths-debian.conf
[DEFAULT]
ignoreip = 127.0.0.1/8 123.45.67.89
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 = [email protected]
sendername = Fail2Ban
sender = [email protected]
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 = badips.py[category="%(name)s", banaction="%(banaction)s"]
action = %(action_mw)s
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
[sshd-ddos]
# 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.
If you appreciate and value the content, please consider:
Upvoting , Sharing and Reblogging below.
@krnel
2016-12-04, 10am
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.
Sweet!
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.
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 :)
Good post friend
upvoted.
Hi,
Thanks for this post, fail2ban is up one my witness server now!
Just a little mistake, it is not
action = $(action_)s
butaction = %(action_)s