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]