From 657b147c0d7830f3600f3dc7feaa4815a7e19fde Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 10 Oct 2018 12:25:53 +0200 Subject: [PATCH 1/4] fixed dependency issue if setup invoked using python 3.x: invocation of 2to3 takes place after setup (and __init__.py) loaded; closes gh-2255. --- fail2ban/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fail2ban/__init__.py b/fail2ban/__init__.py index fa6dcf77..61789a45 100644 --- a/fail2ban/__init__.py +++ b/fail2ban/__init__.py @@ -82,7 +82,7 @@ strptime("2012", "%Y") # short names for pure numeric log-level ("Level 25" could be truncated by short formats): def _init(): - for i in xrange(50): + for i in range(50): if logging.getLevelName(i).startswith('Level'): logging.addLevelName(i, '#%02d-Lev.' % i) _init() From 0df221b54b170ac6fbd204c0e6cf1c7b80f54e67 Mon Sep 17 00:00:00 2001 From: dienteperro Date: Thu, 15 Nov 2018 14:34:51 -0500 Subject: [PATCH 2/4] "be" instead of "me" in shorewall.conf --- config/action.d/shorewall.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/action.d/shorewall.conf b/config/action.d/shorewall.conf index f5f2c775..5626c596 100644 --- a/config/action.d/shorewall.conf +++ b/config/action.d/shorewall.conf @@ -9,7 +9,7 @@ # connections. So if the attempter goes on trying using the same connection # he could even log in. In order to get the same behavior of the iptable # action (so that the ban is immediate) the /etc/shorewall/shorewall.conf -# file should me modified with "BLACKLISTNEWONLY=No". Note that as of +# file should be modified with "BLACKLISTNEWONLY=No". Note that as of # Shorewall 4.5.13 BLACKLISTNEWONLY is deprecated; however the equivalent # of BLACKLISTNEWONLY=No can now be achieved by setting BLACKLIST="ALL". # From 1c1d2cc435d6e8f1eb4a1b60c935a1385a82e295 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 19 Nov 2018 21:19:57 +0100 Subject: [PATCH 3/4] introduces new failregex-flag tag `` signaled that the access to service was gained (ATM used similar to , but does not added to matches); filter.d/sshd.conf: extended with new rules: - Disconnecting ...: Change of username or service not allowed - Disconnected from ... [preauth] (extra/aggressive mode only) --- config/filter.d/sshd.conf | 4 +++- fail2ban/server/filter.py | 14 ++++++++++---- .../filter.d/zzz-sshd-obsolete-multiline.conf | 1 + fail2ban/tests/files/logs/sshd | 10 ++++++++++ 4 files changed, 24 insertions(+), 5 deletions(-) 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] From 0ac5c8941c5ddab69bd7b251c70d714d5eafe3be Mon Sep 17 00:00:00 2001 From: "Sergey G. Brester" Date: Tue, 20 Nov 2018 12:39:38 +0100 Subject: [PATCH 4/4] Update ChangeLog --- ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) 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