diff --git a/ChangeLog b/ChangeLog index f02962e2..fc8ab8c1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -430,7 +430,9 @@ releases. - Rewritten without end-anchor ($), because of potential vulnerability on very long URLs. * filter.d/apache-badbots.conf - extended to recognize Jorgee Vulnerability Scanner (gh-1882) * filter.d/asterisk.conf - fixed failregex AMI Asterisk authentification failed (see gh-1302) -* filter.d/dovecot.conf - fixed failregex, see gh-1879 (partially cherry-picked from gh-1880) +* filter.d/dovecot.conf: + - fixed failregex, see gh-1879 (partially cherry-picked from gh-1880) + - extended to match pam_authenticate failures with "Permission denied" (gh-1897) * filter.d/exim.conf - fixed failregex for case of flood attempts with `D=0s` (gh-1887) * filter.d/postfix-*.conf - added optional port regex (gh-1902) diff --git a/config/filter.d/dovecot.conf b/config/filter.d/dovecot.conf index 4df7c752..2019a160 100644 --- a/config/filter.d/dovecot.conf +++ b/config/filter.d/dovecot.conf @@ -14,7 +14,7 @@ prefregex = ^%(__prefix_line)s(?:%(_auth_worker)s(?:\([^\)]+\))?: )?(?:%(__pam_a failregex = ^authentication failure; logname=\S* uid=\S* euid=\S* tty=dovecot ruser=\S* rhost=(?:\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=(?:[^>]*(?:, session=<\S+>)?)\s*$ - ^pam\(\S+,\): pam_authenticate\(\) failed: (?:User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\))\s*$ + ^pam\(\S+,(?:,\S*)?\): pam_authenticate\(\) failed: (?:User not known to the underlying authentication module: \d+ Time\(s\)|Authentication failure \(password mismatch\?\)|Permission denied)\s*$ ^[a-z\-]{3,15}\(\S*,(?:,\S*)?\): (?:unknown user|invalid credentials)\s*$ > diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index be0c8917..2aecd981 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -459,7 +459,10 @@ class Filter(JailThread): return # Create IP address object ip = IPAddr(ipstr) - + # Avoid exact duplicates + if ip in self.__ignoreIpList: + logSys.warn(" Ignore duplicate %r (%r), already in ignore list", ip, ipstr) + return # log and append to ignore list logSys.debug(" Add %r to ignore list (%r)", ip, ipstr) self.__ignoreIpList.append(ip) diff --git a/fail2ban/tests/files/logs/dovecot b/fail2ban/tests/files/logs/dovecot index 34c91d42..9de3d0b4 100644 --- a/fail2ban/tests/files/logs/dovecot +++ b/fail2ban/tests/files/logs/dovecot @@ -43,6 +43,9 @@ Jan 29 05:13:50 mail dovecot: auth: passwd-file(username,1.2.3.4): unknown user # failJSON: { "time": "2005-01-29T13:54:06", "match": true , "host": "192.0.2.5" } Jan 29 13:54:06 auth-worker(22401): Info: sql(admin@example.de,192.0.2.5,): unknown user +# failJSON: { "time": "2005-01-29T14:38:51", "match": true , "host": "192.0.2.6", "desc": "PAM Permission denied (gh-1897)" } +Jan 29 14:38:51 example.com dovecot[24941]: auth-worker(30165): pam(user@example.com,192.0.2.6,): pam_authenticate() failed: Permission denied + # failJSON: { "time": "2005-04-19T05:22:20", "match": true , "host": "80.255.3.104" } Apr 19 05:22:20 vm5 auth: pam_unix(dovecot:auth): authentication failure; logname= uid=0 euid=0 tty=dovecot ruser=informix rhost=80.255.3.104 diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py index 5545afd6..1072c31f 100644 --- a/fail2ban/tests/servertestcase.py +++ b/fail2ban/tests/servertestcase.py @@ -441,17 +441,16 @@ class Transmitter(TransmitterBase): self.assertEqual( self.transm.proceed(["set", self.jailName, "addignoreip", value]), (0, [value])) - # Will allow duplicate - #NOTE: Should duplicates be allowed, or silent ignore like logpath? + # Duplicates ignored self.assertEqual( self.transm.proceed(["set", self.jailName, "addignoreip", value]), - (0, [value, value])) + (0, [value])) self.assertEqual( self.transm.proceed(["get", self.jailName, "ignoreip"]), - (0, [value, value])) + (0, [value])) self.assertEqual( self.transm.proceed(["set", self.jailName, "delignoreip", value]), - (0, [value])) + (0, [])) self.assertEqual( self.transm.proceed(["get", self.jailName, "ignoreself"]),