mirror of
https://github.com/fail2ban/fail2ban.git
synced 2026-03-11 08:55:31 +00:00
Merge branch 'master' into k0ka/firewalld
This commit is contained in:
commit
370cf94aeb
23 changed files with 186 additions and 56 deletions
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -1,7 +1,8 @@
|
|||
Before submitting your PR, please review the following checklist:
|
||||
|
||||
- [ ] **CHOOSE CORRECT BRANCH**: if filing a bugfix/enhancement
|
||||
against 0.9.x series, choose `master` branch
|
||||
against certain release version, choose `0.9`, `0.10` or `0.11` branch,
|
||||
for dev-edition use `master` branch
|
||||
- [ ] **CONSIDER adding a unit test** if your PR resolves an issue
|
||||
- [ ] **LIST ISSUES** this PR resolves
|
||||
- [ ] **MAKE SURE** this PR doesn't break existing tests
|
||||
|
|
|
|||
17
ChangeLog
17
ChangeLog
|
|
@ -6,6 +6,23 @@
|
|||
Fail2Ban: Changelog
|
||||
===================
|
||||
|
||||
ver. 1.0.1-dev-1 (20??/??/??) - development nightly edition
|
||||
-----------
|
||||
|
||||
### Compatibility:
|
||||
* to v.0.11:
|
||||
- due to change of `actioncheck` behavior (gh-488), some actions can be incompatible as regards
|
||||
the invariant check, if `actionban` or `actionunban` would not throw an error (exit code
|
||||
different from 0) in case of unsane environment.
|
||||
|
||||
### Fixes
|
||||
|
||||
### New Features and Enhancements
|
||||
* `actioncheck` behavior is changed now (gh-488), so invariant check as well as restore or repair
|
||||
of sane environment (in case of recognized unsane state) would only occur on action errors (e. g.
|
||||
if ban or unban operations are exiting with other code as 0)
|
||||
|
||||
|
||||
ver. 0.11.2 (2020/11/23) - heal-the-world-with-security-tools
|
||||
-----------
|
||||
|
||||
|
|
|
|||
14
README.md
14
README.md
|
|
@ -2,7 +2,7 @@
|
|||
/ _|__ _(_) |_ ) |__ __ _ _ _
|
||||
| _/ _` | | |/ /| '_ \/ _` | ' \
|
||||
|_| \__,_|_|_/___|_.__/\__,_|_||_|
|
||||
v0.11.0.dev1 20??/??/??
|
||||
v1.0.1.dev1 20??/??/??
|
||||
|
||||
## Fail2Ban: ban hosts that cause multiple authentication errors
|
||||
|
||||
|
|
@ -46,11 +46,11 @@ Optional:
|
|||
|
||||
To install:
|
||||
|
||||
tar xvfj fail2ban-0.11.0.tar.bz2
|
||||
cd fail2ban-0.11.0
|
||||
tar xvfj fail2ban-1.0.1.tar.bz2
|
||||
cd fail2ban-1.0.1
|
||||
sudo python setup.py install
|
||||
|
||||
Alternatively, you can clone the source from GitHub to a directory of Your choice, and do the install from there. Pick the correct branch, for example, 0.11
|
||||
Alternatively, you can clone the source from GitHub to a directory of Your choice, and do the install from there. Pick the correct branch, for example, master or 0.11
|
||||
|
||||
git clone https://github.com/fail2ban/fail2ban.git
|
||||
cd fail2ban
|
||||
|
|
@ -89,11 +89,11 @@ fail2ban(1) and jail.conf(5) manpages for further references.
|
|||
Code status:
|
||||
------------
|
||||
|
||||
* travis-ci.org: [](https://travis-ci.org/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [](https://travis-ci.org/fail2ban/fail2ban?branch=0.10) (0.10 branch)
|
||||
* travis-ci.org: [](https://travis-ci.org/fail2ban/fail2ban?branch=master) / [](https://travis-ci.org/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [](https://travis-ci.org/fail2ban/fail2ban?branch=0.10) (0.10 branch)
|
||||
|
||||
* coveralls.io: [](https://coveralls.io/github/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [](https://coveralls.io/github/fail2ban/fail2ban?branch=0.10) / (0.10 branch)
|
||||
* coveralls.io: [](https://coveralls.io/github/fail2ban/fail2ban?branch=master) / [](https://coveralls.io/github/fail2ban/fail2ban?branch=0.11) (0.11 branch) / [](https://coveralls.io/github/fail2ban/fail2ban?branch=0.10) / (0.10 branch)
|
||||
|
||||
* codecov.io: [](https://codecov.io/gh/fail2ban/fail2ban/branch/0.11) (0.11 branch) / [](https://codecov.io/gh/fail2ban/fail2ban/branch/0.10) (0.10 branch)
|
||||
* codecov.io: [](https://codecov.io/gh/fail2ban/fail2ban/branch/master) / [](https://codecov.io/gh/fail2ban/fail2ban/branch/0.11) (0.11 branch) / [](https://codecov.io/gh/fail2ban/fail2ban/branch/0.10) (0.10 branch)
|
||||
|
||||
Contact:
|
||||
--------
|
||||
|
|
|
|||
14
config/filter.d/nginx-bad-request.conf
Normal file
14
config/filter.d/nginx-bad-request.conf
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# Fail2Ban filter to match bad requests to nginx
|
||||
#
|
||||
|
||||
[Definition]
|
||||
|
||||
# The request often doesn't contain a method, only some encoded garbage
|
||||
# This will also match requests that are entirely empty
|
||||
failregex = ^<HOST> - \S+ \[\] "[^"]*" 400
|
||||
|
||||
datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
|
||||
^[^\[]*\[({DATE})
|
||||
{^LN-BEG}
|
||||
|
||||
# Author: Jan Przybylak
|
||||
|
|
@ -37,7 +37,9 @@ mdre-rbl = ^RCPT from [^[]*\[<HOST>\]%(_port)s: [45]54 [45]\.7\.1 Service unava
|
|||
mdpr-more = %(mdpr-normal)s
|
||||
mdre-more = %(mdre-normal)s
|
||||
|
||||
mdpr-ddos = (?:lost connection after(?! DATA) [A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+)))
|
||||
# Includes some of the log messages described in
|
||||
# <http://www.postfix.org/POSTSCREEN_README.html>.
|
||||
mdpr-ddos = (?:lost connection after(?! DATA) [A-Z]+|disconnect(?= from \S+(?: \S+=\d+)* auth=0/(?:[1-9]|\d\d+))|(?:PREGREET \d+|HANGUP) after \S+)
|
||||
mdre-ddos = ^from [^[]*\[<HOST>\]%(_port)s:?
|
||||
|
||||
mdpr-extra = (?:%(mdpr-auth)s|%(mdpr-normal)s)
|
||||
|
|
|
|||
|
|
@ -392,7 +392,10 @@ logpath = %(nginx_error_log)s
|
|||
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
[nginx-bad-request]
|
||||
port = http,https
|
||||
logpath = %(nginx_access_log)s
|
||||
|
||||
|
||||
# Ban attackers that try to use PHP's URL-fopen() functionality
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ class Fail2banClient(Fail2banCmdLine, Thread):
|
|||
logSys.log(5, ' client phase %s', phase)
|
||||
if not stream:
|
||||
return False
|
||||
# wait a litle bit for phase "start-ready" before enter active waiting:
|
||||
# wait a little bit for phase "start-ready" before enter active waiting:
|
||||
if phase is not None:
|
||||
Utils.wait_for(lambda: phase.get('start-ready', None) is not None, 0.5, 0.001)
|
||||
phase['configure'] = (True if stream else False)
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ class CommandAction(ActionBase):
|
|||
cmd = self.replaceTag(tag, self._properties,
|
||||
conditional=('family='+family if family else ''),
|
||||
cache=self.__substCache)
|
||||
if '<' not in cmd or not family: return cmd
|
||||
if not family or '<' not in cmd: return cmd
|
||||
# replace family as dynamic tags, important - don't cache, no recursion and auto-escape here:
|
||||
cmd = self.replaceDynamicTags(cmd, {'family':family})
|
||||
return cmd
|
||||
|
|
@ -974,31 +974,38 @@ class CommandAction(ActionBase):
|
|||
except (KeyError, TypeError):
|
||||
family = ''
|
||||
|
||||
# invariant check:
|
||||
if self.actioncheck:
|
||||
# don't repair/restore if unban (no matter):
|
||||
def _beforeRepair():
|
||||
if cmd == '<actionunban>' and not self._properties.get('actionrepair_on_unban'):
|
||||
self._logSys.error("Invariant check failed. Unban is impossible.")
|
||||
repcnt = 0
|
||||
while True:
|
||||
|
||||
# got some error, do invariant check:
|
||||
if repcnt and self.actioncheck:
|
||||
# don't repair/restore if unban (no matter):
|
||||
def _beforeRepair():
|
||||
if cmd == '<actionunban>' and not self._properties.get('actionrepair_on_unban'):
|
||||
self._logSys.error("Invariant check failed. Unban is impossible.")
|
||||
return False
|
||||
return True
|
||||
# check and repair if broken:
|
||||
ret = self._invariantCheck(family, _beforeRepair, forceStart=(cmd != '<actionunban>'))
|
||||
# if not sane (and not restored) return:
|
||||
if ret != 1:
|
||||
return False
|
||||
return True
|
||||
# check and repair if broken:
|
||||
ret = self._invariantCheck(family, _beforeRepair, forceStart=(cmd != '<actionunban>'))
|
||||
# if not sane (and not restored) return:
|
||||
if ret != 1:
|
||||
return False
|
||||
|
||||
# Replace static fields
|
||||
realCmd = self.replaceTag(cmd, self._properties,
|
||||
conditional=('family='+family if family else ''), cache=self.__substCache)
|
||||
# Replace static fields
|
||||
realCmd = self.replaceTag(cmd, self._properties,
|
||||
conditional=('family='+family if family else ''), cache=self.__substCache)
|
||||
|
||||
# Replace dynamical tags, important - don't cache, no recursion and auto-escape here
|
||||
if aInfo is not None:
|
||||
realCmd = self.replaceDynamicTags(realCmd, aInfo)
|
||||
else:
|
||||
realCmd = cmd
|
||||
# Replace dynamical tags, important - don't cache, no recursion and auto-escape here
|
||||
if aInfo is not None:
|
||||
realCmd = self.replaceDynamicTags(realCmd, aInfo)
|
||||
else:
|
||||
realCmd = cmd
|
||||
|
||||
return self.executeCmd(realCmd, self.timeout)
|
||||
# try execute command:
|
||||
ret = self.executeCmd(realCmd, self.timeout)
|
||||
repcnt += 1
|
||||
if ret or repcnt > 1:
|
||||
return ret
|
||||
|
||||
@staticmethod
|
||||
def executeCmd(realCmd, timeout=60, **kwargs):
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ class ObserverThread(JailThread):
|
|||
if self._paused:
|
||||
continue
|
||||
else:
|
||||
## notify event deleted (shutdown) - just sleep a litle bit (waiting for shutdown events, prevent high cpu usage)
|
||||
## notify event deleted (shutdown) - just sleep a little bit (waiting for shutdown events, prevent high cpu usage)
|
||||
time.sleep(ObserverThread.DEFAULT_SLEEP_INTERVAL)
|
||||
## stop by shutdown and empty queue :
|
||||
if not self.is_full:
|
||||
|
|
|
|||
|
|
@ -234,16 +234,12 @@ def reGroupDictStrptime(found_dict, msec=False, default_tz=None):
|
|||
week_of_year = int(val)
|
||||
# U starts week on Sunday, W - on Monday
|
||||
week_of_year_start = 6 if key == 'U' else 0
|
||||
elif key == 'z':
|
||||
elif key in ('z', 'Z'):
|
||||
z = val
|
||||
if z in ("Z", "UTC", "GMT"):
|
||||
tzoffset = 0
|
||||
else:
|
||||
tzoffset = zone2offset(z, 0); # currently offset-based only
|
||||
elif key == 'Z':
|
||||
z = val
|
||||
if z in ("UTC", "GMT"):
|
||||
tzoffset = 0
|
||||
|
||||
# Fail2Ban will assume it's this year
|
||||
assume_year = False
|
||||
|
|
|
|||
|
|
@ -217,6 +217,9 @@ class ExecuteActions(LogCaptureTestCase):
|
|||
# flush for inet6 is intentionally "broken" here - test no unhandled except and invariant check:
|
||||
act['actionflush?family=inet6'] = act.actionflush + '; exit 1'
|
||||
act.actionstart_on_demand = True
|
||||
# force errors via check in ban/unban:
|
||||
act.actionban = "<actioncheck> ; " + act.actionban
|
||||
act.actionunban = "<actioncheck> ; " + act.actionunban
|
||||
self.__actions.start()
|
||||
self.assertNotLogged("stdout: %r" % 'ip start')
|
||||
|
||||
|
|
@ -294,6 +297,9 @@ class ExecuteActions(LogCaptureTestCase):
|
|||
act['actionflush?family=inet6'] = act.actionflush + '; exit 1'
|
||||
act.actionstart_on_demand = True
|
||||
act.actionrepair_on_unban = True
|
||||
# force errors via check in ban/unban:
|
||||
act.actionban = "<actioncheck> ; " + act.actionban
|
||||
act.actionunban = "<actioncheck> ; " + act.actionunban
|
||||
self.__actions.start()
|
||||
self.assertNotLogged("stdout: %r" % 'ip start')
|
||||
|
||||
|
|
|
|||
|
|
@ -305,8 +305,8 @@ class CommandActionTest(LogCaptureTestCase):
|
|||
self.assertEqual(self.__action.actionstart, "touch '%s'" % tmp)
|
||||
self.__action.actionstop = "rm -f '%s'" % tmp
|
||||
self.assertEqual(self.__action.actionstop, "rm -f '%s'" % tmp)
|
||||
self.__action.actionban = "echo -n"
|
||||
self.assertEqual(self.__action.actionban, 'echo -n')
|
||||
self.__action.actionban = "<actioncheck> && echo -n"
|
||||
self.assertEqual(self.__action.actionban, "<actioncheck> && echo -n")
|
||||
self.__action.actioncheck = "[ -e '%s' ]" % tmp
|
||||
self.assertEqual(self.__action.actioncheck, "[ -e '%s' ]" % tmp)
|
||||
self.__action.actionunban = "true"
|
||||
|
|
@ -316,6 +316,7 @@ class CommandActionTest(LogCaptureTestCase):
|
|||
self.assertNotLogged('returned')
|
||||
# no action was actually executed yet
|
||||
|
||||
# start on demand is false, so it should cause failure on first attempt of ban:
|
||||
self.__action.ban({'ip': None})
|
||||
self.assertLogged('Invariant check failed')
|
||||
self.assertLogged('returned successfully')
|
||||
|
|
@ -365,12 +366,51 @@ class CommandActionTest(LogCaptureTestCase):
|
|||
self.pruneLog('[phase 2]')
|
||||
self.__action.actionstart = "touch '%s'" % tmp
|
||||
self.__action.actionstop = "rm '%s'" % tmp
|
||||
self.__action.actionban = """printf "%%%%b\n" <ip> >> '%s'""" % tmp
|
||||
self.__action.actionban = """<actioncheck> && printf "%%%%b\n" <ip> >> '%s'""" % tmp
|
||||
self.__action.actioncheck = "[ -e '%s' ]" % tmp
|
||||
self.__action.ban({'ip': None})
|
||||
self.assertLogged('Invariant check failed')
|
||||
self.assertNotLogged('Unable to restore environment')
|
||||
|
||||
@with_tmpdir
|
||||
def testExecuteActionCheckOnBanFailure(self, tmp):
|
||||
tmp += '/fail2ban.test'
|
||||
self.__action.actionstart = "touch '%s'; echo 'started ...'" % tmp
|
||||
self.__action.actionstop = "rm -f '%s'" % tmp
|
||||
self.__action.actionban = "[ -e '%s' ] && echo 'banned '<ip>" % tmp
|
||||
self.__action.actioncheck = "[ -e '%s' ] && echo 'check ok' || { echo 'check failed'; exit 1; }" % tmp
|
||||
self.__action.actionrepair = "echo 'repair ...'; touch '%s'" % tmp
|
||||
self.__action.actionstart_on_demand = False
|
||||
self.__action.start()
|
||||
# phase 1: with repair;
|
||||
# phase 2: without repair (start/stop), not on demand;
|
||||
# phase 3: without repair (start/stop), start on demand.
|
||||
for i in (1, 2, 3):
|
||||
self.pruneLog('[phase %s]' % i)
|
||||
# 1st time with success ban:
|
||||
self.__action.ban({'ip': '192.0.2.1'})
|
||||
self.assertLogged(
|
||||
"stdout: %r" % 'banned 192.0.2.1', all=True)
|
||||
self.assertNotLogged("Invariant check failed. Trying",
|
||||
"stdout: %r" % 'check failed',
|
||||
"stdout: %r" % ('repair ...' if self.__action.actionrepair else 'started ...'),
|
||||
"stdout: %r" % 'check ok', all=True)
|
||||
# force error in ban:
|
||||
os.remove(tmp)
|
||||
self.pruneLog()
|
||||
# 2nd time with fail recognition, success repair, check and ban:
|
||||
self.__action.ban({'ip': '192.0.2.2'})
|
||||
self.assertLogged("Invariant check failed. Trying",
|
||||
"stdout: %r" % 'check failed',
|
||||
"stdout: %r" % ('repair ...' if self.__action.actionrepair else 'started ...'),
|
||||
"stdout: %r" % 'check ok',
|
||||
"stdout: %r" % 'banned 192.0.2.2', all=True)
|
||||
# repeat without repair (stop/start), herafter enable on demand:
|
||||
if self.__action.actionrepair:
|
||||
self.__action.actionrepair = ""
|
||||
elif not self.__action.actionstart_on_demand:
|
||||
self.__action.actionstart_on_demand = True
|
||||
|
||||
@with_tmpdir
|
||||
def testExecuteActionCheckRepairEnvironment(self, tmp):
|
||||
tmp += '/fail2ban.test'
|
||||
|
|
|
|||
|
|
@ -516,6 +516,9 @@ class CustomDateFormatsTest(unittest.TestCase):
|
|||
(1072746123.0 - 3600, "{^LN-BEG}%ExY-%Exm-%Exd %ExH:%ExM:%ExS(?: %Z)?", "[2003-12-30 01:02:03] server ..."),
|
||||
(1072746123.0, "{^LN-BEG}%ExY-%Exm-%Exd %ExH:%ExM:%ExS(?: %z)?", "[2003-12-30 01:02:03 UTC] server ..."),
|
||||
(1072746123.0, "{^LN-BEG}%ExY-%Exm-%Exd %ExH:%ExM:%ExS(?: %Z)?", "[2003-12-30 01:02:03 UTC] server ..."),
|
||||
(1072746123.0, "{^LN-BEG}%ExY-%Exm-%Exd %ExH:%ExM:%ExS(?: %z)?", "[2003-12-30 01:02:03 Z] server ..."),
|
||||
(1072746123.0, "{^LN-BEG}%ExY-%Exm-%Exd %ExH:%ExM:%ExS(?: %z)?", "[2003-12-30 01:02:03 +0000] server ..."),
|
||||
(1072746123.0, "{^LN-BEG}%ExY-%Exm-%Exd %ExH:%ExM:%ExS(?: %Z)?", "[2003-12-30 01:02:03 Z] server ..."),
|
||||
):
|
||||
logSys.debug('== test: %r', (matched, dp, line))
|
||||
if dp is None:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Previous version --
|
||||
# failJSON: { "time": "2005-04-16T21:05:29", "match": true , "host": "69.93.127.111" }
|
||||
# failJSON: { "time": "2005-04-17T06:05:29", "match": true , "host": "69.93.127.111" }
|
||||
[PDT Apr 16 21:05:29] error : Warning: Client '69.93.127.111' supplied unknown user 'foo' accessing monit httpd
|
||||
# failJSON: { "time": "2005-04-16T20:59:33", "match": true , "host": "97.113.189.111" }
|
||||
# failJSON: { "time": "2005-04-17T05:59:33", "match": true , "host": "97.113.189.111" }
|
||||
[PDT Apr 16 20:59:33] error : Warning: Client '97.113.189.111' supplied wrong password for user 'admin' accessing monit httpd
|
||||
|
||||
# Current version -- corresponding "https://bitbucket.org/tildeslash/monit/src/6905335aa903d425cae732cab766bd88ea5f2d1d/src/http/processor.c?at=master&fileviewer=file-view-default#processor.c-728"
|
||||
|
|
|
|||
23
fail2ban/tests/files/logs/nginx-bad-request
Normal file
23
fail2ban/tests/files/logs/nginx-bad-request
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# failJSON: { "time": "2015-01-20T19:53:28", "match": true , "host": "12.34.56.78" }
|
||||
12.34.56.78 - - [20/Jan/2015:19:53:28 +0100] "" 400 47 "-" "-" "-"
|
||||
|
||||
# failJSON: { "time": "2015-01-20T19:53:28", "match": true , "host": "12.34.56.78" }
|
||||
12.34.56.78 - root [20/Jan/2015:19:53:28 +0100] "" 400 47 "-" "-" "-"
|
||||
|
||||
# failJSON: { "time": "2015-01-20T19:53:28", "match": true , "host": "12.34.56.78" }
|
||||
12.34.56.78 - - [20/Jan/2015:19:53:28 +0100] "\x03\x00\x00/*\xE0\x00\x00\x00\x00\x00Cookie: mstshash=Administr" 400 47 "-" "-" "-"
|
||||
|
||||
# failJSON: { "time": "2015-01-20T19:53:28", "match": true , "host": "12.34.56.78" }
|
||||
12.34.56.78 - - [20/Jan/2015:19:53:28 +0100] "GET //admin/pma/scripts/setup.php HTTP/1.1" 400 47 "-" "-" "-"
|
||||
|
||||
# failJSON: { "time": "2015-01-20T19:54:28", "match": true , "host": "12.34.56.78" }
|
||||
12.34.56.78 - - [20/Jan/2015:19:54:28 +0100] "HELP" 400 47 "-" "-" "-"
|
||||
|
||||
# failJSON: { "time": "2015-01-20T19:55:28", "match": true , "host": "12.34.56.78" }
|
||||
12.34.56.78 - - [20/Jan/2015:19:55:28 +0100] "batman" 400 47 "-" "-" "-"
|
||||
|
||||
# failJSON: { "time": "2015-01-20T01:17:07", "match": true , "host": "7.8.9.10" }
|
||||
7.8.9.10 - root [20/Jan/2015:01:17:07 +0100] "CONNECT 123.123.123.123 HTTP/1.1" 400 162 "-" "-" "-"
|
||||
|
||||
# failJSON: { "time": "2014-12-12T22:59:02", "match": true , "host": "2.5.2.5" }
|
||||
2.5.2.5 - tomcat [12/Dec/2014:22:59:02 +0100] "GET /cgi-bin/tools/tools.pl HTTP/1.1" 400 162 "-" "-" "-"
|
||||
|
|
@ -151,6 +151,11 @@ Feb 18 09:48:04 xxx postfix/smtpd[23]: lost connection after AUTH from unknown[1
|
|||
# failJSON: { "time": "2005-02-18T09:48:04", "match": true , "host": "192.0.2.23" }
|
||||
Feb 18 09:48:04 xxx postfix/smtpd[23]: lost connection after AUTH from unknown[192.0.2.23]
|
||||
|
||||
# failJSON: { "time": "2004-12-23T19:39:13", "match": true , "host": "192.0.2.2" }
|
||||
Dec 23 19:39:13 xxx postfix/postscreen[21057]: PREGREET 14 after 0.08 from [192.0.2.2]:59415: EHLO ylmf-pc\r\n
|
||||
# failJSON: { "time": "2004-12-24T00:54:36", "match": true , "host": "192.0.2.3" }
|
||||
Dec 24 00:54:36 xxx postfix/postscreen[22515]: HANGUP after 16 from [192.0.2.3]:48119 in tests after SMTP handshake
|
||||
|
||||
# filterOptions: [{}, {"mode": "ddos"}, {"mode": "aggressive"}]
|
||||
# failJSON: { "match": false, "desc": "don't affect lawful data (sporadical connection aborts within DATA-phase, see gh-1813 for discussion)" }
|
||||
Feb 18 09:50:05 xxx postfix/smtpd[42]: lost connection after DATA from good-host.example.com[192.0.2.10]
|
||||
|
|
|
|||
|
|
@ -2066,25 +2066,38 @@ class ServerConfigReaderTests(LogCaptureTestCase):
|
|||
action.ban(aInfos['ipv4'])
|
||||
if tests.get('ip4-start'): self.assertLogged(*tests.get('*-start', ())+tests['ip4-start'], all=True)
|
||||
if tests.get('ip6-start'): self.assertNotLogged(*tests['ip6-start'], all=True)
|
||||
self.assertLogged(*tests.get('ip4-check',())+tests['ip4-ban'], all=True)
|
||||
self.assertLogged(*tests['ip4-ban'], all=True)
|
||||
self.assertNotLogged(*tests['ip6'], all=True)
|
||||
# test unban ip4 :
|
||||
self.pruneLog('# === unban ipv4 ===')
|
||||
action.unban(aInfos['ipv4'])
|
||||
self.assertLogged(*tests.get('ip4-check',())+tests['ip4-unban'], all=True)
|
||||
self.assertLogged(*tests['ip4-unban'], all=True)
|
||||
self.assertNotLogged(*tests['ip6'], all=True)
|
||||
# test ban ip6 :
|
||||
self.pruneLog('# === ban ipv6 ===')
|
||||
action.ban(aInfos['ipv6'])
|
||||
if tests.get('ip6-start'): self.assertLogged(*tests.get('*-start', ())+tests['ip6-start'], all=True)
|
||||
if tests.get('ip4-start'): self.assertNotLogged(*tests['ip4-start'], all=True)
|
||||
self.assertLogged(*tests.get('ip6-check',())+tests['ip6-ban'], all=True)
|
||||
self.assertLogged(*tests['ip6-ban'], all=True)
|
||||
self.assertNotLogged(*tests['ip4'], all=True)
|
||||
# test unban ip6 :
|
||||
self.pruneLog('# === unban ipv6 ===')
|
||||
action.unban(aInfos['ipv6'])
|
||||
self.assertLogged(*tests.get('ip6-check',())+tests['ip6-unban'], all=True)
|
||||
self.assertLogged(*tests['ip6-unban'], all=True)
|
||||
self.assertNotLogged(*tests['ip4'], all=True)
|
||||
# test invariant check (normally on demand in error case only):
|
||||
if tests.get('ip4-check'):
|
||||
self.pruneLog('# === check ipv4 ===')
|
||||
action._invariantCheck(aInfos['ipv4']['family'])
|
||||
self.assertLogged(*tests['ip4-check'], all=True)
|
||||
if tests.get('ip6-check') and tests['ip6-check'] != tests['ip4-check']:
|
||||
self.assertNotLogged(*tests['ip6-check'], all=True)
|
||||
if tests.get('ip6-check'):
|
||||
self.pruneLog('# === check ipv6 ===')
|
||||
action._invariantCheck(aInfos['ipv6']['family'])
|
||||
self.assertLogged(*tests['ip6-check'], all=True)
|
||||
if tests.get('ip4-check') and tests['ip4-check'] != tests['ip6-check']:
|
||||
self.assertNotLogged(*tests['ip4-check'], all=True)
|
||||
# test flush for actions should supported this:
|
||||
if tests.get('flush'):
|
||||
self.pruneLog('# === flush ===')
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ __author__ = "Cyril Jaquier, Yaroslav Halchenko, Steven Hiscocks, Daniel Black"
|
|||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2005-2016 Yaroslav Halchenko, 2013-2014 Steven Hiscocks, Daniel Black"
|
||||
__license__ = "GPL-v2+"
|
||||
|
||||
version = "0.11.2"
|
||||
version = "1.0.1.dev1"
|
||||
|
||||
def normVersion():
|
||||
""" Returns fail2ban version in normalized machine-readable format"""
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
|
||||
.TH FAIL2BAN-CLIENT "1" "November 2020" "fail2ban-client v0.11.2" "User Commands"
|
||||
.TH FAIL2BAN-CLIENT "1" "February 2020" "fail2ban-client v1.0.1.dev1" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-client \- configure and control the server
|
||||
.SH SYNOPSIS
|
||||
.B fail2ban-client
|
||||
[\fI\,OPTIONS\/\fR] \fI\,<COMMAND>\/\fR
|
||||
.SH DESCRIPTION
|
||||
Fail2Ban v0.11.2 reads log file that contains password failure report
|
||||
Fail2Ban v1.0.1.dev1 reads log file that contains password failure report
|
||||
and bans the corresponding IP addresses using firewall rules.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
|
||||
.TH FAIL2BAN-PYTHON "1" "November 2020" "fail2ban-python 0.11.2" "User Commands"
|
||||
.TH FAIL2BAN-PYTHON "1" "January 2020" "fail2ban-python 1.0.1.1" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-python \- a helper for Fail2Ban to assure that the same Python is used
|
||||
.SH DESCRIPTION
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
|
||||
.TH FAIL2BAN-REGEX "1" "November 2020" "fail2ban-regex 0.11.2" "User Commands"
|
||||
.TH FAIL2BAN-REGEX "1" "January 2020" "fail2ban-regex 1.0.1.dev1" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-regex \- test Fail2ban "failregex" option
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
|
||||
.TH FAIL2BAN-SERVER "1" "November 2020" "fail2ban-server v0.11.2" "User Commands"
|
||||
.TH FAIL2BAN-SERVER "1" "February 2020" "fail2ban-server v1.0.1.dev1" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-server \- start the server
|
||||
.SH SYNOPSIS
|
||||
.B fail2ban-server
|
||||
[\fI\,OPTIONS\/\fR]
|
||||
.SH DESCRIPTION
|
||||
Fail2Ban v0.11.2 reads log file that contains password failure report
|
||||
Fail2Ban v1.0.1.dev1 reads log file that contains password failure report
|
||||
and bans the corresponding IP addresses using firewall rules.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
|
||||
.TH FAIL2BAN-TESTCASES "1" "November 2020" "fail2ban-testcases 0.11.2" "User Commands"
|
||||
.TH FAIL2BAN-TESTCASES "1" "January 2020" "fail2ban-testcases 1.0.1.dev1" "User Commands"
|
||||
.SH NAME
|
||||
fail2ban-testcases \- run Fail2Ban unit-tests
|
||||
.SH SYNOPSIS
|
||||
|
|
|
|||
Loading…
Reference in a new issue