mirror of https://github.com/fail2ban/fail2ban
fixed test cases (ban ASAP also followed in test suite now, so failure reached maxretry causes immediate ban now)
parent
55d7d9e214
commit
e353fb8024
|
@ -164,18 +164,25 @@ def _assert_correct_last_attempt(utest, filter_, output, count=None):
|
||||||
# get fail ticket from jail
|
# get fail ticket from jail
|
||||||
found.append(_ticket_tuple(filter_.getFailTicket()))
|
found.append(_ticket_tuple(filter_.getFailTicket()))
|
||||||
else:
|
else:
|
||||||
# when we are testing without jails
|
# when we are testing without jails wait for failures (up to max time)
|
||||||
# wait for failures (up to max time)
|
if filter_.jail:
|
||||||
Utils.wait_for(
|
while True:
|
||||||
lambda: filter_.failManager.getFailCount() >= (tickcount, failcount),
|
t = filter_.jail.getFailTicket()
|
||||||
_maxWaitTime(10))
|
if not t: break
|
||||||
# get fail ticket(s) from filter
|
found.append(_ticket_tuple(t))
|
||||||
while tickcount:
|
if found:
|
||||||
try:
|
tickcount -= len(found)
|
||||||
found.append(_ticket_tuple(filter_.failManager.toBan()))
|
if tickcount > 0:
|
||||||
except FailManagerEmpty:
|
Utils.wait_for(
|
||||||
break
|
lambda: filter_.failManager.getFailCount() >= (tickcount, failcount),
|
||||||
tickcount -= 1
|
_maxWaitTime(10))
|
||||||
|
# get fail ticket(s) from filter
|
||||||
|
while tickcount:
|
||||||
|
try:
|
||||||
|
found.append(_ticket_tuple(filter_.failManager.toBan()))
|
||||||
|
except FailManagerEmpty:
|
||||||
|
break
|
||||||
|
tickcount -= 1
|
||||||
|
|
||||||
if not isinstance(output[0], (tuple,list)):
|
if not isinstance(output[0], (tuple,list)):
|
||||||
utest.assertEqual(len(found), 1)
|
utest.assertEqual(len(found), 1)
|
||||||
|
@ -951,14 +958,11 @@ class LogFileMonitor(LogCaptureTestCase):
|
||||||
self.file.close()
|
self.file.close()
|
||||||
self.file = _copy_lines_between_files(GetFailures.FILENAME_01, self.name,
|
self.file = _copy_lines_between_files(GetFailures.FILENAME_01, self.name,
|
||||||
n=14, mode='w')
|
n=14, mode='w')
|
||||||
print('=========='*10)
|
|
||||||
self.filter.getFailures(self.name)
|
self.filter.getFailures(self.name)
|
||||||
print('=========='*10)
|
|
||||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||||
self.assertEqual(self.filter.failManager.getFailTotal(), 2)
|
self.assertEqual(self.filter.failManager.getFailTotal(), 2)
|
||||||
|
|
||||||
# move aside, but leaving the handle still open...
|
# move aside, but leaving the handle still open...
|
||||||
print('=========='*10)
|
|
||||||
os.rename(self.name, self.name + '.bak')
|
os.rename(self.name, self.name + '.bak')
|
||||||
_copy_lines_between_files(GetFailures.FILENAME_01, self.name, skip=14, n=1).close()
|
_copy_lines_between_files(GetFailures.FILENAME_01, self.name, skip=14, n=1).close()
|
||||||
self.filter.getFailures(self.name)
|
self.filter.getFailures(self.name)
|
||||||
|
@ -1112,12 +1116,13 @@ def get_monitor_failures_testcase(Filter_):
|
||||||
skip=12, n=3, mode='w')
|
skip=12, n=3, mode='w')
|
||||||
self.assert_correct_last_attempt(GetFailures.FAILURES_01)
|
self.assert_correct_last_attempt(GetFailures.FAILURES_01)
|
||||||
|
|
||||||
def _wait4failures(self, count=2):
|
def _wait4failures(self, count=2, waitEmpty=True):
|
||||||
# Poll might need more time
|
# Poll might need more time
|
||||||
self.assertTrue(self.isEmpty(_maxWaitTime(5)),
|
if waitEmpty:
|
||||||
"Queue must be empty but it is not: %s."
|
self.assertTrue(self.isEmpty(_maxWaitTime(5)),
|
||||||
% (', '.join([str(x) for x in self.jail.queue])))
|
"Queue must be empty but it is not: %s."
|
||||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
% (', '.join([str(x) for x in self.jail.queue])))
|
||||||
|
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||||
Utils.wait_for(lambda: self.filter.failManager.getFailTotal() >= count, _maxWaitTime(10))
|
Utils.wait_for(lambda: self.filter.failManager.getFailTotal() >= count, _maxWaitTime(10))
|
||||||
self.assertEqual(self.filter.failManager.getFailTotal(), count)
|
self.assertEqual(self.filter.failManager.getFailTotal(), count)
|
||||||
|
|
||||||
|
@ -1283,9 +1288,9 @@ def get_monitor_failures_testcase(Filter_):
|
||||||
# now copy and get even more
|
# now copy and get even more
|
||||||
_copy_lines_between_files(GetFailures.FILENAME_01, self.file, skip=12, n=3)
|
_copy_lines_between_files(GetFailures.FILENAME_01, self.file, skip=12, n=3)
|
||||||
# check for 3 failures (not 9), because 6 already get above...
|
# check for 3 failures (not 9), because 6 already get above...
|
||||||
self.assert_correct_last_attempt(GetFailures.FAILURES_01)
|
self.assert_correct_last_attempt(GetFailures.FAILURES_01, count=3)
|
||||||
# total count in this test:
|
# total count in this test:
|
||||||
self.assertEqual(self.filter.failManager.getFailTotal(), 9)
|
self._wait4failures(12, False)
|
||||||
|
|
||||||
cls = MonitorFailures
|
cls = MonitorFailures
|
||||||
cls.__qualname__ = cls.__name__ = "MonitorFailures<%s>(%s)" \
|
cls.__qualname__ = cls.__name__ = "MonitorFailures<%s>(%s)" \
|
||||||
|
@ -1640,6 +1645,7 @@ class GetFailures(LogCaptureTestCase):
|
||||||
[u'Aug 14 11:%d:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:141.3.81.106 port 51332 ssh2'
|
[u'Aug 14 11:%d:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:141.3.81.106 port 51332 ssh2'
|
||||||
% m for m in 53, 54, 57, 58])
|
% m for m in 53, 54, 57, 58])
|
||||||
|
|
||||||
|
self.filter.setMaxRetry(4)
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_02, autoSeek=0)
|
self.filter.addLogPath(GetFailures.FILENAME_02, autoSeek=0)
|
||||||
self.filter.addFailRegex(r"Failed .* from <HOST>")
|
self.filter.addFailRegex(r"Failed .* from <HOST>")
|
||||||
self.filter.getFailures(GetFailures.FILENAME_02)
|
self.filter.getFailures(GetFailures.FILENAME_02)
|
||||||
|
@ -1648,6 +1654,7 @@ class GetFailures(LogCaptureTestCase):
|
||||||
def testGetFailures03(self):
|
def testGetFailures03(self):
|
||||||
output = ('203.162.223.135', 6, 1124013600.0)
|
output = ('203.162.223.135', 6, 1124013600.0)
|
||||||
|
|
||||||
|
self.filter.setMaxRetry(6)
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_03, autoSeek=0)
|
self.filter.addLogPath(GetFailures.FILENAME_03, autoSeek=0)
|
||||||
self.filter.addFailRegex(r"error,relay=<HOST>,.*550 User unknown")
|
self.filter.addFailRegex(r"error,relay=<HOST>,.*550 User unknown")
|
||||||
self.filter.getFailures(GetFailures.FILENAME_03)
|
self.filter.getFailures(GetFailures.FILENAME_03)
|
||||||
|
@ -1656,6 +1663,7 @@ class GetFailures(LogCaptureTestCase):
|
||||||
def testGetFailures03_InOperation(self):
|
def testGetFailures03_InOperation(self):
|
||||||
output = ('203.162.223.135', 9, 1124013600.0)
|
output = ('203.162.223.135', 9, 1124013600.0)
|
||||||
|
|
||||||
|
self.filter.setMaxRetry(9)
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_03, autoSeek=0)
|
self.filter.addLogPath(GetFailures.FILENAME_03, autoSeek=0)
|
||||||
self.filter.addFailRegex(r"error,relay=<HOST>,.*550 User unknown")
|
self.filter.addFailRegex(r"error,relay=<HOST>,.*550 User unknown")
|
||||||
self.filter.getFailures(GetFailures.FILENAME_03, inOperation=True)
|
self.filter.getFailures(GetFailures.FILENAME_03, inOperation=True)
|
||||||
|
@ -1673,7 +1681,7 @@ class GetFailures(LogCaptureTestCase):
|
||||||
def testGetFailures03_Seek2(self):
|
def testGetFailures03_Seek2(self):
|
||||||
# same test as above but with seek to 'Aug 14 11:59:04' - so other output ...
|
# same test as above but with seek to 'Aug 14 11:59:04' - so other output ...
|
||||||
output = ('203.162.223.135', 2, 1124013600.0)
|
output = ('203.162.223.135', 2, 1124013600.0)
|
||||||
self.filter.setMaxRetry(1)
|
self.filter.setMaxRetry(2)
|
||||||
|
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_03, autoSeek=output[2])
|
self.filter.addLogPath(GetFailures.FILENAME_03, autoSeek=output[2])
|
||||||
self.filter.addFailRegex(r"error,relay=<HOST>,.*550 User unknown")
|
self.filter.addFailRegex(r"error,relay=<HOST>,.*550 User unknown")
|
||||||
|
@ -1683,10 +1691,12 @@ class GetFailures(LogCaptureTestCase):
|
||||||
def testGetFailures04(self):
|
def testGetFailures04(self):
|
||||||
# because of not exact time in testcase04.log (no year), we should always use our test time:
|
# because of not exact time in testcase04.log (no year), we should always use our test time:
|
||||||
self.assertEqual(MyTime.time(), 1124013600)
|
self.assertEqual(MyTime.time(), 1124013600)
|
||||||
# should find exact 4 failures for *.186 and 2 failures for *.185
|
# should find exact 4 failures for *.186 and 2 failures for *.185, but maxretry is 2, so 3 tickets:
|
||||||
output = (('212.41.96.186', 4, 1124013600.0),
|
output = (
|
||||||
('212.41.96.185', 2, 1124013598.0))
|
('212.41.96.186', 2, 1124013480.0),
|
||||||
|
('212.41.96.186', 2, 1124013600.0),
|
||||||
|
('212.41.96.185', 2, 1124013598.0)
|
||||||
|
)
|
||||||
# speedup search using exact date pattern:
|
# speedup search using exact date pattern:
|
||||||
self.filter.setDatePattern((r'^%ExY(?P<_sep>[-/.])%m(?P=_sep)%d[T ]%H:%M:%S(?:[.,]%f)?(?:\s*%z)?',
|
self.filter.setDatePattern((r'^%ExY(?P<_sep>[-/.])%m(?P=_sep)%d[T ]%H:%M:%S(?:[.,]%f)?(?:\s*%z)?',
|
||||||
r'^(?:%a )?%b %d %H:%M:%S(?:\.%f)?(?: %ExY)?',
|
r'^(?:%a )?%b %d %H:%M:%S(?:\.%f)?(?: %ExY)?',
|
||||||
|
@ -1743,9 +1753,11 @@ class GetFailures(LogCaptureTestCase):
|
||||||
unittest.F2B.SkipIfNoNetwork()
|
unittest.F2B.SkipIfNoNetwork()
|
||||||
# We should still catch failures with usedns = no ;-)
|
# We should still catch failures with usedns = no ;-)
|
||||||
output_yes = (
|
output_yes = (
|
||||||
('93.184.216.34', 2, 1124013539.0,
|
('93.184.216.34', 1, 1124013299.0,
|
||||||
[u'Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2',
|
[u'Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2']
|
||||||
u'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.34 port 51332 ssh2']
|
),
|
||||||
|
('93.184.216.34', 1, 1124013539.0,
|
||||||
|
[u'Aug 14 11:58:59 i60p295 sshd[12365]: Failed publickey for roehl from ::ffff:93.184.216.34 port 51332 ssh2']
|
||||||
),
|
),
|
||||||
('2606:2800:220:1:248:1893:25c8:1946', 1, 1124013299.0,
|
('2606:2800:220:1:248:1893:25c8:1946', 1, 1124013299.0,
|
||||||
[u'Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2']
|
[u'Aug 14 11:54:59 i60p295 sshd[12365]: Failed publickey for roehl from example.com port 51332 ssh2']
|
||||||
|
@ -1779,8 +1791,11 @@ class GetFailures(LogCaptureTestCase):
|
||||||
_assert_correct_last_attempt(self, filter_, output)
|
_assert_correct_last_attempt(self, filter_, output)
|
||||||
|
|
||||||
def testGetFailuresMultiRegex(self):
|
def testGetFailuresMultiRegex(self):
|
||||||
output = ('141.3.81.106', 8, 1124013541.0)
|
output = [
|
||||||
|
('141.3.81.106', 8, 1124013541.0)
|
||||||
|
]
|
||||||
|
|
||||||
|
self.filter.setMaxRetry(8)
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_02, autoSeek=False)
|
self.filter.addLogPath(GetFailures.FILENAME_02, autoSeek=False)
|
||||||
self.filter.addFailRegex(r"Failed .* from <HOST>")
|
self.filter.addFailRegex(r"Failed .* from <HOST>")
|
||||||
self.filter.addFailRegex(r"Accepted .* from <HOST>")
|
self.filter.addFailRegex(r"Accepted .* from <HOST>")
|
||||||
|
@ -1798,26 +1813,25 @@ class GetFailures(LogCaptureTestCase):
|
||||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||||
|
|
||||||
def testGetFailuresMultiLine(self):
|
def testGetFailuresMultiLine(self):
|
||||||
output = [("192.0.43.10", 2, 1124013599.0),
|
output = [
|
||||||
("192.0.43.11", 1, 1124013598.0)]
|
("192.0.43.10", 1, 1124013598.0),
|
||||||
|
("192.0.43.10", 1, 1124013599.0),
|
||||||
|
("192.0.43.11", 1, 1124013598.0)
|
||||||
|
]
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE, autoSeek=False)
|
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE, autoSeek=False)
|
||||||
self.filter.setMaxLines(100)
|
self.filter.setMaxLines(100)
|
||||||
self.filter.addFailRegex(r"^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
self.filter.addFailRegex(r"^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
||||||
self.filter.setMaxRetry(1)
|
self.filter.setMaxRetry(1)
|
||||||
|
|
||||||
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
||||||
|
|
||||||
foundList = []
|
_assert_correct_last_attempt(self, self.filter, output)
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
foundList.append(
|
|
||||||
_ticket_tuple(self.filter.failManager.toBan())[0:3])
|
|
||||||
except FailManagerEmpty:
|
|
||||||
break
|
|
||||||
self.assertSortedEqual(foundList, output)
|
|
||||||
|
|
||||||
def testGetFailuresMultiLineIgnoreRegex(self):
|
def testGetFailuresMultiLineIgnoreRegex(self):
|
||||||
output = [("192.0.43.10", 2, 1124013599.0)]
|
output = [
|
||||||
|
("192.0.43.10", 1, 1124013598.0),
|
||||||
|
("192.0.43.10", 1, 1124013599.0)
|
||||||
|
]
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE, autoSeek=False)
|
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE, autoSeek=False)
|
||||||
self.filter.setMaxLines(100)
|
self.filter.setMaxLines(100)
|
||||||
self.filter.addFailRegex(r"^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
self.filter.addFailRegex(r"^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
||||||
|
@ -1826,14 +1840,17 @@ class GetFailures(LogCaptureTestCase):
|
||||||
|
|
||||||
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
||||||
|
|
||||||
_assert_correct_last_attempt(self, self.filter, output.pop())
|
_assert_correct_last_attempt(self, self.filter, output)
|
||||||
|
|
||||||
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||||
|
|
||||||
def testGetFailuresMultiLineMultiRegex(self):
|
def testGetFailuresMultiLineMultiRegex(self):
|
||||||
output = [("192.0.43.10", 2, 1124013599.0),
|
output = [
|
||||||
|
("192.0.43.10", 1, 1124013598.0),
|
||||||
|
("192.0.43.10", 1, 1124013599.0),
|
||||||
("192.0.43.11", 1, 1124013598.0),
|
("192.0.43.11", 1, 1124013598.0),
|
||||||
("192.0.43.15", 1, 1124013598.0)]
|
("192.0.43.15", 1, 1124013598.0)
|
||||||
|
]
|
||||||
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE, autoSeek=False)
|
self.filter.addLogPath(GetFailures.FILENAME_MULTILINE, autoSeek=False)
|
||||||
self.filter.setMaxLines(100)
|
self.filter.setMaxLines(100)
|
||||||
self.filter.addFailRegex(r"^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
self.filter.addFailRegex(r"^.*rsyncd\[(?P<pid>\d+)\]: connect from .+ \(<HOST>\)$<SKIPLINES>^.+ rsyncd\[(?P=pid)\]: rsync error: .*$")
|
||||||
|
@ -1842,14 +1859,9 @@ class GetFailures(LogCaptureTestCase):
|
||||||
|
|
||||||
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
self.filter.getFailures(GetFailures.FILENAME_MULTILINE)
|
||||||
|
|
||||||
foundList = []
|
_assert_correct_last_attempt(self, self.filter, output)
|
||||||
while True:
|
|
||||||
try:
|
self.assertRaises(FailManagerEmpty, self.filter.failManager.toBan)
|
||||||
foundList.append(
|
|
||||||
_ticket_tuple(self.filter.failManager.toBan())[0:3])
|
|
||||||
except FailManagerEmpty:
|
|
||||||
break
|
|
||||||
self.assertSortedEqual(foundList, output)
|
|
||||||
|
|
||||||
|
|
||||||
class DNSUtilsTests(unittest.TestCase):
|
class DNSUtilsTests(unittest.TestCase):
|
||||||
|
|
Loading…
Reference in New Issue