mirror of https://github.com/fail2ban/fail2ban
Merge branch '0.10' into 0.11
commit
eb1156b099
|
@ -24,6 +24,8 @@ __pref = (?:(?:error|fatal): (?:PAM: )?)?
|
|||
#__suff = (?: port \d+)?(?: \[preauth\])?\s*
|
||||
__suff = (?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*
|
||||
__on_port_opt = (?: (?:port \d+|on \S+)){0,2}
|
||||
# close by authenticating user:
|
||||
__authng_user = (?: authenticating user <F-USER>\S+|.+?</F-USER>)?
|
||||
|
||||
# for all possible (also future) forms of "no matching (cipher|mac|MAC|compression method|key exchange method|host key type) found",
|
||||
# see ssherr.c for all possible SSH_ERR_..._ALG_MATCH errors.
|
||||
|
@ -54,16 +56,16 @@ cmnfailre = ^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER>
|
|||
^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>%(__on_port_opt)s:\s*11:
|
||||
^<F-NOFAIL>Connection <F-MLFFORGET>closed</F-MLFFORGET></F-NOFAIL> by <HOST><mdrp-<mode>-suff-onclosed>
|
||||
^<F-NOFAIL>Connection <F-MLFFORGET>closed</F-MLFFORGET></F-NOFAIL> by%(__authng_user)s <HOST><mdrp-<mode>-suff-onclosed>
|
||||
^<F-MLFFORGET><F-NOFAIL>Accepted \w+</F-NOFAIL></F-MLFFORGET> for <F-USER>\S+</F-USER> from <HOST>(?:\s|$)
|
||||
|
||||
mdre-normal =
|
||||
# used to differentiate "connection closed" with and without `[preauth]` (fail/nofail cases in ddos mode)
|
||||
mdrp-normal-suff-onclosed =
|
||||
mdrp-normal-suff-onclosed = (?:%(__suff)s|\s*)$
|
||||
|
||||
mdre-ddos = ^Did not receive identification string from <HOST>
|
||||
^Connection <F-MLFFORGET>reset</F-MLFFORGET> by <HOST>
|
||||
^Connection <F-MLFFORGET>closed</F-MLFFORGET> by <HOST>%(__on_port_opt)s\s+\[preauth\]\s*$
|
||||
^Connection <F-MLFFORGET>closed</F-MLFFORGET> by%(__authng_user)s <HOST>%(__on_port_opt)s\s+\[preauth\]\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
|
||||
mdrp-ddos-suff-onclosed = %(__on_port_opt)s\s*$
|
||||
|
|
|
@ -411,17 +411,23 @@ class Fail2banRegex(object):
|
|||
def testRegex(self, line, date=None):
|
||||
orgLineBuffer = self._filter._Filter__lineBuffer
|
||||
fullBuffer = len(orgLineBuffer) >= self._filter.getMaxLines()
|
||||
is_ignored = False
|
||||
try:
|
||||
ret = self._filter.processLine(line, date)
|
||||
found = self._filter.processLine(line, date)
|
||||
lines = []
|
||||
line = self._filter.processedLine()
|
||||
for match in ret:
|
||||
ret = []
|
||||
for match in found:
|
||||
# Append True/False flag depending if line was matched by
|
||||
# more than one regex
|
||||
match.append(len(ret)>1)
|
||||
regex = self._failregex[match[0]]
|
||||
regex.inc()
|
||||
regex.appendIP(match)
|
||||
if not match[3].get('nofail'):
|
||||
ret.append(match)
|
||||
else:
|
||||
is_ignored = True
|
||||
except RegexException as e: # pragma: no cover
|
||||
output( 'ERROR: %s' % e )
|
||||
return False
|
||||
|
@ -447,13 +453,13 @@ class Fail2banRegex(object):
|
|||
if lines: # pre-lines parsed in multiline mode (buffering)
|
||||
lines.append(line)
|
||||
line = "\n".join(lines)
|
||||
return line, ret
|
||||
return line, ret, is_ignored
|
||||
|
||||
def process(self, test_lines):
|
||||
t0 = time.time()
|
||||
for line in test_lines:
|
||||
if isinstance(line, tuple):
|
||||
line_datetimestripped, ret = self.testRegex(
|
||||
line_datetimestripped, ret, is_ignored = self.testRegex(
|
||||
line[0], line[1])
|
||||
line = "".join(line[0])
|
||||
else:
|
||||
|
@ -461,8 +467,9 @@ class Fail2banRegex(object):
|
|||
if line.startswith('#') or not line:
|
||||
# skip comment and empty lines
|
||||
continue
|
||||
line_datetimestripped, ret = self.testRegex(line)
|
||||
is_ignored = self.testIgnoreRegex(line_datetimestripped)
|
||||
line_datetimestripped, ret, is_ignored = self.testRegex(line)
|
||||
if not is_ignored:
|
||||
is_ignored = self.testIgnoreRegex(line_datetimestripped)
|
||||
|
||||
if is_ignored:
|
||||
self._line_stats.ignored += 1
|
||||
|
|
|
@ -16,6 +16,8 @@ __pref = (?:(?:error|fatal): (?:PAM: )?)?
|
|||
# optional suffix (logged from several ssh versions) like " [preauth]"
|
||||
__suff = (?: (?:port \d+|on \S+|\[preauth\])){0,3}\s*
|
||||
__on_port_opt = (?: (?:port \d+|on \S+)){0,2}
|
||||
# close by authenticating user:
|
||||
__authng_user = (?: authenticating user <F-USER>\S+|.+?</F-USER>)?
|
||||
|
||||
# single line prefix:
|
||||
__prefix_line_sl = %(__prefix_line)s%(__pref)s
|
||||
|
@ -48,12 +50,13 @@ cmnfailre = ^%(__prefix_line_sl)s[aA]uthentication (?:failure|error|failed) for
|
|||
^%(__prefix_line_ml1)s%(__pam_auth)s\(sshd:auth\):\s+authentication failure;\s*logname=\S*\s*uid=\d*\s*euid=\d*\s*tty=\S*\s*ruser=\S*\s*rhost=<HOST>\s.*%(__suff)s$%(__prefix_line_ml2)sConnection closed
|
||||
^%(__prefix_line_sl)s(error: )?maximum authentication attempts exceeded for .* from <HOST>%(__on_port_opt)s(?: ssh\d*)? \[preauth\]$
|
||||
^%(__prefix_line_ml1)sUser .+ not allowed because account is locked%(__prefix_line_ml2)sReceived disconnect from <HOST>%(__on_port_opt)s:\s*11: .+%(__suff)s$
|
||||
^%(__prefix_line_ml1)sDisconnecting: Too many authentication failures(?: for .+?)?%(__suff)s%(__prefix_line_ml2)sConnection closed by <HOST>%(__suff)s$
|
||||
^%(__prefix_line_ml1)sDisconnecting: Too many authentication failures(?: for .+?)?%(__suff)s%(__prefix_line_ml2)sConnection closed by%(__authng_user)s <HOST>%(__suff)s$
|
||||
^%(__prefix_line_ml1)sConnection from <HOST>%(__on_port_opt)s%(__prefix_line_ml2)sDisconnecting: Too many authentication failures(?: for .+?)?%(__suff)s$
|
||||
|
||||
mdre-normal =
|
||||
|
||||
mdre-ddos = ^%(__prefix_line_sl)sDid not receive identification string from <HOST>
|
||||
^%(__prefix_line_sl)sConnection closed by%(__authng_user)s <HOST>%(__on_port_opt)s\s+\[preauth\]\s*$
|
||||
^%(__prefix_line_sl)sConnection reset by <HOST>
|
||||
^%(__prefix_line_ml1)sSSH: Server;Ltype: (?:Authname|Version|Kex);Remote: <HOST>-\d+;[A-Z]\w+:.*%(__prefix_line_ml2)sRead from socket failed: Connection reset by peer%(__suff)s$
|
||||
|
||||
|
|
|
@ -209,7 +209,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|||
def testVerboseFullSshd(self):
|
||||
(opts, args, fail2banRegex) = _Fail2banRegex(
|
||||
"-l", "notice", # put down log-level, because of too many debug-messages
|
||||
"-v", "--verbose-date", "--print-all-matched",
|
||||
"-v", "--verbose-date", "--print-all-matched", "--print-all-ignored",
|
||||
"-c", CONFIG_DIR,
|
||||
Fail2banRegexTest.FILENAME_SSHD, "sshd"
|
||||
)
|
||||
|
|
|
@ -283,6 +283,13 @@ Nov 24 23:46:43 host sshd[32686]: fatal: Read from socket failed: Connection res
|
|||
# failJSON: { "time": "2005-03-15T09:20:57", "match": true , "host": "192.0.2.39", "desc": "Singleline for connection reset by" }
|
||||
Mar 15 09:20:57 host sshd[28972]: Connection reset by 192.0.2.39 port 14282 [preauth]
|
||||
|
||||
# failJSON: { "time": "2005-07-17T23:03:05", "match": true , "host": "192.0.2.10", "user": "root", "desc": "user name additionally, gh-2185" }
|
||||
Jul 17 23:03:05 srv sshd[1296]: Connection closed by authenticating user root 192.0.2.10 port 46038 [preauth]
|
||||
# failJSON: { "time": "2005-07-17T23:04:00", "match": true , "host": "192.0.2.11", "user": "test 127.0.0.1", "desc": "check inject on username, gh-2185" }
|
||||
Jul 17 23:04:00 srv sshd[1300]: Connection closed by authenticating user test 127.0.0.1 192.0.2.11 port 46039 [preauth]
|
||||
# failJSON: { "time": "2005-07-17T23:04:01", "match": true , "host": "192.0.2.11", "user": "test 127.0.0.1 port 12345", "desc": "check inject on username, gh-2185" }
|
||||
Jul 17 23:04:01 srv sshd[1300]: Connection closed by authenticating user test 127.0.0.1 port 12345 192.0.2.11 port 46039 [preauth]
|
||||
|
||||
# filterOptions: [{"test.condition":"name=='sshd'", "mode": "ddos"}, {"test.condition":"name=='sshd'", "mode": "aggressive"}]
|
||||
|
||||
# failJSON: { "time": "2005-03-15T09:21:01", "match": true , "host": "192.0.2.212", "desc": "DDOS mode causes failure on close within preauth stage" }
|
||||
|
@ -290,8 +297,6 @@ Mar 15 09:21:01 host sshd[2717]: Connection closed by 192.0.2.212 [preauth]
|
|||
# failJSON: { "time": "2005-03-15T09:21:02", "match": true , "host": "192.0.2.212", "desc": "DDOS mode causes failure on close within preauth stage" }
|
||||
Mar 15 09:21:02 host sshd[2717]: Connection closed by 192.0.2.212 [preauth]
|
||||
|
||||
|
||||
|
||||
# filterOptions: [{"mode": "extra"}, {"mode": "aggressive"}]
|
||||
|
||||
# several other cases from gh-864:
|
||||
|
|
|
@ -201,6 +201,7 @@ def testSampleRegexsFactory(name, basedir):
|
|||
flt, regexsUsedIdx = flt
|
||||
regexList = flt.getFailRegex()
|
||||
|
||||
failregex = -1
|
||||
try:
|
||||
fail = {}
|
||||
ret = flt.processLine(line)
|
||||
|
@ -263,9 +264,10 @@ def testSampleRegexsFactory(name, basedir):
|
|||
regexsUsedRe.add(regexList[failregex])
|
||||
except AssertionError as e: # pragma: no cover
|
||||
import pprint
|
||||
raise AssertionError("%s: %s on: %s:%i, line:\n%s\n"
|
||||
raise AssertionError("%s: %s on: %s:%i, line:\n %sregex (%s):\n %s\n"
|
||||
"faildata: %s\nfail: %s" % (
|
||||
fltName, e, logFile.filename(), logFile.filelineno(), line,
|
||||
fltName, e, logFile.filename(), logFile.filelineno(),
|
||||
line, failregex, regexList[failregex] if failregex != -1 else None,
|
||||
'\n'.join(pprint.pformat(faildata).splitlines()),
|
||||
'\n'.join(pprint.pformat(fail).splitlines())))
|
||||
|
||||
|
|
Loading…
Reference in New Issue