|
|
|
@ -258,7 +258,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
"-l", "notice", # put down log-level, because of too many debug-messages
|
|
|
|
|
"-v", "--verbose-date", "--print-all-matched", "--print-all-ignored",
|
|
|
|
|
"-c", CONFIG_DIR,
|
|
|
|
|
FILENAME_SSHD, "sshd"
|
|
|
|
|
FILENAME_SSHD, "sshd.conf"
|
|
|
|
|
))
|
|
|
|
|
# test failure line and not-failure lines both presents:
|
|
|
|
|
self.assertLogged("[29116]: User root not allowed because account is locked",
|
|
|
|
@ -269,7 +269,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
"-l", "notice", # put down log-level, because of too many debug-messages
|
|
|
|
|
"-vv", "-c", CONFIG_DIR,
|
|
|
|
|
"Dec 31 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 192.0.2.1",
|
|
|
|
|
"sshd[logtype=short]"
|
|
|
|
|
"filter.d/sshd[logtype=short]"
|
|
|
|
|
))
|
|
|
|
|
# tet logtype is specified and set in real options:
|
|
|
|
|
self.assertLogged("Real filter options :", "'logtype': 'short'", all=True)
|
|
|
|
@ -288,6 +288,16 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
"[29116]: User root not allowed because account is locked",
|
|
|
|
|
"[29116]: Received disconnect from 192.0.2.4", all=True)
|
|
|
|
|
|
|
|
|
|
def testLoadFromJail(self):
|
|
|
|
|
self.assertTrue(_test_exec(
|
|
|
|
|
"-l", "notice", # put down log-level, because of too many debug-messages
|
|
|
|
|
"-c", CONFIG_DIR, '-vv',
|
|
|
|
|
FILENAME_ZZZ_SSHD, "sshd[logtype=short]"
|
|
|
|
|
))
|
|
|
|
|
# test it was jail not filter:
|
|
|
|
|
self.assertLogged(
|
|
|
|
|
"Use %11s jail : %s" % ('','sshd'))
|
|
|
|
|
|
|
|
|
|
def testMultilineSshd(self):
|
|
|
|
|
# by the way test of missing lines by multiline in `for bufLine in orgLineBuffer[int(fullBuffer):]`
|
|
|
|
|
self.assertTrue(_test_exec(
|
|
|
|
@ -431,11 +441,11 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
)
|
|
|
|
|
_test = lambda *args: _test_exec(*(opts + args))
|
|
|
|
|
# with MLFID from prefregex and IP after failure obtained from F-NOFAIL RE:
|
|
|
|
|
self.assertTrue(_test('-o', 'IP:<ip>', log, 'sshd'))
|
|
|
|
|
self.assertTrue(_test('-o', 'IP:<ip>', log, 'sshd.conf'))
|
|
|
|
|
self.assertLogged('IP:192.0.2.76')
|
|
|
|
|
self.pruneLog()
|
|
|
|
|
# test diverse ID/IP constellations:
|
|
|
|
|
def _test_variants(flt="sshd", prefix=""):
|
|
|
|
|
def _test_variants(flt="sshd.conf", prefix=""):
|
|
|
|
|
# with different ID/IP from failregex (ID/User from first, IP from second message):
|
|
|
|
|
self.assertTrue(_test('-o', 'ID:"<fid>" | IP:<ip> | U:<F-USER>', log,
|
|
|
|
|
flt+'[failregex="'
|
|
|
|
@ -455,7 +465,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
# first with sshd and prefregex:
|
|
|
|
|
_test_variants()
|
|
|
|
|
# the same without prefregex and MLFID directly in failregex (no merge with prefregex groups):
|
|
|
|
|
_test_variants('common', prefix=r"\s*\S+ sshd\[<F-MLFID>\d+</F-MLFID>\]:\s+")
|
|
|
|
|
_test_variants('common.conf', prefix=r"\s*\S+ sshd\[<F-MLFID>\d+</F-MLFID>\]:\s+")
|
|
|
|
|
|
|
|
|
|
def testNoDateTime(self):
|
|
|
|
|
# datepattern doesn't match:
|
|
|
|
@ -490,7 +500,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
# complex substitution using tags and message (ip, user, msg):
|
|
|
|
|
self.assertTrue(_test_exec('-o', '<ip>, <F-USER>, <msg>',
|
|
|
|
|
'-c', CONFIG_DIR, '--usedns', 'no',
|
|
|
|
|
STR_ML_SSHD + "\n" + STR_ML_SSHD_OK, 'sshd[logtype=short, publickey=invalid]'))
|
|
|
|
|
STR_ML_SSHD + "\n" + STR_ML_SSHD_OK, 'sshd.conf[logtype=short, publickey=invalid]'))
|
|
|
|
|
# be sure we don't have IP in one line and have it in another:
|
|
|
|
|
lines = STR_ML_SSHD.split("\n")
|
|
|
|
|
self.assertTrue('192.0.2.2' not in lines[-2] and '192.0.2.2' in lines[-1])
|
|
|
|
@ -506,7 +516,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
self.pruneLog("[test-phase 1] mode=aggressive & publickey=nofail + OK (accepted)")
|
|
|
|
|
self.assertTrue(_test_exec('-o', '<ip>, <F-USER>, <msg>',
|
|
|
|
|
'-c', CONFIG_DIR, '--usedns', 'no',
|
|
|
|
|
STR_ML_SSHD + "\n" + STR_ML_SSHD_OK, 'sshd[logtype=short, mode=aggressive]'))
|
|
|
|
|
STR_ML_SSHD + "\n" + STR_ML_SSHD_OK, 'sshd.conf[logtype=short, mode=aggressive]'))
|
|
|
|
|
self.assertLogged(
|
|
|
|
|
'192.0.2.2, git, '+lines[-4],
|
|
|
|
|
'192.0.2.2, git, '+lines[-3],
|
|
|
|
@ -520,7 +530,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
self.pruneLog("[test-phase 2] mode=aggressive & publickey=nofail + FAIL (closed on preauth)")
|
|
|
|
|
self.assertTrue(_test_exec('-o', '<ip>, <F-USER>, <msg>',
|
|
|
|
|
'-c', CONFIG_DIR, '--usedns', 'no',
|
|
|
|
|
STR_ML_SSHD + "\n" + STR_ML_SSHD_FAIL, 'sshd[logtype=short, mode=aggressive]'))
|
|
|
|
|
STR_ML_SSHD + "\n" + STR_ML_SSHD_FAIL, 'sshd.conf[logtype=short, mode=aggressive]'))
|
|
|
|
|
# 192.0.2.1 should be found for every failure (2x failed key + 1x closed):
|
|
|
|
|
lines = STR_ML_SSHD.split("\n")[0:2] + STR_ML_SSHD_FAIL.split("\n")[-1:]
|
|
|
|
|
self.assertLogged(
|
|
|
|
@ -541,7 +551,7 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
|
|
|
|
'svc[2] connect started 192.0.2.4\n'
|
|
|
|
|
'svc[2] connect authorized 192.0.2.4\n'
|
|
|
|
|
'svc[2] connect finished 192.0.2.4\n',
|
|
|
|
|
r'common[prefregex="^svc\[<F-MLFID>\d+</F-MLFID>\] connect <F-CONTENT>.+</F-CONTENT>$"'
|
|
|
|
|
r'common.conf[prefregex="^svc\[<F-MLFID>\d+</F-MLFID>\] connect <F-CONTENT>.+</F-CONTENT>$"'
|
|
|
|
|
', failregex="'
|
|
|
|
|
'^started\n'
|
|
|
|
|
'^<F-NOFAIL><F-MLFFORGET>finished</F-MLFFORGET></F-NOFAIL> <ADDR>\n'
|
|
|
|
|