diff --git a/ChangeLog b/ChangeLog index f1963b1e..a3370146 100644 --- a/ChangeLog +++ b/ChangeLog @@ -33,6 +33,7 @@ ver. 0.9.2 (2014/XX/XXX) - wanna-be-released - New Features: - New filter: - postfix-rbl Thanks Lee Clemens + - apache-fakegooglebot.conf Thanks Lee Clemens - New recursive embedded substitution feature added: - `<HOST>` becomes `` for PREF=`IPV4`; - `<HOST>` becomes `1.2.3.4` for PREF=`IPV4` and IPV4HOST=`1.2.3.4`; @@ -49,6 +50,8 @@ ver. 0.9.2 (2014/XX/XXX) - wanna-be-released - empty or "basic" works as-is - "cymru" additionally prints (ASN, Country RIR) per banned IP - Requires dnspython or dnspython3 + - New ignorecommand: + - apache-fakegooglebot.sh Thanks Lee Clemens - Enhancements: * Enable multiport for firewallcmd-new action. Closes gh-834 diff --git a/config/filter.d/apache-fakegooglebot.conf b/config/filter.d/apache-fakegooglebot.conf new file mode 100644 index 00000000..b8a73504 --- /dev/null +++ b/config/filter.d/apache-fakegooglebot.conf @@ -0,0 +1,14 @@ +# Fail2Ban filter for fake Googlebot User Agents + +[Definition] + +failregex = ^ .*Googlebot.*$ + +ignoreregex = + + +# DEV Notes: +# +# Author: Lee Clemens +# Thanks: Johannes B. Ullrich, Ph.D. +# Reference: https://isc.sans.edu/forums/diary/When+Google+isnt+Google/15968/ diff --git a/config/filter.d/ignorecommands/apache-fakegooglebot.sh b/config/filter.d/ignorecommands/apache-fakegooglebot.sh new file mode 100755 index 00000000..d8b2d328 --- /dev/null +++ b/config/filter.d/ignorecommands/apache-fakegooglebot.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Based on: https://isc.sans.edu/forums/diary/When+Google+isnt+Google/15968/ + +if [ "$#" -ne 1 ]; then + echo "Unexpected number of arguments: $#" + exit 1 +else + b="$1" + h=$(host ${b}) + if echo ${h} | grep -e ' crawl-.*\.googlebot\.com\.$'; then + h=$(echo ${h} | cut -f5 -d' ') + n=$(host ${h} | cut -f4 -d' ') + if [ "${n}" = "${b}" ] ; then + exit 0 + else + exit 1 + fi + else + exit 1 + fi +fi diff --git a/config/jail.conf b/config/jail.conf index 334e3298..621c7230 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -277,6 +277,14 @@ logpath = %(apache_error_log)s maxretry = 2 +[apache-fakegooglebot] + +port = http,https +logpath = %(apache_access_log)s +maxretry = 1 +ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot.sh + + [apache-modsecurity] port = http,https diff --git a/config/paths-common.conf b/config/paths-common.conf index c634e73d..837d339a 100644 --- a/config/paths-common.conf +++ b/config/paths-common.conf @@ -61,3 +61,6 @@ dovecot_log = %(syslog_mail_warn)s solidpop3d_log = %(syslog_local0)s mysql_log = %(syslog_daemon)s + +# Directory with ignorecommand scripts +ignorecommands_dir = /etc/fail2ban/filter.d/ignorecommands diff --git a/fail2ban/client/filterreader.py b/fail2ban/client/filterreader.py index 669a5896..51d18c0e 100644 --- a/fail2ban/client/filterreader.py +++ b/fail2ban/client/filterreader.py @@ -71,7 +71,7 @@ class FilterReader(DefinitionInitConfigReader): for regex in value.split('\n'): # Do not send a command if the rule is empty. if regex != '': - stream.append(["set", self._jailName, "addignoreregex", regex]) + stream.append(["set", self._jailName, "addignoreregex", regex]) if self._initOpts: if 'maxlines' in self._initOpts: # We warn when multiline regex is used without maxlines > 1 diff --git a/fail2ban/tests/files/logs/apache-fakegooglebot b/fail2ban/tests/files/logs/apache-fakegooglebot new file mode 100644 index 00000000..76bb0dcb --- /dev/null +++ b/fail2ban/tests/files/logs/apache-fakegooglebot @@ -0,0 +1,5 @@ +# Apache 2.2 +# failJSON: { "time": "2015-01-31T14:29:44", "match": true, "host": "66.249.66.1" } +66.249.66.1 - - - [31/Jan/2015:14:29:44 ] example.com "GET / HTTP/1.1" 200 814 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" + 293 1149 546 +# failJSON: { "time": "2015-01-31T14:29:44", "match": false, "host": "93.184.216.34" } +93.184.216.34 - - - [31/Jan/2015:14:29:44 ] example.com "GET / HTTP/1.1" 200 814 "-" "NOT A __GOOGLE_BOT__" + 293 1149 546 diff --git a/fail2ban/tests/samplestestcase.py b/fail2ban/tests/samplestestcase.py index 2c18a504..bd2bd2e7 100644 --- a/fail2ban/tests/samplestestcase.py +++ b/fail2ban/tests/samplestestcase.py @@ -141,7 +141,8 @@ def testSampleRegexsFactory(name): return testFilter -for filter_ in filter(lambda x: not x.endswith('common.conf'), os.listdir(os.path.join(CONFIG_DIR, "filter.d"))): +for filter_ in filter(lambda x: not x.endswith('common.conf') and x.endswith('.conf'), + os.listdir(os.path.join(CONFIG_DIR, "filter.d"))): filterName = filter_.rpartition(".")[0] if not filterName.startswith('.'): setattr( diff --git a/setup.py b/setup.py index f0b4b331..a6970eff 100755 --- a/setup.py +++ b/setup.py @@ -96,7 +96,7 @@ setup( 'bin/fail2ban-client', 'bin/fail2ban-server', 'bin/fail2ban-regex', - 'bin/fail2ban-testcases', + 'bin/fail2ban-testcases' ], packages = [ 'fail2ban', @@ -124,6 +124,9 @@ setup( ('/etc/fail2ban/filter.d', glob("config/filter.d/*.conf") ), + ('/etc/fail2ban/filter.d/ignorecommands', + glob("config/filter.d/ignorecommands/*") + ), ('/etc/fail2ban/action.d', glob("config/action.d/*.conf") + glob("config/action.d/*.py")