diff --git a/ChangeLog b/ChangeLog index 0cda45fa..a45de141 100644 --- a/ChangeLog +++ b/ChangeLog @@ -35,8 +35,13 @@ ver. 0.10.5-dev-1 (20??/??/??) - development edition ----------- ### Fixes +* `filter.d/sshd.conf`: + - captures `Disconnecting ...: Change of username or service not allowed` (gh-2239, gh-2279) + - captures `Disconnected from ... [preauth]` (`extra`/`aggressive` mode and preauth phase only, gh-2239, gh-2279) ### New Features +* new failregex-flag tag `` for failregex, signaled that the access to service was gained + (ATM used similar to tag ``, but it does not add the log-line to matches, gh-2279) ### Enhancements diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index 60efead7..906e46cf 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -54,10 +54,11 @@ cmnfailre = ^[aA]uthentication (?:failure|error|failed) for .* ^%(__pam_auth)s\(sshd:auth\):\s+authentication failure;(?:\s+(?:(?:logname|e?uid|tty)=\S*)){0,4}\s+ruser=\S*\s+rhost=(?:\s+user=\S*)?%(__suff)s$ ^(error: )?maximum authentication attempts exceeded for .* from %(__on_port_opt)s(?: ssh\d*)?%(__suff)s$ ^User .+ not allowed because account is locked%(__suff)s + ^Disconnecting(?: from)?(?: (?:invalid|authenticating)) user \S+ %(__on_port_opt)s:\s*Change of username or service not allowed:\s*.*\[preauth\]\s*$ ^Disconnecting: Too many authentication failures(?: for .+?)?%(__suff)s$ ^Received disconnect from %(__on_port_opt)s:\s*11: ^Connection closed by%(__authng_user)s -suff-onclosed> - ^Accepted \w+ for \S+ from (?:\s|$) + ^Accepted \w+ for \S+ from (?:\s|$) mdre-normal = # used to differentiate "connection closed" with and without `[preauth]` (fail/nofail cases in ddos mode) @@ -74,6 +75,7 @@ mdre-extra = ^Received disconnect from %(__on_p ^Unable to negotiate with %(__on_port_opt)s: no matching <__alg_match> found. ^Unable to negotiate a <__alg_match> ^no matching <__alg_match> found: + ^Disconnected(?: from)?(?: (?:invalid|authenticating)) user \S+ %(__on_port_opt)s \[preauth\]\s*$ mdrp-extra-suff-onclosed = %(mdrp-normal-suff-onclosed)s mdre-aggressive = %(mdre-ddos)s diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index 681e708c..1e7d5e76 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -670,16 +670,21 @@ class Filter(JailThread): mlfidFail = self.mlfidCache.get(mlfid) if self.__mlfidCache else None users = None nfflgs = 0 - if fail.get('nofail'): nfflgs |= 1 + if fail.get("mlfgained"): + nfflgs |= 9 + if not fail.get('nofail'): + fail['nofail'] = fail["mlfgained"] + elif fail.get('nofail'): nfflgs |= 1 if fail.get('mlfforget'): nfflgs |= 2 # if multi-line failure id (connection id) known: if mlfidFail: mlfidGroups = mlfidFail[1] # update users set (hold all users of connect): users = self._updateUsers(mlfidGroups, fail.get('user')) - # be sure we've correct current state ('nofail' only from last failure) + # be sure we've correct current state ('nofail' and 'mlfgained' only from last failure) try: del mlfidGroups['nofail'] + del mlfidGroups['mlfgained'] except KeyError: pass # # ATM incremental (non-empty only) merge deactivated (for future version only), @@ -703,16 +708,17 @@ class Filter(JailThread): # we've new user, reset 'nofail' because of multiple users attempts: try: del fail['nofail'] + nfflgs &= ~1 # reset nofail except KeyError: pass # merge matches: - if not fail.get('nofail'): # current state (corresponding users) + if not (nfflgs & 1): # current nofail state (corresponding users) try: m = fail.pop("nofail-matches") m += fail.get("matches", []) except KeyError: m = fail.get("matches", []) - if not (nfflgs & 2): # not mlfforget: + if not (nfflgs & 8): # no gain signaled m += failRegex.getMatchedTupleLines() fail["matches"] = m elif not (nfflgs & 2) and (nfflgs & 1): # not mlfforget and nofail: diff --git a/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf b/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf index 98fca7f5..cc7737ec 100644 --- a/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf +++ b/fail2ban/tests/config/filter.d/zzz-sshd-obsolete-multiline.conf @@ -64,6 +64,7 @@ mdre-extra = ^%(__prefix_line_sl)sReceived disconnect from %(__on_port_opt ^%(__prefix_line_sl)sUnable to negotiate with %(__on_port_opt)s: no matching <__alg_match> found. ^%(__prefix_line_ml1)sConnection from %(__on_port_opt)s%(__prefix_line_ml2)sUnable to negotiate a <__alg_match> ^%(__prefix_line_ml1)sConnection from %(__on_port_opt)s%(__prefix_line_ml2)sno matching <__alg_match> found: + ^%(__prefix_line_sl)sDisconnected(?: from)?(?: (?:invalid|authenticating)) user \S+ %(__on_port_opt)s \[preauth\]\s*$ mdre-aggressive = %(mdre-ddos)s %(mdre-extra)s diff --git a/fail2ban/tests/files/logs/sshd b/fail2ban/tests/files/logs/sshd index e2b3d456..f32f3462 100644 --- a/fail2ban/tests/files/logs/sshd +++ b/fail2ban/tests/files/logs/sshd @@ -253,6 +253,13 @@ Mar 7 18:53:34 bar sshd[1559]: Accepted password for known from 192.0.2.116 por # failJSON: { "match": false , "desc": "No failure" } Mar 7 18:53:38 bar sshd[1559]: Connection closed by 192.0.2.116 +# failJSON: { "time": "2005-03-19T16:47:48", "match": true , "attempts": 1, "user": "admin", "host": "192.0.2.117", "desc": "Failure: attempt invalid user" } +Mar 19 16:47:48 test sshd[5672]: Invalid user admin from 192.0.2.117 port 44004 +# failJSON: { "time": "2005-03-19T16:47:49", "match": true , "attempts": 2, "user": "admin", "host": "192.0.2.117", "desc": "Failure: attempt to change user (disallowed)" } +Mar 19 16:47:49 test sshd[5672]: Disconnecting invalid user admin 192.0.2.117 port 44004: Change of username or service not allowed: (admin,ssh-connection) -> (user,ssh-connection) [preauth] +# failJSON: { "time": "2005-03-19T16:47:50", "match": false, "desc": "Disconnected during preauth phase (no failure in normal mode)" } +Mar 19 16:47:50 srv sshd[5672]: Disconnected from authenticating user admin 192.0.2.6 port 33553 [preauth] + # filterOptions: [{"mode": "ddos"}, {"mode": "aggressive"}] # http://forums.powervps.com/showthread.php?t=1667 @@ -334,3 +341,6 @@ Oct 26 15:30:40 localhost sshd[14737]: Unable to negotiate with 192.0.2.2 port 5 Nov 26 13:03:38 srv sshd[14737]: Unable to negotiate with 192.0.2.4 port 50404: no matching host key type found. Their offer: ssh-dss # failJSON: { "time": "2004-11-26T13:03:39", "match": true , "host": "192.0.2.5", "desc": "No matching everything ... found." } Nov 26 13:03:39 srv sshd[14738]: fatal: Unable to negotiate with 192.0.2.5 port 55555: no matching everything new here found. Their offer: ... + +# failJSON: { "time": "2004-11-26T16:47:51", "match": true , "host": "192.0.2.6", "desc": "Disconnected during preauth phase (in extra/aggressive mode)" } +Nov 26 16:47:51 srv sshd[19320]: Disconnected from authenticating user root 192.0.2.6 port 33553 [preauth]