diff options
Diffstat (limited to 'config/filter.d')
36 files changed, 400 insertions, 197 deletions
diff --git a/config/filter.d/apache-auth.conf b/config/filter.d/apache-auth.conf index 8a63858d..d9a6fa5e 100644 --- a/config/filter.d/apache-auth.conf +++ b/config/filter.d/apache-auth.conf @@ -9,20 +9,21 @@ before = apache-common.conf [Definition] +prefregex = ^%(_apache_error_client)s (?:AH\d+: )?<F-CONTENT>.+</F-CONTENT>$ -failregex = ^%(_apache_error_client)s (AH(01797|01630): )?client denied by server configuration: (uri )?\S*(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01617: )?user .*? authentication failure for "\S*": Password Mismatch(, referer: \S+)?$ - ^%(_apache_error_client)s (AH01618: )?user .*? not found(: )?\S*(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01614: )?client used wrong authentication scheme: \S*(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH\d+: )?Authorization of user \S+ to access \S* failed, reason: .*$ - ^%(_apache_error_client)s (AH0179[24]: )?(Digest: )?user .*?: password mismatch: \S*(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH0179[01]: |Digest: )user `.*?' in realm `.+' (not found|denied by provider): \S*(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01631: )?user .*?: authorization failure for "\S*":(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01775: )?(Digest: )?invalid nonce .* received - length is not \S+(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01788: )?(Digest: )?realm mismatch - got `.*?' but expected `.+'(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01789: )?(Digest: )?unknown algorithm `.*?' received: \S*(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01793: )?invalid qop `.*?' received: \S*(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01777: )?(Digest: )?invalid nonce .*? received - user attempted time travel(, referer: \S+)?\s*$ +# auth_type = ((?:Digest|Basic): )? +auth_type = ([A-Z]\w+: )? + +failregex = ^client (?:denied by server configuration|used wrong authentication scheme)\b + ^user <F-USER>(?:\S*|.*?)</F-USER> (?:auth(?:oriz|entic)ation failure|not found|denied by provider)\b + ^Authorization of user <F-USER>(?:\S*|.*?)</F-USER> to access .*? failed\b + ^%(auth_type)suser <F-USER>(?:\S*|.*?)</F-USER>: password mismatch\b + ^%(auth_type)suser `<F-USER>(?:[^']*|.*?)</F-USER>' in realm `.+' (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 ignoreregex = @@ -43,14 +44,17 @@ ignoreregex = # 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 -# ^%(_apache_error_client)s (AH01778: )?user .*: nonce expired \([\d.]+ seconds old - max lifetime [\d.]+\) - sending new nonce\s*$ -# ^%(_apache_error_client)s (AH01779: )?user .*: one-time-nonce mismatch - sending new nonce\s*$ -# ^%(_apache_error_client)s (AH02486: )?realm mismatch - got `.*' but no realm specified\s*$ +# ^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*$ # -# referer is always in error log messages if it exists added as per the log_error_core function in server/log.c +# 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 +# Major edits by Daniel Black and Ben Rubson. +# Rewritten for v.0.10 by Sergey Brester (sebres). diff --git a/config/filter.d/apache-botsearch.conf b/config/filter.d/apache-botsearch.conf index 5687d405..7def09ac 100644 --- a/config/filter.d/apache-botsearch.conf +++ b/config/filter.d/apache-botsearch.conf @@ -23,13 +23,12 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s ((AH001(28|30): )?File does not exist|(AH01264: )?script not found or unable to stat): <webroot><block>(, referer: \S+)?\s*$ - ^%(_apache_error_client)s script '<webroot><block>' not found or unable to stat(, referer: \S+)?\s*$ - -ignoreregex = +prefregex = ^%(_apache_error_client)s (?:AH\d+: )?<F-CONTENT>.+</F-CONTENT>$ +failregex = ^(?:File does not exist|script not found or unable to stat): <webroot><block>(, referer: \S+)?\s*$ + ^script '<webroot><block>' not found or unable to stat(, referer: \S+)?\s*$ -[Init] +ignoreregex = # Webroot represents the webroot on which all other files are based webroot = /var/www/ diff --git a/config/filter.d/apache-common.conf b/config/filter.d/apache-common.conf index 3d1f902b..3eec83d0 100644 --- a/config/filter.d/apache-common.conf +++ b/config/filter.d/apache-common.conf @@ -3,12 +3,31 @@ [INCLUDES] +before = common.conf # Load customizations if any available after = apache-common.local [DEFAULT] -_apache_error_client = \[\] \[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client <HOST>(:\d{1,5})?\] +# 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-prefix-<logging>> + +_apache_error_client = <apache-prefix>\[(:?error|\S+:\S+)\]( \[pid \d+(:\S+ \d+)?\])? \[client <HOST>(:\d{1,5})?\] datepattern = {^LN-BEG} diff --git a/config/filter.d/apache-modsecurity.conf b/config/filter.d/apache-modsecurity.conf index ad7e9b24..e296227a 100644 --- a/config/filter.d/apache-modsecurity.conf +++ b/config/filter.d/apache-modsecurity.conf @@ -10,9 +10,10 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s ModSecurity: (\[.*?\] )*Access denied with code [45]\d\d.*$ +failregex = ^%(_apache_error_client)s 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/config/filter.d/apache-overflows.conf b/config/filter.d/apache-overflows.conf index 74e44b8e..02a2ef20 100644 --- a/config/filter.d/apache-overflows.conf +++ b/config/filter.d/apache-overflows.conf @@ -8,11 +8,15 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s ((AH0013[456]: )?Invalid (method|URI) in request .*( - possible attempt to establish SSL connection on non-SSL port)?|(AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string: .*|AH00566: request failed: invalid characters in URI)(, referer: \S+)?$ +failregex = ^%(_apache_error_client)s (?:(?:AH0013[456]: )?Invalid (method|URI) in request\b|(?:AH00565: )?request failed: URI too long \(longer than \d+\)|request failed: erroneous characters after protocol string:|(?:AH00566: )?request failed: invalid characters in URI\b) ignoreregex = # DEV Notes: +# +# [sebres] Because this apache-log could contain very long URLs (and/or referrer), +# the parsing of it anchored way may be very vulnerable (at least as regards +# the system resources, see gh-1790). Thus rewritten without end-anchor ($). # # fgrep -r 'URI too long' httpd-2.* # httpd-2.2.25/server/protocol.c: "request failed: URI too long (longer than %d)", r->server->limit_req_line); diff --git a/config/filter.d/apache-shellshock.conf b/config/filter.d/apache-shellshock.conf index 39df1704..e2707dc0 100644 --- a/config/filter.d/apache-shellshock.conf +++ b/config/filter.d/apache-shellshock.conf @@ -9,8 +9,10 @@ before = apache-common.conf [Definition] -failregex = ^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: warning: HTTP_.*?: ignoring function definition attempt(, referer: \S+)?\s*$ - ^%(_apache_error_client)s (AH01215: )?/bin/(ba)?sh: error importing function definition for `HTTP_.*?'(, referer: \S+)?\s*$ +prefregex = ^%(_apache_error_client)s (AH01215: )?/bin/([bd]a)?sh: <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^warning: HTTP_[^:]+: ignoring function definition attempt(, referer: \S+)?\s*$ + ^error importing function definition for `HTTP_[^']+'(, referer: \S+)?\s*$ ignoreregex = diff --git a/config/filter.d/assp.conf b/config/filter.d/assp.conf index 7cca81d2..9837f71d 100644 --- a/config/filter.d/assp.conf +++ b/config/filter.d/assp.conf @@ -8,7 +8,7 @@ # [Definition] -# Note: First three failregex matches below are for ASSP V1 with the remaining being designed for V2. Deleting the V1 regex is recommended but I left it in for compatibilty reasons. +# Note: First three failregex matches below are for ASSP V1 with the remaining being designed for V2. Deleting the V1 regex is recommended but I left it in for compatibility reasons. __assp_actions = (?:dropping|refusing) diff --git a/config/filter.d/asterisk.conf b/config/filter.d/asterisk.conf index df55d288..f382e258 100644 --- a/config/filter.d/asterisk.conf +++ b/config/filter.d/asterisk.conf @@ -11,23 +11,27 @@ before = common.conf _daemon = asterisk -__pid_re = (?:\[\d+\]) +__pid_re = (?:\s*\[\d+\]) iso8601 = \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{4} # All Asterisk log messages begin like this: log_prefix= (?:NOTICE|SECURITY|WARNING)%(__pid_re)s:?(?:\[C-[\da-f]*\])? [^:]+:\d*(?:(?: in)? \w+:)? -failregex = ^%(__prefix_line)s%(log_prefix)s Registration from '[^']*' failed for '<HOST>(:\d+)?' - (Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$ - ^%(__prefix_line)s%(log_prefix)s Call from '[^']*' \(<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context - ^%(__prefix_line)s%(log_prefix)s Host <HOST> failed to authenticate as '[^']*'$ - ^%(__prefix_line)s%(log_prefix)s No registration for peer '[^']*' \(from <HOST>\)$ - ^%(__prefix_line)s%(log_prefix)s Host <HOST> failed MD5 authentication for '[^']*' \([^)]+\)$ - ^%(__prefix_line)s%(log_prefix)s Failed to authenticate (user|device) [^@]+@<HOST>\S*$ - ^%(__prefix_line)s%(log_prefix)s hacking attempt detected '<HOST>'$ - ^%(__prefix_line)s%(log_prefix)s SecurityEvent="(FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)",EventTV="([\d-]+|%(iso8601)s)",Severity="[\w]+",Service="[\w]+",EventVersion="\d+",AccountID="(\d*|<unknown>)",SessionID=".+",LocalAddress="IPV[46]/(UDP|TCP|WS)/[\da-fA-F:.]+/\d+",RemoteAddress="IPV[46]/(UDP|TCP|WS)/<HOST>/\d+"(,Challenge="[\w/]+")?(,ReceivedChallenge="\w+")?(,Response="\w+",ExpectedResponse="\w*")?(,ReceivedHash="[\da-f]+")?(,ACLName="\w+")?$ - ^%(__prefix_line)s%(log_prefix)s "Rejecting unknown SIP connection from <HOST>"$ - ^%(__prefix_line)s%(log_prefix)s Request (?:'[^']*' )?from '[^']*' failed for '<HOST>(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ +prefregex = ^%(__prefix_line)s%(log_prefix)s <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^Registration from '[^']*' failed for '<HOST>(:\d+)?' - (?:Wrong password|Username/auth name mismatch|No matching peer found|Not a local domain|Device does not match ACL|Peer is not supposed to register|ACL error \(permit/deny\)|Not a local domain)$ + ^Call from '[^']*' \(<HOST>:\d+\) to extension '[^']*' rejected because extension not found in context + ^(?:Host )?<HOST> (?:failed (?:to authenticate\b|MD5 authentication\b)|tried to authenticate with nonexistent user\b) + ^No registration for peer '[^']*' \(from <HOST>\)$ + ^Failed to authenticate (?:user|device) [^@]+@<HOST>\S*$ + ^hacking attempt detected '<HOST>'$ + ^SecurityEvent="(?:FailedACL|InvalidAccountID|ChallengeResponseFailed|InvalidPassword)"(?:(?:,(?!RemoteAddress=)\w+="[^"]*")*|.*?),RemoteAddress="IPV[46]/(UDP|TCP|WS)/<HOST>/\d+"(?:,(?!RemoteAddress=)\w+="[^"]*")*$ + ^"Rejecting unknown SIP connection from <HOST>"$ + ^Request (?:'[^']*' )?from '[^']*' failed for '<HOST>(?::\d+)?'\s\(callid: [^\)]*\) - (?:No matching endpoint found|Not match Endpoint(?: Contact)? ACL|(?:Failed|Error) to authenticate)\s*$ + +# FreePBX (todo: make optional in v.0.10): +# ^(%(__prefix_line)s|\[\]\s*WARNING%(__pid_re)s:?(?:\[C-[\da-f]*\])? )[^:]+: Friendly Scanner from <HOST>$ ignoreregex = diff --git a/config/filter.d/botsearch-common.conf b/config/filter.d/botsearch-common.conf index a673a310..6052fab1 100644 --- a/config/filter.d/botsearch-common.conf +++ b/config/filter.d/botsearch-common.conf @@ -5,7 +5,7 @@ # Block is the actual non-found directories to block block = \/?(<webmail>|<phpmyadmin>|<wordpress>|cgi-bin|mysqladmin)[^,]* -# These are just convient definitions that assist the blocking of stuff that +# These are just convenient definitions that assist the blocking of stuff that # isn't installed webmail = roundcube|(ext)?mail|horde|(v-?)?webmail diff --git a/config/filter.d/courier-auth.conf b/config/filter.d/courier-auth.conf index 87ee55b4..1ac33736 100644 --- a/config/filter.d/courier-auth.conf +++ b/config/filter.d/courier-auth.conf @@ -11,7 +11,7 @@ before = common.conf _daemon = (?:courier)?(?:imapd?|pop3d?)(?:login)?(?:-ssl)? -failregex = ^%(__prefix_line)sLOGIN FAILED, user=.*, ip=\[<HOST>\]$ +failregex = ^%(__prefix_line)sLOGIN FAILED, (?:user|method)=.*, ip=\[<HOST>\]$ ignoreregex = diff --git a/config/filter.d/courier-smtp.conf b/config/filter.d/courier-smtp.conf index fc0afc26..888753c4 100644 --- a/config/filter.d/courier-smtp.conf +++ b/config/filter.d/courier-smtp.conf @@ -12,8 +12,10 @@ before = common.conf _daemon = courieresmtpd -failregex = ^%(__prefix_line)serror,relay=<HOST>,.*: 550 User (<.*> )?unknown\.?$ - ^%(__prefix_line)serror,relay=<HOST>,msg="535 Authentication failed\.",cmd:( AUTH \S+)?( [0-9a-zA-Z\+/=]+)?(?: \S+)$ +prefregex = ^%(__prefix_line)serror,relay=<HOST>,<F-CONTENT>.+</F-CONTENT>$ + +failregex = ^[^:]*: 550 User (<.*> )?unknown\.?$ + ^msg="535 Authentication failed\.",cmd:( AUTH \S+)?( [0-9a-zA-Z\+/=]+)?(?: \S+)$ ignoreregex = diff --git a/config/filter.d/cyrus-imap.conf b/config/filter.d/cyrus-imap.conf index 73764d9d..31dfda60 100644 --- a/config/filter.d/cyrus-imap.conf +++ b/config/filter.d/cyrus-imap.conf @@ -13,7 +13,7 @@ before = common.conf _daemon = (?:cyrus/)?(?:imap(d|s)?|pop3(d|s)?) -failregex = ^%(__prefix_line)sbadlogin: \S+ ?\[<HOST>\] \S+ .*?\[?SASL\(-13\): (authentication failure|user not found): .*\]?$ +failregex = ^%(__prefix_line)sbadlogin: [^\[]*\[<HOST>\] \S+ .*?\[?SASL\(-13\): (authentication failure|user not found): .*\]?$ ignoreregex = diff --git a/config/filter.d/domino-smtp.conf b/config/filter.d/domino-smtp.conf new file mode 100644 index 00000000..cdc17736 --- /dev/null +++ b/config/filter.d/domino-smtp.conf @@ -0,0 +1,47 @@ +# Fail2Ban configuration file for IBM Domino SMTP Server TASK to detect failed login attempts +# +# Author: Christian Brandlehner +# +# $Revision: 003 $ +# +# Configuration: +# Set the following Domino Server parameters in notes.ini: +# console_log_enabled=1 +# log_sessions=2 +# You also have to use a date and time format supported by fail2ban. Recommended notes.ini configuration is: +# DateOrder=DMY +# DateSeparator=- +# ClockType=24_Hour +# TimeSeparator=: +# +# Depending on your locale you might have to tweak the date and time format so fail2ban can read the log + +#[INCLUDES] +# Read common prefixes. If any customizations available -- read them from +# common.local +#before = common.conf + +[Definition] +# Option: failregex +# Notes.: regex to match the password failure messages in the logfile. 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>\S+) +# Values: TEXT +# +# Sample log entries (used different time formats and an extra sample with process info in front of date) +# 01-23-2009 19:54:51 SMTP Server: Authentication failed for user postmaster ; connecting host 1.2.3.4 +# [28325:00010-3735542592] 22-06-2014 09:56:12 smtp: postmaster [1.2.3.4] authentication failure using internet password +# 08-09-2014 06:14:27 smtp: postmaster [1.2.3.4] authentication failure using internet password +# 08-09-2014 06:14:27 SMTP Server: Authentication failed for user postmaster ; connecting host 1.2.3.4 + +__prefix = (?:\[[^\]]+\])?\s+ +failregex = ^%(__prefix)sSMTP Server: Authentication failed for user .*? \; connecting host <HOST>$ + ^%(__prefix)ssmtp: (?:[^\[]+ )*\[<HOST>\] authentication failure using internet password\s*$ +# Option: ignoreregex +# Notes.: regex to ignore. If this regex matches, the line is ignored. +# Values: TEXT +# + +ignoreregex = + diff --git a/config/filter.d/dovecot.conf b/config/filter.d/dovecot.conf index 6f8510fc..42ab2c88 100644 --- a/config/filter.d/dovecot.conf +++ b/config/filter.d/dovecot.conf @@ -7,13 +7,15 @@ before = common.conf [Definition] -_daemon = (auth|dovecot(-auth)?|auth-worker) +_auth_worker = (?:dovecot: )?auth(?:-worker)? +_daemon = (dovecot(-auth)?|auth) -failregex = ^%(__prefix_line)s(%(__pam_auth)s(\(dovecot:auth\))?:)?\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(\s+user=\S*)?\s*$ - ^%(__prefix_line)s(pop3|imap)-login: (Info: )?(Aborted login|Disconnected)(: Inactivity)? \(((auth failed, \d+ attempts)( in \d+ secs)?|tried to use (disabled|disallowed) \S+ auth)\):( user=<\S*>,)?( method=\S+,)? rip=<HOST>(, lip=(\d{1,3}\.){3}\d{1,3})?(, TLS( handshaking(: SSL_accept\(\) failed: error:[\dA-F]+:SSL routines:[TLS\d]+_GET_CLIENT_HELLO:unknown protocol)?)?(: Disconnected)?)?(, session=<\S+>)?\s*$ - ^%(__prefix_line)s(Info|dovecot: auth\(default\)|auth-worker\(\d+\)): pam\(\S+,<HOST>\): pam_authenticate\(\) failed: (User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$ - ^%(__prefix_line)s(auth|auth-worker\(\d+\)): (pam|passwd-file)\(\S+,<HOST>\): unknown user\s*$ - ^%(__prefix_line)s(auth|auth-worker\(\d+\)): Info: ldap\(\S*,<HOST>,\S*\): invalid credentials\s*$ +prefregex = ^%(__prefix_line)s(%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_auth)s(?:\(dovecot:auth\))?: |(?:pop3|imap)-login: )?(?:Info: )?<F-CONTENT>.+</F-CONTENT>$ + +failregex = ^authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=<HOST>(?:\s+user=\S*)?\s*$ + ^(?:Aborted login|Disconnected)(?::(?: [^ \(]+)+)? \((?:auth failed, \d+ attempts( in \d+ secs)?|tried to use (disabled|disallowed) \S+ auth)\):( user=<[^>]*>,)?( method=\S+,)? rip=<HOST>(?:, lip=\S+)?(?:, TLS(?: handshaking(?:: SSL_accept\(\) failed: error:[\dA-F]+:SSL routines:[TLS\d]+_GET_CLIENT_HELLO:unknown protocol)?)?(: Disconnected)?)?(, session=<\S+>)?\s*$ + ^pam\(\S+,<HOST>\): pam_authenticate\(\) failed: (User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$ + ^[a-z\-]{3,15}\(\S*,<HOST>(?:,\S*)?\): (?:unknown user|invalid credentials)\s*$ ignoreregex = @@ -31,3 +33,4 @@ datepattern = {^LN-BEG}TAI64N # Author: Martin Waschbuesch # Daniel Black (rewrote with begin and end anchors) # Martin O'Neal (added LDAP authentication failure regex) +# Sergey G. Brester aka sebres (reviewed, optimized, IPv6-compatibility) diff --git a/config/filter.d/dropbear.conf b/config/filter.d/dropbear.conf index 288b0882..930bb128 100644 --- a/config/filter.d/dropbear.conf +++ b/config/filter.d/dropbear.conf @@ -23,9 +23,11 @@ before = common.conf _daemon = dropbear -failregex = ^%(__prefix_line)s[Ll]ogin attempt for nonexistent user ('.*' )?from <HOST>:\d+$ - ^%(__prefix_line)s[Bb]ad (PAM )?password attempt for .+ from <HOST>(:\d+)?$ - ^%(__prefix_line)s[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from <HOST>:\d+\s*$ +prefregex = ^%(__prefix_line)s<F-CONTENT>(?:[Ll]ogin|[Bb]ad|[Ee]xit).+</F-CONTENT>$ + +failregex = ^[Ll]ogin attempt for nonexistent user ('.*' )?from <HOST>:\d+$ + ^[Bb]ad (PAM )?password attempt for .+ from <HOST>(:\d+)?$ + ^[Ee]xit before auth \(user '.+', \d+ fails\): Max auth tries reached - user '.+' from <HOST>:\d+\s*$ ignoreregex = diff --git a/config/filter.d/ejabberd-auth.conf b/config/filter.d/ejabberd-auth.conf index 56517489..48e82df5 100644 --- a/config/filter.d/ejabberd-auth.conf +++ b/config/filter.d/ejabberd-auth.conf @@ -16,8 +16,8 @@ # searched for other failures. This tag can be used multiple times. # Values: TEXT # -failregex = ^=INFO REPORT==== ===\nI\(<0\.\d+\.0>:ejabberd_c2s:\d+\) : \([^)]+\) Failed authentication for .+ from IP <HOST> \({{(?:\d+,){3}\d+},\d+}\)$ - ^(?:\.\d+)? \[info\] <0\.\d+\.\d>@ejabberd_c2s:wait_for_feature_request:\d+ \([^\)]+\) Failed authentication for \S+ from IP <HOST>$ +failregex = ^=INFO REPORT==== ===\nI\(<0\.\d+\.0>:ejabberd_c2s:\d+\) : \([^)]+\) Failed authentication for \S+ from (?:IP )?<HOST>(?: \({{(?:\d+,){3}\d+},\d+}\))?$ + ^(?:\.\d+)? \[info\] <0\.\d+\.\d>@ejabberd_c2s:\w+:\d+ \([^\)]+\) Failed (?:c2s \w+ )?authentication for \S+ from (?:IP )?(?:::FFFF:)?<HOST>(?:: |$) # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. diff --git a/config/filter.d/exim-common.conf b/config/filter.d/exim-common.conf index 0e1b74fa..b3b25750 100644 --- a/config/filter.d/exim-common.conf +++ b/config/filter.d/exim-common.conf @@ -9,7 +9,9 @@ after = exim-common.local [Definition] -host_info = (?:H=([\w.-]+ )?(?:\(\S+\) )?)?\[<HOST>\](?::\d+)? (?:I=\[\S+\](:\d+)? )?(?:U=\S+ )?(?:P=e?smtp )? +host_info_pre = (?:H=([\w.-]+ )?(?:\(\S+\) )?)? +host_info_suf = (?::\d+)?(?: I=\[\S+\](:\d+)?)?(?: U=\S+)?(?: P=e?smtp)?(?: F=(?:<>|[^@]+@\S+))?\s +host_info = %(host_info_pre)s\[<HOST>\]%(host_info_suf)s pid = (?: \[\d+\])? # DEV Notes: diff --git a/config/filter.d/exim.conf b/config/filter.d/exim.conf index a1d699c0..2151a161 100644 --- a/config/filter.d/exim.conf +++ b/config/filter.d/exim.conf @@ -13,14 +13,17 @@ before = exim-common.conf [Definition] +# Fre-filter via "prefregex" is currently inactive because of too different failure syntax in exim-log (testing needed): +#prefregex = ^%(pid)s <F-CONTENT>\b(?:\w+ authenticator failed|([\w\-]+ )?SMTP (?:(?:call|connection) from|protocol(?: synchronization)? error)|no MAIL in|(?:%(host_info_pre)s\[[^\]]+\]%(host_info_suf)s(?:sender verify fail|rejected RCPT|dropped|AUTH command))).+</F-CONTENT>$ + failregex = ^%(pid)s %(host_info)ssender verify fail for <\S+>: (?:Unknown user|Unrouteable address|all relevant MX records point to non-existent hosts)\s*$ - ^%(pid)s \w+ authenticator failed for (\S+ )?\(\S+\) \[<HOST>\](?::\d+)?(?: I=\[\S+\](:\d+)?)?: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$ - ^%(pid)s %(host_info)sF=(?:<>|[^@]+@\S+) rejected RCPT [^@]+@\S+: (?:relay not permitted|Sender verify failed|Unknown user)\s*$ + ^%(pid)s \w+ authenticator failed for (?:[^\[\( ]* )?(?:\(\S*\) )?\[<HOST>\](?::\d+)?(?: I=\[\S+\](:\d+)?)?: 535 Incorrect authentication data( \(set_id=.*\)|: \d+ Time\(s\))?\s*$ + ^%(pid)s %(host_info)srejected RCPT [^@]+@\S+: (?:relay not permitted|Sender verify failed|Unknown user|Unrouteable address)\s*$ ^%(pid)s SMTP protocol synchronization error \([^)]*\): rejected (?:connection from|"\S+") %(host_info)s(?:next )?input=".*"\s*$ ^%(pid)s SMTP call from \S+ %(host_info)sdropped: too many nonmail commands \(last was "\S+"\)\s*$ ^%(pid)s SMTP protocol error in "AUTH \S*(?: \S*)?" %(host_info)sAUTH command used when not advertised\s*$ - ^%(pid)s no MAIL in SMTP connection from (?:\S* )?(?:\(\S*\) )?%(host_info)sD=\d+s(?: C=\S*)?\s*$ - ^%(pid)s \S+ SMTP connection from (?:\S* )?(?:\(\S*\) )?%(host_info)sclosed by DROP in ACL\s*$ + ^%(pid)s no MAIL in SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sD=\d\S+s(?: C=\S*)?\s*$ + ^%(pid)s (?:[\w\-]+ )?SMTP connection from (?:[^\[\( ]* )?(?:\(\S*\) )?%(host_info)sclosed by DROP in ACL\s*$ ignoreregex = diff --git a/config/filter.d/froxlor-auth.conf b/config/filter.d/froxlor-auth.conf index 04003263..d8f3785c 100644 --- a/config/filter.d/froxlor-auth.conf +++ b/config/filter.d/froxlor-auth.conf @@ -25,8 +25,11 @@ _daemon = Froxlor # (?:::f{4,6}:)?(?P<host>[\w\-.^_]+) # Values: TEXT # -failregex = ^%(__prefix_line)s\[Login Action <HOST>\] Unknown user \S* tried to login.$ - ^%(__prefix_line)s\[Login Action <HOST>\] User \S* tried to login with wrong password.$ + +prefregex = ^%(__prefix_line)s\[Login Action <HOST>\] <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^Unknown user \S* tried to login.$ + ^User \S* tried to login with wrong password.$ # Option: ignoreregex diff --git a/config/filter.d/haproxy-http-auth.conf b/config/filter.d/haproxy-http-auth.conf index 298ca292..f92f9d67 100644 --- a/config/filter.d/haproxy-http-auth.conf +++ b/config/filter.d/haproxy-http-auth.conf @@ -28,7 +28,7 @@ _daemon = haproxy # (?:::f{4,6}:)?(?P<host>[\w\-.^_]+) # Values: TEXT # -failregex = ^%(__prefix_line)s<HOST>.*<NOSRV> -1/-1/-1/-1/\+*\d* 401 +failregex = ^%(__prefix_line)s<HOST>(?::\d+)?\s+.*<NOSRV> -1/-1/-1/-1/\+*\d* 401 # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. diff --git a/config/filter.d/kerio.conf b/config/filter.d/kerio.conf index e0d94753..0fde0927 100644 --- a/config/filter.d/kerio.conf +++ b/config/filter.d/kerio.conf @@ -3,9 +3,14 @@ [Definition] failregex = ^ SMTP Spam attack detected from <HOST>, - ^ IP address <HOST> found in DNS blacklist \S+, mail from \S+ to \S+$ + ^ IP address <HOST> found in DNS blacklist ^ Relay attempt from IP address <HOST> ^ Attempt to deliver to unknown recipient \S+, from \S+, IP address <HOST>$ + ^ Failed SMTP login from <HOST> + ^ SMTP: User \S+ doesn't exist. Attempt from IP address <HOST> + ^ Client with IP address <HOST> has no reverse DNS entry, connection rejected before SMTP greeting$ + ^ Administration login into Web Administration from <HOST> failed: IP address not allowed$ + ^ Message from IP address <HOST>, sender \S+ rejected: sender domain does not exist$ ignoreregex = @@ -14,5 +19,6 @@ datepattern = ^\[%%d/%%b/%%Y %%H:%%M:%%S\] # DEV NOTES: # # Author: A.P. Lawrence +# Updated by: M. Bischoff <https://github.com/herrbischoff> # # Based off: http://aplawrence.com/Kerio/fail2ban.html diff --git a/config/filter.d/mongodb-auth.conf b/config/filter.d/mongodb-auth.conf new file mode 100644 index 00000000..66c27abb --- /dev/null +++ b/config/filter.d/mongodb-auth.conf @@ -0,0 +1,49 @@ +# Fail2Ban filter for unsuccesfull MongoDB authentication attempts +# +# Logfile /var/log/mongodb/mongodb.log +# +# add setting in /etc/mongodb.conf +# logpath=/var/log/mongodb/mongodb.log +# +# and use of the authentication +# auth = true +# + +[Definition] +#failregex = ^\s+\[initandlisten\] connection accepted from <HOST>:\d+ \#(?P<__connid>\d+) \(1 connection now open\)<SKIPLINES>\s+\[conn(?P=__connid)\] Failed to authenticate\s+ +failregex = ^\s+\[conn(?P<__connid>\d+)\] Failed to authenticate [^\n]+<SKIPLINES>\s+\[conn(?P=__connid)\] end connection <HOST> + +ignoreregex = + + +[Init] +maxlines = 10 + +# DEV Notes: +# +# Regarding the multiline regex: +# +# There can be a nunber of non-related lines between the first and second part +# of this regex maxlines of 10 is quite generious. +# +# Note the capture __connid, includes the connection ID, used in second part of regex. +# +# The first regex is commented out (but will match also), because it is better to use +# the host from "end connection" line (uncommented above): +# - it has the same prefix, searching begins directly with failure message +# (so faster, because ignores success connections at all) +# - it is not so vulnerable in case of possible race condition +# +# Log example: +# 2016-10-20T09:54:27.108+0200 [initandlisten] connection accepted from 127.0.0.1:53276 #1 (1 connection now open) +# 2016-10-20T09:54:27.109+0200 [conn1] authenticate db: test { authenticate: 1, nonce: "xxx", user: "root", key: "xxx" } +# 2016-10-20T09:54:27.110+0200 [conn1] Failed to authenticate root@test with mechanism MONGODB-CR: AuthenticationFailed UserNotFound Could not find user root@test +# 2016-11-09T09:54:27.894+0100 [conn1] end connection 127.0.0.1:53276 (0 connections now open) +# 2016-11-09T11:55:58.890+0100 [initandlisten] connection accepted from 127.0.0.1:54266 #1510 (1 connection now open) +# 2016-11-09T11:55:58.892+0100 [conn1510] authenticate db: admin { authenticate: 1, nonce: "xxx", user: "root", key: "xxx" } +# 2016-11-09T11:55:58.892+0100 [conn1510] Failed to authenticate root@admin with mechanism MONGODB-CR: AuthenticationFailed key mismatch +# 2016-11-09T11:55:58.894+0100 [conn1510] end connection 127.0.0.1:54266 (0 connections now open) +# +# Authors: Alexander Finkhäuser +# Sergey G. Brester (sebres) + diff --git a/config/filter.d/murmur.conf b/config/filter.d/murmur.conf index 507bbd2f..f5f100a6 100644 --- a/config/filter.d/murmur.conf +++ b/config/filter.d/murmur.conf @@ -17,8 +17,10 @@ _usernameregex = [^>]+ _prefix = \s+\d+ => <\d+:%(_usernameregex)s\(-1\)> Rejected connection from <HOST>:\d+: -failregex = ^%(_prefix)s Invalid server password$ - ^%(_prefix)s Wrong certificate or password for existing user$ +prefregex = ^%(_prefix)s <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^Invalid server password$ + ^Wrong certificate or password for existing user$ ignoreregex = diff --git a/config/filter.d/mysqld-auth.conf b/config/filter.d/mysqld-auth.conf index 3ad70cb7..31bd2056 100644 --- a/config/filter.d/mysqld-auth.conf +++ b/config/filter.d/mysqld-auth.conf @@ -1,4 +1,4 @@ -# Fail2Ban filter for unsuccesfull MySQL authentication attempts +# Fail2Ban filter for unsuccesful MySQL authentication attempts # # # To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld]: diff --git a/config/filter.d/named-refused.conf b/config/filter.d/named-refused.conf index eec3d667..2e14d442 100644 --- a/config/filter.d/named-refused.conf +++ b/config/filter.d/named-refused.conf @@ -34,9 +34,11 @@ __daemon_combs_re=(?:%(__pid_re)s?:\s+%(__daemon_re)s|%(__daemon_re)s%(__pid_re) # this can be optional (for instance if we match named native log files) __line_prefix=(?:\s\S+ %(__daemon_combs_re)s\s+)? -failregex = ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: (view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$ - ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: zone transfer '\S+/AXFR/\w+' denied\s*$ - ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$ +prefregex = ^%(__line_prefix)s( error:)?\s*client <HOST>#\S+( \([\S.]+\))?: <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^(view (internal|external): )?query(?: \(cache\))? '.*' denied\s*$ + ^zone transfer '\S+/AXFR/\w+' denied\s*$ + ^bad zone transfer request: '\S+/IN': non-authoritative zone \(NOTAUTH\)\s*$ ignoreregex = diff --git a/config/filter.d/pam-generic.conf b/config/filter.d/pam-generic.conf index e0d4e9c1..ff4ea802 100644 --- a/config/filter.d/pam-generic.conf +++ b/config/filter.d/pam-generic.conf @@ -16,7 +16,12 @@ _ttys_re=\S* __pam_re=\(?%(__pam_auth)s(?:\(\S+\))?\)?:? _daemon = \S+ -failregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s ruser=\S* rhost=<HOST>(?:\s+user=.*)?\s*$ +prefregex = ^%(__prefix_line)s%(__pam_re)s\s+authentication failure; logname=\S* uid=\S* euid=\S* tty=%(_ttys_re)s <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^ruser=<F-USER>\S*</F-USER> rhost=<HOST>\s*$ + ^ruser= rhost=<HOST>\s+user=<F-USER>\S*</F-USER>\s*$ + ^ruser= rhost=<HOST>\s+user=<F-USER>.*?</F-USER>\s*$ + ^ruser=<F-USER>.*?</F-USER> rhost=<HOST>\s*$ ignoreregex = diff --git a/config/filter.d/postfix-rbl.conf b/config/filter.d/postfix-rbl.conf deleted file mode 100644 index c3f8c332..00000000 --- a/config/filter.d/postfix-rbl.conf +++ /dev/null @@ -1,19 +0,0 @@ -# Fail2Ban filter for Postfix's RBL based Blocked hosts -# -# - -[INCLUDES] - -# Read common prefixes. If any customizations available -- read them from -# common.local -before = common.conf - -[Definition] - -_daemon = postfix(-\w+)?/smtpd - -failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 454 4\.7\.1 Service unavailable; Client host \[\S+\] blocked using .* from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$ - -ignoreregex = - -# Author: Lee Clemens diff --git a/config/filter.d/postfix-sasl.conf b/config/filter.d/postfix-sasl.conf deleted file mode 100644 index 1a24ca94..00000000 --- a/config/filter.d/postfix-sasl.conf +++ /dev/null @@ -1,21 +0,0 @@ -# Fail2Ban filter for postfix authentication failures -# - -[INCLUDES] - -before = common.conf - -[Definition] - -_daemon = postfix(-\w+)?/(?:submission/|smtps/)?smtp[ds] - -failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(:[ A-Za-z0-9+/:]*={0,2})?\s*$ - -ignoreregex = authentication failed: Connection lost to authentication server$ - -[Init] - -journalmatch = _SYSTEMD_UNIT=postfix.service - - -# Author: Yaroslav Halchenko diff --git a/config/filter.d/postfix.conf b/config/filter.d/postfix.conf index 3051409b..b86b3d4d 100644 --- a/config/filter.d/postfix.conf +++ b/config/filter.d/postfix.conf @@ -10,15 +10,57 @@ before = common.conf [Definition] -_daemon = postfix(-\w+)?/(?:submission/|smtps/)?smtp[ds] - -failregex = ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 554 5\.7\.1 .*$ - ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 Client host rejected: cannot find your hostname, (\[\S*\]); from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$ - ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.7\.1 : Helo command rejected: Host not found; from=<> to=<> proto=ESMTP helo= *$ - ^%(__prefix_line)sNOQUEUE: reject: EHLO from \S+\[<HOST>\]: 504 5\.5\.2 <\S+>: Helo command rejected: need fully-qualified hostname; - ^%(__prefix_line)sNOQUEUE: reject: VRFY from \S+\[<HOST>\]: 550 5\.1\.1 .*$ - ^%(__prefix_line)sNOQUEUE: reject: RCPT from \S+\[<HOST>\]: 450 4\.1\.8 <\S*>: Sender address rejected: Domain not found; from=<\S*> to=<\S+> proto=ESMTP helo=<\S*>$ - ^%(__prefix_line)simproper command pipelining after \S+ from [^[]*\[<HOST>\]:?$ +_daemon = postfix(-\w+)?/\w+(?:/smtp[ds])? +_port = (?::\d+)? + +prefregex = ^%(__prefix_line)s<mdpr-<mode>> <F-CONTENT>.+</F-CONTENT>$ + +mdpr-normal = (?:NOQUEUE: reject:|improper command pipelining after \S+) +mdre-normal=^RCPT from [^[]*\[<HOST>\]<_port>: 55[04] 5\.7\.1\s + ^RCPT from [^[]*\[<HOST>\]<_port>: 45[04] 4\.7\.1 (?:Service unavailable\b|Client host rejected: cannot find your (reverse )?hostname\b) + ^RCPT from [^[]*\[<HOST>\]<_port>: 450 4\.7\.1 (<[^>]*>)?: Helo command rejected: Host not found\b + ^EHLO from [^[]*\[<HOST>\]<_port>: 504 5\.5\.2 (<[^>]*>)?: Helo command rejected: need fully-qualified hostname\b + ^VRFY from [^[]*\[<HOST>\]<_port>: 550 5\.1\.1\s + ^RCPT from [^[]*\[<HOST>\]<_port>: 450 4\.1\.8 (<[^>]*>)?: Sender address rejected: Domain not found\b + ^from [^[]*\[<HOST>\]:? + +mdpr-auth = warning: +mdre-auth = ^[^[]*\[<HOST>\]: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server| Invalid authentication mechanism) +mdre-auth2= ^[^[]*\[<HOST>\]: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed:(?! Connection lost to authentication server) +# todo: check/remove "Invalid authentication mechanism" from ignore list, if gh-1243 will get finished (see gh-1297). + +# Mode "rbl" currently included in mode "normal", but if needed for jail "postfix-rbl" only: +mdpr-rbl = %(mdpr-normal)s +mdre-rbl = ^RCPT from [^[]*\[<HOST>\]: [45]54 [45]\.7\.1 Service unavailable; Client host \[\S+\] blocked\b + +# Mode "rbl" currently included in mode "normal" (within 1st rule) +mdpr-more = %(mdpr-normal)s +mdre-more = %(mdre-normal)s + +mdpr-ddos = lost connection after(?! DATA) [A-Z]+ +mdre-ddos = ^from [^[]*\[<HOST>\]:? + +mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s) +mdre-extra = %(mdre-auth)s + %(mdre-normal)s + +mdpr-aggressive = (?:%(mdpr-auth)s|%(mdpr-normal)s|%(mdpr-ddos)s) +mdre-aggressive = %(mdre-auth2)s + %(mdre-normal)s + + + +failregex = <mdre-<mode>> + +# Parameter "mode": more (default combines normal and rbl), auth, normal, rbl, ddos, extra or aggressive (combines all) +# Usage example (for jail.local): +# [postfix] +# mode = aggressive +# # or another jail (rewrite filter parameters of jail): +# [postfix-rbl] +# filter = postfix[mode=rbl] +# +mode = more ignoreregex = diff --git a/config/filter.d/proftpd.conf b/config/filter.d/proftpd.conf index 4bc0ba01..a7bd2837 100644 --- a/config/filter.d/proftpd.conf +++ b/config/filter.d/proftpd.conf @@ -16,12 +16,19 @@ _daemon = proftpd __suffix_failed_login = (User not authorized for login|No such user found|Incorrect password|Password expired|Account disabled|Invalid shell: '\S+'|User in \S+|Limit (access|configuration) denies login|Not a UserAlias|maximum login length exceeded).? -failregex = ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ USER .*: no such user found from \S+ \[\S+\] to \S+:\S+ *$ - ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ USER .* \(Login failed\): %(__suffix_failed_login)s\s*$ - ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ SECURITY VIOLATION: .* login attempted\. *$ - ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ Maximum login attempts \(\d+\) exceeded *$ + +prefregex = ^%(__prefix_line)s%(__hostname)s \(\S+\[<HOST>\]\)[: -]+ <F-CONTENT>(?:USER|SECURITY|Maximum).+</F-CONTENT>$ + + +failregex = ^USER .*: no such user found from \S+ \[\S+\] to \S+:\S+ *$ + ^USER .* \(Login failed\): %(__suffix_failed_login)s\s*$ + ^SECURITY VIOLATION: .* login attempted\. *$ + ^Maximum login attempts \(\d+\) exceeded *$ ignoreregex = +[Init] +journalmatch = _SYSTEMD_UNIT=proftpd.service + # Author: Yaroslav Halchenko # Daniel Black - hardening of regex diff --git a/config/filter.d/roundcube-auth.conf b/config/filter.d/roundcube-auth.conf index 886cf2d6..9912ff47 100644 --- a/config/filter.d/roundcube-auth.conf +++ b/config/filter.d/roundcube-auth.conf @@ -13,10 +13,15 @@ before = common.conf [Definition] -failregex = ^\s*(\[\])?(%(__hostname)s\s*(roundcube:)?\s*(<[\w]+>)? IMAP Error)?: (FAILED login|Login failed) for .*? from <HOST>(\. .* in .*?/rcube_imap\.php on line \d+ \(\S+ \S+\))?$ - ^\[\]:\s*(<[\w]+>)? Failed login for [\w\-\.\+]+(@[\w\-\.\+]+\.[a-zA-Z]{2,6})? from <HOST> in session \w+( \(error: \d\))?$ +prefregex = ^\s*(\[\])?(%(__hostname)s\s*(?:roundcube(?:\[(\d*)\])?:)?\s*(<[\w]+>)? IMAP Error)?: <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^(?:FAILED login|Login failed) for <F-USER>.*</F-USER> from <HOST>(?:(?:\([^\)]*\))?\. (?:(?! from ).)*(?: user=(?P=user))? in \S+\.php on line \d+ \(\S+ \S+\))?$ + ^(?:<[\w]+> )?Failed login for <F-USER>.*</F-USER> from <HOST> in session \w+( \(error: \d\))?$ ignoreregex = + +journalmatch = SYSLOG_IDENTIFIER=roundcube + # DEV Notes: # # Source: https://github.com/roundcube/roundcubemail/blob/master/program/lib/Roundcube/rcube_imap.php#L180 diff --git a/config/filter.d/sendmail-reject.conf b/config/filter.d/sendmail-reject.conf index 20d3648e..0793a99b 100644 --- a/config/filter.d/sendmail-reject.conf +++ b/config/filter.d/sendmail-reject.conf @@ -21,30 +21,45 @@ before = common.conf _daemon = (?:(sm-(mta|acceptingconnections)|sendmail)) -failregex = ^%(__prefix_line)s\w{14}: ruleset=check_rcpt, arg1=(?P<email><\S+@\S+>), relay=(\S+ )?\[<HOST>\]( \(may be forged\))?, reject=(550 5\.7\.1 (?P=email)\.\.\. Relaying denied\. (IP name possibly forged \[(\d+\.){3}\d+\]|Proper authentication required\.|IP name lookup failed \[(\d+\.){3}\d+\])|553 5\.1\.8 (?P=email)\.\.\. Domain of sender address \S+ does not exist|550 5\.[71]\.1 (?P=email)\.\.\. (Rejected: .*|User unknown))$ - ^%(__prefix_line)sruleset=check_relay, arg1=(?P<dom>\S+), arg2=<HOST>, relay=((?P=dom) )?\[(\d+\.){3}\d+\]( \(may be forged\))?, reject=421 4\.3\.2 (Connection rate limit exceeded\.|Too many open connections\.)$ - ^%(__prefix_line)s\w{14}: rejecting commands from (\S* )?\[<HOST>\] due to pre-greeting traffic after \d+ seconds$ - ^%(__prefix_line)s\w{14}: (\S+ )?\[<HOST>\]: ((?i)expn|vrfy) \S+ \[rejected\]$ - ^(?P<__prefix>%(__prefix_line)s\w+: )<[^@]+@[^>]+>\.\.\. No such user here<SKIPLINES>(?P=__prefix)from=<[^@]+@[^>]+>, size=\d+, class=\d+, nrcpts=\d+, bodytype=\w+, proto=E?SMTP, daemon=MTA, relay=\S+ \[<HOST>\]$ +prefregex = ^<F-MLFID>%(__prefix_line)s(?:\w{14}: )?</F-MLFID><F-CONTENT>.+</F-CONTENT>$ +cmnfailre = ^ruleset=check_rcpt, arg1=(?P<email><\S+@\S+>), relay=(\S+ )?\[<HOST>\](?: \(may be forged\))?, reject=(550 5\.7\.1 (?P=email)\.\.\. Relaying denied\. (IP name possibly forged \[(\d+\.){3}\d+\]|Proper authentication required\.|IP name lookup failed \[(\d+\.){3}\d+\])|553 5\.1\.8 (?P=email)\.\.\. Domain of sender address \S+ does not exist|550 5\.[71]\.1 (?P=email)\.\.\. (Rejected: .*|User unknown))$ + ^ruleset=check_relay, arg1=(?P<dom>\S+), arg2=<HOST>, relay=((?P=dom) )?\[(\d+\.){3}\d+\](?: \(may be forged\))?, reject=421 4\.3\.2 (Connection rate limit exceeded\.|Too many open connections\.)$ + ^rejecting commands from (\S* )?\[<HOST>\] due to pre-greeting traffic after \d+ seconds$ + ^(?:\S+ )?\[<HOST>\]: (?:(?i)expn|vrfy) \S+ \[rejected\]$ + ^<[^@]+@[^>]+>\.\.\. No such user here$ + ^<F-NOFAIL>from=<[^@]+@[^>]+></F-NOFAIL>, size=\d+, class=\d+, nrcpts=\d+, bodytype=\w+, proto=E?SMTP, daemon=MTA, relay=\S+ \[<HOST>\]$ -ignoreregex = +mdre-normal = +mdre-extra = ^(?:\S+ )?\[<HOST>\](?: \(may be forged\))? did not issue (?:[A-Z]{4}[/ ]?)+during connection to M(?:TA|SP)(?:-\w+)?$ -[Init] +mdre-aggressive = %(mdre-extra)s + +failregex = %(cmnfailre)s + <mdre-<mode>> + +# Parameter "mode": normal (default), extra or aggressive +# Usage example (for jail.local): +# [sendmail-reject] +# filter = sendmail-reject[mode=extra] +# +mode = normal + +ignoreregex = -# "maxlines" is number of log lines to buffer for multi-line regex searches -maxlines = 10 # DEV NOTES: # -# Regarding the last multiline regex: +# Regarding the multiline regex: # -# There can be a nunber of non-related lines between the first and second part -# of this regex maxlines of 10 is quite generious. Only one of the -# "No such user" lines needs to be matched before the line with the HOST. +# "No such user" lines generate a failure and needs to be matched together with +# another line with the HOST, therefore no-failure line was added as regex, that +# contains HOST (see line with tag <F-NOFAIL>). # -# Note the capture __prefix, includes both the __prefix_lines (which includes -# the sendmail PID), but also the \w+ which the the sendmail assigned mail ID. +# Note the capture <F-MLFID>, includes both the __prefix_lines (which includes +# the sendmail PID), but also the `\w{14}` which the the sendmail assigned +# mail ID (todo: check this is necessary, possible obsolete). # -# Author: Daniel Black and Fabian Wenk +# Author: Daniel Black, Fabian Wenk and Sergey Brester aka sebres. +# Rewritten using prefregex by Serg G. Brester. diff --git a/config/filter.d/sshd-ddos.conf b/config/filter.d/sshd-ddos.conf deleted file mode 100644 index 4f71c7f3..00000000 --- a/config/filter.d/sshd-ddos.conf +++ /dev/null @@ -1,29 +0,0 @@ -# Fail2Ban ssh filter for at attempted exploit -# -# The regex here also relates to a exploit: -# -# http://www.securityfocus.com/bid/17958/exploit -# The example code here shows the pushing of the exploit straight after -# reading the server version. This is where the client version string normally -# pushed. As such the server will read this unparsible information as -# "Did not receive identification string". - -[INCLUDES] - -# Read common prefixes. If any customizations available -- read them from -# common.local -before = common.conf - -[Definition] - -_daemon = sshd - -failregex = ^%(__prefix_line)sDid not receive identification string from <HOST>\s*$ - -ignoreregex = - -[Init] - -journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd - -# Author: Yaroslav Halchenko diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index a425de1f..95915fcc 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -14,32 +14,74 @@ # common.local before = common.conf -[Definition] +[DEFAULT] _daemon = sshd -failregex = ^%(__prefix_line)s(?:error: PAM: )?[aA]uthentication (?:failure|error|failed) for .* from <HOST>( via \S+)?\s*$ - ^%(__prefix_line)s(?:error: PAM: )?User not known to the underlying authentication module for .* from <HOST>\s*$ - ^%(__prefix_line)sFailed \S+ for (?P<cond_inv>invalid user )?(?P<user>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)) from <HOST>(?: port \d+)?(?: ssh\d*)?(?(cond_user):|(?:(?:(?! from ).)*)$) - ^%(__prefix_line)sROOT LOGIN REFUSED.* FROM <HOST>\s*$ - ^%(__prefix_line)s[iI](?:llegal|nvalid) user .* from <HOST>\s*$ - ^%(__prefix_line)sUser .+ from <HOST> not allowed because not listed in AllowUsers\s*$ - ^%(__prefix_line)sUser .+ from <HOST> not allowed because listed in DenyUsers\s*$ - ^%(__prefix_line)sUser .+ from <HOST> not allowed because not in any group\s*$ - ^%(__prefix_line)srefused connect from \S+ \(<HOST>\)\s*$ - ^%(__prefix_line)s(?:error: )?Received disconnect from <HOST>: 3: .*: Auth fail(?: \[preauth\])?$ - ^%(__prefix_line)sUser .+ from <HOST> not allowed because a group is listed in DenyGroups\s*$ - ^%(__prefix_line)sUser .+ from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*$ - ^(?P<__prefix>%(__prefix_line)s)User .+ not allowed because account is locked<SKIPLINES>(?P=__prefix)(?:error: )?Received disconnect from <HOST>: 11: .+ \[preauth\]$ - ^(?P<__prefix>%(__prefix_line)s)Disconnecting: Too many authentication failures for .+? \[preauth\]<SKIPLINES>(?P=__prefix)(?:error: )?Connection closed by <HOST> \[preauth\]$ - ^(?P<__prefix>%(__prefix_line)s)Connection from <HOST> port \d+(?: on \S+ port \d+)?<SKIPLINES>(?P=__prefix)Disconnecting: Too many authentication failures for .+? \[preauth\]$ - ^%(__prefix_line)s(error: )?maximum authentication attempts exceeded for .* from <HOST>(?: port \d*)?(?: ssh\d*)? \[preauth\]$ - ^%(__prefix_line)spam_unix\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=\S*\s*rhost=<HOST>\s.*$ +# optional prefix (logged from several ssh versions) like "error: ", "error: PAM: " or "fatal: " +__pref = (?:(?:error|fatal): (?:PAM: )?)? +# optional suffix (logged from several ssh versions) like " [preauth]" +__suff = (?: \[preauth\])?\s* +__on_port_opt = (?: port \d+)?(?: on \S+(?: port \d+)?)? + +[Definition] + +prefregex = ^<F-MLFID>%(__prefix_line)s</F-MLFID>%(__pref)s<F-CONTENT>.+</F-CONTENT>$ + +cmnfailre = ^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \S+)?\s*%(__suff)s$ + ^User not known to the underlying authentication module for <F-USER>.*</F-USER> from <HOST>\s*%(__suff)s$ + ^Failed \S+ for (?P<cond_inv>invalid user )?<F-USER>(?P<cond_user>\S+)|(?(cond_inv)(?:(?! from ).)*?|[^:]+)</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$) + ^<F-USER>ROOT</F-USER> LOGIN REFUSED.* FROM <HOST>\s*%(__suff)s$ + ^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> from <HOST>%(__on_port_opt)s\s*$ + ^User <F-USER>.+</F-USER> from <HOST> not allowed because not listed in AllowUsers\s*%(__suff)s$ + ^User <F-USER>.+</F-USER> from <HOST> not allowed because listed in DenyUsers\s*%(__suff)s$ + ^User <F-USER>.+</F-USER> from <HOST> not allowed because not in any group\s*%(__suff)s$ + ^refused connect from \S+ \(<HOST>\)\s*%(__suff)s$ + ^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*3: .*: Auth fail%(__suff)s$ + ^User <F-USER>.+</F-USER> from <HOST> not allowed because a group is listed in DenyGroups\s*%(__suff)s$ + ^User <F-USER>.+</F-USER> from <HOST> not allowed because none of user's groups are listed in AllowGroups\s*%(__suff)s$ + ^pam_unix\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=<F-USER>\S*</F-USER>\s*rhost=<HOST>\s.*%(__suff)s$ + ^(error: )?maximum authentication attempts exceeded for <F-USER>.*</F-USER> from <HOST>%(__on_port_opt)s(?: ssh\d*)?%(__suff)s$ + ^User <F-USER>.+</F-USER> not allowed because account is locked%(__suff)s + ^<F-MLFFORGET>Disconnecting</F-MLFFORGET>: Too many authentication failures(?: for <F-USER>.+?</F-USER>)?%(__suff)s + ^<F-NOFAIL>Received <F-MLFFORGET>disconnect</F-MLFFORGET></F-NOFAIL> from <HOST>: 11: + ^<F-NOFAIL>Connection <F-MLFFORGET>closed</F-MLFFORGET></F-NOFAIL> by <HOST>%(__suff)s$ + +mdre-normal = + +mdre-ddos = ^Did not receive identification string from <HOST>%(__suff)s$ + ^Connection <F-MLFFORGET>reset</F-MLFFORGET> by <HOST>%(__on_port_opt)s%(__suff)s + ^<F-NOFAIL>SSH: Server;Ltype:</F-NOFAIL> (?:Authname|Version|Kex);Remote: <HOST>-\d+;[A-Z]\w+: + ^Read from socket failed: Connection <F-MLFFORGET>reset</F-MLFFORGET> by peer%(__suff)s + +mdre-extra = ^Received <F-MLFFORGET>disconnect</F-MLFFORGET> from <HOST>%(__on_port_opt)s:\s*14: No supported authentication methods available%(__suff)s$ + ^Unable to negotiate with <HOST>%(__on_port_opt)s: no matching (?:cipher|key exchange method) found. + ^Unable to negotiate a (?:cipher|key exchange method)%(__suff)s$ + +mdre-aggressive = %(mdre-ddos)s + %(mdre-extra)s + +cfooterre = ^<F-NOFAIL>Connection from</F-NOFAIL> <HOST> + +failregex = %(cmnfailre)s + <mdre-<mode>> + %(cfooterre)s + +# Parameter "mode": normal (default), ddos, extra or aggressive (combines all) +# Usage example (for jail.local): +# [sshd] +# mode = extra +# # or another jail (rewrite filter parameters of jail): +# [sshd-aggressive] +# filter = sshd[mode=aggressive] +# +mode = normal + +#filter = sshd[mode=aggressive] ignoreregex = -# "maxlines" is number of log lines to buffer for multi-line regex searches -maxlines = 10 +maxlines = 1 journalmatch = _SYSTEMD_UNIT=sshd.service + _COMM=sshd @@ -52,5 +94,5 @@ datepattern = {^LN-BEG} # and later catch-all's could contain user-provided input, which need to be greedily # matched away first. # -# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black - +# Author: Cyril Jaquier, Yaroslav Halchenko, Petr Voralek, Daniel Black and Sergey Brester aka sebres +# Rewritten using prefregex (and introduced "mode" parameter) by Serg G. Brester. diff --git a/config/filter.d/suhosin.conf b/config/filter.d/suhosin.conf index f125eadc..46fbe381 100644 --- a/config/filter.d/suhosin.conf +++ b/config/filter.d/suhosin.conf @@ -17,7 +17,7 @@ _daemon = (?:lighttpd|suhosin) _lighttpd_prefix = (?:\(mod_fastcgi\.c\.\d+\) FastCGI-stderr:\s) -failregex = ^%(__prefix_line)s%(_lighttpd_prefix)s?ALERT - .* \(attacker '<HOST>', file '.*'(?:, line \d+)?\)$ +failregex = ^%(__prefix_line)s%(_lighttpd_prefix)s?ALERT - .*? \(attacker '<HOST>', file '[^']*'(?:, line \d+)?\)$ ignoreregex = diff --git a/config/filter.d/xinetd-fail.conf b/config/filter.d/xinetd-fail.conf index d75e3d66..b4093d98 100644 --- a/config/filter.d/xinetd-fail.conf +++ b/config/filter.d/xinetd-fail.conf @@ -14,8 +14,10 @@ before = common.conf _daemon = xinetd -failregex = ^%(__prefix_line)sFAIL: \S+ address from=<HOST>$ - ^%(__prefix_line)sFAIL: \S+ libwrap from=<HOST>$ +prefregex = ^%(__prefix_line)sFAIL: <F-CONTENT>.+</F-CONTENT>$ + +failregex = ^\S+ address from=<HOST>$ + ^\S+ libwrap from=<HOST>$ ignoreregex = |