diff --git a/ansible/plays/configure-fail2ban/configure-fail2ban.yml b/ansible/plays/configure-fail2ban/configure-fail2ban.yml new file mode 100644 index 0000000..81ecee8 --- /dev/null +++ b/ansible/plays/configure-fail2ban/configure-fail2ban.yml @@ -0,0 +1,24 @@ +- hosts: nginx-server + become: yes + tasks: + - name: Copy custom fail2ban filters + synchronize: + mode: push + src: fail2ban/filter.d/ + dest: /etc/fail2ban/filter.d/ + - name: Copy custom fail2ban jail.local + synchronize: + mode: push + src: fail2ban/jail.local + dest: /etc/fail2ban/ + - name: Reload fail2ban service + ansible.builtin.service: + name: fail2ban + state: reloaded + - name: Checking status of fail2ban service after restart + command: systemctl status fail2ban + register: result + - name: Showing fail2ban status report + debug: + var: result + diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/3proxy.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/3proxy.conf new file mode 100644 index 0000000..76c7573 --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/3proxy.conf @@ -0,0 +1,20 @@ +# Fail2Ban filter for 3proxy +# +# + +[Definition] + + +failregex = ^\s[+-]\d{4} \S+ \d{3}0[1-9] \S+ :\d+ [\d.]+:\d+ \d+ \d+ \d+\s + +ignoreregex = + +datepattern = {^LN-BEG} + +# DEV Notes: +# http://www.3proxy.ru/howtoe.asp#ERRORS indicates that 01-09 are +# all authentication problems (%E field) +# Log format is: "L%d-%m-%Y %H:%M:%S %z %N.%p %E %U %C:%c %R:%r %O %I %h %T" +# +# Requested by ykimon in https://github.com/fail2ban/fail2ban/issues/246 +# Author: Daniel Black diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-auth.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-auth.conf new file mode 100644 index 0000000..40f6d6e --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-auth.conf @@ -0,0 +1,71 @@ +# Fail2Ban apache-auth filter +# + +[INCLUDES] + +# Read common prefixes. If any customizations available -- read them from +# apache-common.local +before = apache-common.conf + +[Definition] + +# Mode for filter: normal (default) and aggressive (allows DDoS & brute force detection of mod_evasive) +mode = normal + +# ignore messages of mod_evasive module: +apache-pref-ign-normal = (?!evasive) +# allow "denied by server configuration" from all modules: +apache-pref-ign-aggressive = +# mode related ignore prefix for common _apache_error_client substitution: +apache-pref-ignore = > + +prefregex = ^%(_apache_error_client)s (?:AH\d+: )?.+$ + +# auth_type = ((?:Digest|Basic): )? +auth_type = ([A-Z]\w+: )? + +failregex = ^client (?:denied by server configuration|used wrong authentication scheme)\b + ^user (?!`)(?:\S*|.*?) (?:auth(?:oriz|entic)ation failure|not found|denied by provider)\b + ^Authorization of user (?:\S*|.*?) to access .*? failed\b + ^%(auth_type)suser (?:\S*|.*?): password mismatch\b + ^%(auth_type)suser `(?:[^']*|.*?)' in realm `.+' (auth(?:oriz|entic)ation failure|not found|denied by provider)\b + ^%(auth_type)sinvalid nonce .* received - length is not\b + ^%(auth_type)srealm mismatch - got `(?:[^']*|.*?)' but expected\b + ^%(auth_type)sunknown algorithm `(?:[^']*|.*?)' received\b + ^invalid qop `(?:[^']*|.*?)' received\b + ^%(auth_type)sinvalid nonce .*? received - user attempted time travel\b + ^(?:No h|H)ostname \S+ provided via SNI(?:, but no hostname provided| and hostname \S+ provided| for a name based virtual host)\b + +ignoreregex = + +# DEV Notes: +# +# This filter matches the authorization failures of Apache. It takes the log messages +# from the modules in aaa that return HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED or +# HTTP_FORBIDDEN and not AUTH_GENERAL_ERROR or HTTP_INTERNAL_SERVER_ERROR. +# +# An unauthorized response 401 is the first step for a browser to instigate authentication +# however apache doesn't log this as an error. Only subsequent errors are logged in the +# error log. +# +# Source: +# +# By searching the code in http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/* +# for ap_log_rerror(APLOG_MARK, APLOG_ERR and examining resulting return code should get +# all of these expressions. Lots of submodules like mod_authz_* return back to mod_authz_core +# to return the actual failure. +# +# Note that URI can contain spaces. +# +# See also: http://wiki.apache.org/httpd/ListOfErrors +# Expressions that don't have tests and aren't common. +# more be added with https://issues.apache.org/bugzilla/show_bug.cgi?id=55284 +# ^user .*: nonce expired \([\d.]+ seconds old - max lifetime [\d.]+\) - sending new nonce\s*$ +# ^user .*: one-time-nonce mismatch - sending new nonce\s*$ +# ^realm mismatch - got `(?:[^']*|.*?)' but no realm specified\s*$ +# +# Because url/referer are foreign input, short form of regex used if long enough to idetify failure. +# +# Author: Cyril Jaquier +# Major edits by Daniel Black and Ben Rubson. +# Rewritten for v.0.10 by Sergey Brester (sebres). diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-badbots.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-badbots.conf new file mode 100644 index 0000000..12d4105 --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-badbots.conf @@ -0,0 +1,24 @@ +# Fail2Ban configuration file +# +# Regexp to catch known spambots and software alike. Please verify +# that it is your intent to block IPs which were driven by +# above mentioned bots. + + +[Definition] + +badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider|(?:Mozilla/\d+\.\d+ )?Jorgee +badbots = Atomic_Email_Hunter/4\.0|atSpider/1\.0|autoemailspider|bwh3_user_agent|China Local Browse 2\.6|ContactBot/0\.2|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailSpider|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Guestbook Auto Submitter|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \(efp@gmx\.net\)|LetsCrawl\.com/1\.0 \+http\://letscrawl\.com/|Lincoln State Web Browser|LMQueueBot/0\.2|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|MVAClient|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/3\.0 \(compatible; scan4mail \(advanced version\) http\://www\.peterspages\.net/?scan4mail\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 efp@gmx\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|NameOfAgent \(CMS Spider\)|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot admin@google\.com|ShablastBot 1\.0|snap\.com beta crawler v0|Snapbot/1\.0|Snapbot/1\.0 \(Snap Shots, \+http\://www\.snap\.com\)|sogou develop spider|Sogou Orion spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sogou spider|Sogou web spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|VadixBot|WebVulnCrawl\.unknown/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00 + +failregex = ^ -.*"(GET|POST|HEAD).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$ + +ignoreregex = + +datepattern = ^[^\[]*\[({DATE}) + {^LN-BEG} + +# DEV Notes: +# List of bad bots fetched from http://www.user-agents.org +# Generated on Thu Nov 7 14:23:35 PST 2013 by files/gen_badbots. +# +# Author: Yaroslav Halchenko diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-botsearch.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-botsearch.conf new file mode 100644 index 0000000..872f199 --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-botsearch.conf @@ -0,0 +1,39 @@ +# Fail2Ban filter to match web requests for selected URLs that don't exist +# +# This filter is aimed at blocking specific URLs that don't exist. This +# could be a set of URLs places in a Disallow: directive in robots.txt or +# just some web services that don't exist caused bots are searching for +# exploitable content. This filter is designed to have a low false positive +# rate due. +# +# An alternative to this is the apache-noscript filter which blocks all +# types of scripts that don't exist. +# +# +# This is normally a predefined list of exploitable or valuable web services +# that are hidden or aren't actually installed. +# + +[INCLUDES] + +# overwrite with apache-common.local if _apache_error_client is incorrect. +# Load regexes for filtering from botsearch-common.conf +before = apache-common.conf + botsearch-common.conf + +[Definition] + +prefregex = ^%(_apache_error_client)s (?:AH\d+: )?.+$ + +failregex = ^(?:File does not exist|script not found or unable to stat): (, referer: \S+)?\s*$ + ^script '' not found or unable to stat(, referer: \S+)?\s*$ + +ignoreregex = + +# Webroot represents the webroot on which all other files are based +webroot = /var/www/ + + +# DEV Notes: +# +# Author: Daniel Black diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-common.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-common.conf new file mode 100644 index 0000000..6577fe7 --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-common.conf @@ -0,0 +1,44 @@ +# Generic configuration items (to be used as interpolations) in other +# apache filters. + +[INCLUDES] + +before = common.conf +# Load customizations if any available +after = apache-common.local + +[DEFAULT] + +# Apache logging mode: +# all - universal prefix (logfile, syslog) +# logfile - logfile only +# syslog - syslog only +# Use `filter = apache-auth[logging=syslog]` to get more precise regex if apache logs into syslog (ErrorLog syslog). +# Use `filter = apache-auth[logging=all]` to get universal regex matches both logging variants. +logging = logfile + +# Apache logging prefixes (date-pattern prefix, server, process etc.): +apache-prefix-syslog = %(__prefix_line)s +apache-prefix-logfile = \[\]\s +apache-prefix-all = (?:%(apache-prefix-logfile)s|%(apache-prefix-syslog)s)? + +# Setting for __prefix_line (only `logging=syslog`): +_daemon = (?:apache\d*|httpd(?:/\w+)?) + +apache-prefix = > + +apache-pref-ignore = + +_apache_error_client = \[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client (:\d{1,5})?\] + +datepattern = {^LN-BEG} + +# Common prefix for [error] apache messages which also would include +# Depending on the version it could be +# 2.2: [Sat Jun 01 11:23:08 2013] [error] [client 1.2.3.4] +# 2.4: [Thu Jun 27 11:55:44.569531 2013] [core:info] [pid 4101:tid 2992634688] [client 1.2.3.4:46652] +# 2.4 (perfork): [Mon Dec 23 07:49:01.981912 2013] [:error] [pid 3790] [client 204.232.202.107:46301] script '/var/www/timthumb.php' not found or unable to +# +# Reference: https://github.com/fail2ban/fail2ban/issues/268 +# +# Author: Yaroslav Halchenko diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-fakegooglebot.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-fakegooglebot.conf new file mode 100644 index 0000000..729410a --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-fakegooglebot.conf @@ -0,0 +1,16 @@ +# Fail2Ban filter for fake Googlebot User Agents + +[Definition] + +failregex = ^ .*Googlebot.*$ + +ignoreregex = + +datepattern = ^[^\[]*\[({DATE}) + {^LN-BEG} + +# 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/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-modsecurity.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-modsecurity.conf new file mode 100644 index 0000000..f7600ac --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-modsecurity.conf @@ -0,0 +1,19 @@ +# Fail2Ban apache-modsec filter +# + +[INCLUDES] + +# Read common prefixes. If any customizations available -- read them from +# apache-common.local +before = apache-common.conf + +[Definition] + + +failregex = ^%(_apache_error_client)s(?: \[client [^\]]+\])? ModSecurity:\s+(?:\[(?:\w+ \"[^\"]*\"|[^\]]*)\]\s*)*Access denied with code [45]\d\d + +ignoreregex = + +# https://github.com/SpiderLabs/ModSecurity/wiki/ModSecurity-2-Data-Formats +# Author: Daniel Black +# Sergey G. Brester aka sebres (review, optimization) diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-nohome.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-nohome.conf new file mode 100644 index 0000000..358d6d3 --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-nohome.conf @@ -0,0 +1,20 @@ +# Fail2Ban filter to web requests for home directories on Apache servers +# +# Regex to match failures to find a home directory on a server, which +# became popular last days. Most often attacker just uses IP instead of +# domain name -- so expect to see them in generic error.log if you have +# per-domain log files. + +[INCLUDES] + +# overwrite with apache-common.local if _apache_error_client is incorrect. +before = apache-common.conf + +[Definition] + + +failregex = ^%(_apache_error_client)s (AH00128: )?File does not exist: .*/~.* + +ignoreregex = + +# Author: Yaroslav O. Halchenko diff --git a/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-noscript.conf b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-noscript.conf new file mode 100644 index 0000000..32991cb --- /dev/null +++ b/ansible/plays/configure-fail2ban/fail2ban/filter.d/apache-noscript.conf @@ -0,0 +1,37 @@ +# Fail2Ban filter to block web requests for scripts (on non scripted websites) +# +# This matches many types of scripts that don't exist. This could generate a +# lot of false positive matches in cases like wikis and forums where users +# no affiliated with the website can insert links to missing files/scripts into +# pages and cause non-malicious browsers of the site to trigger against this +# filter. +# +# If you'd like to match specific URLs that don't exist see the +# apache-botsearch filter. +# + +[INCLUDES] + +# overwrite with apache-common.local if _apache_error_client is incorrect. +before = apache-common.conf + +[Definition] + +script = /\S*(?:php(?:[45]|[.-]cgi)?|\.asp|\.exe|\.pl) + +prefregex = ^%(_apache_error_client)s (?:AH0(?:01(?:28|30)|1(?:264|071)): )?(?:(?:[Ff]ile|script|[Gg]ot) ).+$ + +failregex = ^(?:does not exist|not found or unable to stat):