Secure Your Web Server Using Fail2ban
Fail2ban application monitors server log files for intrusion attempts and other suspicious activity. After a predefined number of failures from a host, fail2ban blocks its IP address automatically for a specific duration.
With fail2ban, you can help secure your server against unauthorized access attempts. It is particularly effective in reducing the risk from scripted attacks and botnets.
To Install Fail2ban in Debian/Ubuntu System
$ sudo ap–get update
$ sudo apt–get install fail2ban
Redhat/Centos Users can use Yum repo manager to install fail2ban
$ sudo yum install fail2ban
To get started, we need to adjust the configuration file that fail2ban uses to determine what application logs to monitor and what actions to take when offending entries are found. The supplied /etc/fail2ban/jail.conf is the main provided resource for this.
To make modifications, we need to copy this file to /etc/fail2ban/jail.local. This will prevent our changes from being overwritten if a package update provides a new default file:
$ sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Finally Restart fail2ban
By Default, only SSH filter is enable , which brute force against SSH
However, we need to jail apache web server also, so we have to add
enabled = true
in all directive where we are protecting apache
[apache-auth]
enabled = true
port = http,https
logpath = %(apache_error_log)s
[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
enabled = true
port = http,https
logpath = %(apache_access_log)s
bantime = 48h
maxretry = 1
[apache-noscript]
enabled = true
port = http,https
logpath = %(apache_error_log)s
[apache-overflows]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 2
[apache-nohome]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 2
[apache-botsearch]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 2
[apache-fakegooglebot]
enabled = true
port = http,https
logpath = %(apache_access_log)s
maxretry = 1
ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot <ip>
[apache-modsecurity]
port = http,https
logpath = %(apache_error_log)s
maxretry = 2
[apache-shellshock]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 1
To Mitigate DoS attacks against Apache Web Server
Under /etc/fail2ban/jail.d/apache-get-dos.conf file insert the below lines
[apache-get-dos]
enabled = true
port = http,https
filter = apache-get-dos
logpath = /var/www/*/logs/access.log
datepattern = %%d/%%b/%%Y:%%H:%%M:%%S %%z
maxretry = 300
findtime = 5m
bantime = 1h
Alternatively you insert the below lines
# Fail2Ban filter to scan Apache access.log for DoS attacks
[INCLUDES]
before = common.conf
[Definition]
# Option: failregex
# Notes.: regex to match GET requests in the logfile resulting in one of the
# following status codes: 401, 403, 404, 503.
# The host must be matched by a group named “host”. The tag “<HOST>”
# can be used for standard IP/hostname matching and is only an alias for
# (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values: TEXT
failregex = ^<HOST> .*“GET (?!\/robots\.txt).*” (401|403|404|503)\s
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =
Sometimes, the definition for designed failregex too aggressively and have banned too many IPs, remember those commands:
# unban an IP from a specific jail
# $ fail2ban–client set <JAIL> unbanip <IP>
$ fail2ban–client set apache–get–dos unbanip 192.168.6.4
# unban an IP (or several) from all jails
$ fail2ban–client unban <IP> … <IP>
# unbans all IP addresses (in all jails and database)
$ fail2ban–client unban –all
We can provide you with some additional commands to further investigate such DoS attacks:
$ sudo netstat -an |grep -i est|awk ‘{print $2}’|cut -d. -f1-4|sort|uniq -c| sort -nr |head -20
You may also want to scan all Apache access logs for the IPs with most requests:
# Top 10 IP list for ALL sites for previous hour
$ grep -h “\[$(date -d -1hour +’%d/%b/%Y:%H:’)” /var/www/*/logs/access.log |\
cut -d’ ‘ -f1 | sort | uniq -c | sort -nr | head -n10
# Top 10 IP list for ALL sites for current hour
$ grep -h “\[$(date +’%d/%b/%Y:%H:’)” /var/www/*/logs/access.log | \
cut -d’ ‘ -f1 | sort | uniq -c | sort -nr | head -n10
# Top 10 IP list for ALL sites with filename
$ grep “\[$(date +’%d/%b/%Y:%H:’)” /var/www/*/logs/access.log | cut -d’ ‘ -f1 |\
sort | uniq -c | sort -nr | head -n10
I recommend you block such IPs directly on your front-end firewall. But in case you can’t, use iptables to quickly block a single IP:
# Block a single IP
$ sudo iptables -A INPUT -s <IP> -j DROP
# Unblock it
$ sudo iptables -D INPUT -s <IP> -j DROP