From badf9d03b9fa51f9e409b159bc7717de7e524121 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Sun, 22 Sep 2013 18:12:16 +0100 Subject: [PATCH 1/4] ENH: Allow setting of ISO8601 via datepattern (default for systemd) --- fail2ban/client/beautifier.py | 2 ++ fail2ban/server/filter.py | 19 +++++++++++++------ fail2ban/server/filtersystemd.py | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/fail2ban/client/beautifier.py b/fail2ban/client/beautifier.py index 1c6cdaeb..f2c1fb16 100644 --- a/fail2ban/client/beautifier.py +++ b/fail2ban/client/beautifier.py @@ -123,6 +123,8 @@ class Beautifier: msg = "Current date pattern set to: " if response is None: msg = msg + "Default Detectors" + elif response[0] is None: + msg = msg + "%s" % response[1] else: msg = msg + "%s (%s)" % response elif inC[2] in ("ignoreip", "addignoreip", "delignoreip"): diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index 30ba2649..e1f8613f 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -28,7 +28,7 @@ from failmanager import FailManager from ticket import FailTicket from jailthread import JailThread from datedetector import DateDetector -from datetemplate import DatePatternRegex +from datetemplate import DatePatternRegex, DateISO8601 from mytime import MyTime from failregex import FailRegex, Regex, RegexException @@ -199,11 +199,15 @@ class Filter(JailThread): def setDatePattern(self, pattern): dateDetector = DateDetector() - template = DatePatternRegex() - if pattern[0] == "^": # Special extra to enable anchor - template.setPattern(pattern[1:], anchor=True) + if pattern == "ISO8601": + template = DateISO8601() + template.setName("ISO8601") else: - template.setPattern(pattern, anchor=False) + template = DatePatternRegex() + if pattern[0] == "^": # Special extra to enable anchor + template.setPattern(pattern[1:], anchor=True) + else: + template.setPattern(pattern, anchor=False) dateDetector.appendTemplate(template) self.dateDetector = dateDetector logSys.info("Date pattern set to `%r`: `%s`" % @@ -221,7 +225,10 @@ class Filter(JailThread): if len(templates) > 1: return None # Default Detectors in use elif len(templates) == 1: - pattern = templates[0].getPattern() + if hasattr(templates[0], "getPattern"): + pattern = templates[0].getPattern() + else: + pattern = None if templates[0].getRegex()[0] == "^": pattern = "^" + pattern return pattern, templates[0].getName() diff --git a/fail2ban/server/filtersystemd.py b/fail2ban/server/filtersystemd.py index c0fe9a87..87daa8e6 100644 --- a/fail2ban/server/filtersystemd.py +++ b/fail2ban/server/filtersystemd.py @@ -57,6 +57,7 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover # Initialise systemd-journal connection self.__journal = journal.Reader(converters={'__CURSOR': lambda x: x}) self.__matches = [] + self.setDatePattern("ISO8601") logSys.debug("Created FilterSystemd") From e07df3f7d4eb87e16e040b6ec3c63619d0283f6a Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Sun, 22 Sep 2013 18:14:04 +0100 Subject: [PATCH 2/4] ENH: fail2ban-regex uses ISO8601 when using journal backend Also fix setting of date pattern occurring too early, before filter being created. --- bin/fail2ban-regex | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/bin/fail2ban-regex b/bin/fail2ban-regex index b7d477c4..e54659f7 100755 --- a/bin/fail2ban-regex +++ b/bin/fail2ban-regex @@ -198,16 +198,9 @@ class Fail2banRegex(object): self._print_all_missed = opts.print_all_missed self._print_all_ignored = opts.print_all_ignored self._maxlines_set = False # so we allow to override maxlines in cmdline + self._datepattern_set = False self._journalmatch = None - if opts.datepattern: - self.setDatePattern(opts.datepattern) - - if opts.encoding: - self.encoding = opts.encoding - else: - self.encoding = locale.getpreferredencoding() - self._filter = Filter(None) self._ignoreregex = list() self._failregex = list() @@ -217,9 +210,20 @@ class Fail2banRegex(object): self.setMaxLines(opts.maxlines) if opts.journalmatch is not None: self.setJournalMatch(opts.journalmatch.split()) + if opts.datepattern: + self.setDatePattern(opts.datepattern) + if opts.encoding: + self.encoding = opts.encoding + else: + self.encoding = locale.getpreferredencoding() + + def setDatePattern(self, pattern): - self._filter.setDatePattern(pattern) + if not self._datepattern_set: + self._filter.setDatePattern(pattern) + self._datepattern_set = True + print "Use datepattern : %s" % self._filter.getDatePattern()[1] def setMaxLines(self, v): if not self._maxlines_set: @@ -425,6 +429,11 @@ if __name__ == "__main__": parser = get_opt_parser() (opts, args) = parser.parse_args() + print + print "Running tests" + print "=============" + print + fail2banRegex = Fail2banRegex(opts) # We need 2 or 3 parameters @@ -462,11 +471,6 @@ if __name__ == "__main__": stdout.setFormatter(Formatter(fmt)) logSys.addHandler(stdout) - print - print "Running tests" - print "=============" - print - cmd_log, cmd_regex = args[:2] fail2banRegex.readRegex(cmd_regex, 'fail') or sys.exit(-1) @@ -489,6 +493,7 @@ if __name__ == "__main__": sys.exit(-1) myjournal = journal.Reader(converters={'__CURSOR': lambda x: x}) journalmatch = fail2banRegex._journalmatch + fail2banRegex.setDatePattern("ISO8601") if journalmatch: try: for element in journalmatch: From 9c61adcad72e81d0c9471daad8d5cd84efa48eb5 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Tue, 24 Sep 2013 22:11:04 +0100 Subject: [PATCH 3/4] ENH+DOC: Allow setting of Epoch and TAI64N date pattern Also add this to jail.conf man page --- fail2ban/server/filter.py | 10 ++++++++-- man/jail.conf.5 | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index e1f8613f..7d1bcbaf 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -28,7 +28,7 @@ from failmanager import FailManager from ticket import FailTicket from jailthread import JailThread from datedetector import DateDetector -from datetemplate import DatePatternRegex, DateISO8601 +from datetemplate import DatePatternRegex, DateISO8601, DateEpoch, DateTai64n from mytime import MyTime from failregex import FailRegex, Regex, RegexException @@ -199,9 +199,15 @@ class Filter(JailThread): def setDatePattern(self, pattern): dateDetector = DateDetector() - if pattern == "ISO8601": + if pattern.upper() == "ISO8601": template = DateISO8601() template.setName("ISO8601") + elif pattern.upper() == "EPOCH": + template = DateEpoch() + template.setName("Epoch") + elif patter.upper() == "TAI64N": + template = DateTai64n() + template.setName("TAI64N") else: template = DatePatternRegex() if pattern[0] == "^": # Special extra to enable anchor diff --git a/man/jail.conf.5 b/man/jail.conf.5 index 668530cd..ffad71d5 100644 --- a/man/jail.conf.5 +++ b/man/jail.conf.5 @@ -183,6 +183,9 @@ The following are acceptable format fields (see strptime(3) for descriptions): .nf %% %a %A %b %B %d %H %I %j %m %M %p %S %U %w %W %y %Y .fi +.br + +Also, special values of \fIEpoch\fR (UNIX Timestamp), \fITAI64N\fR and \fIISO8601\fR can be used. .TP \fBjournalmatch\fR specifies the systemd journal match used to filter the journal entries. See \fBjournalctl(1)\fR and \fBsystemd.journal-fields(7)\fR for matches syntax and more details on special journal fields. This option is only valid for the \fIsystemd\fR backend. From 011ccbc6759ef0bff6fc8f773baa7839bbd8f2e8 Mon Sep 17 00:00:00 2001 From: Steven Hiscocks Date: Tue, 24 Sep 2013 22:25:17 +0100 Subject: [PATCH 4/4] TST+BF: Fix bug in Filter.{get,set}DatePattern and improve tests --- fail2ban/server/filter.py | 6 +++--- fail2ban/tests/servertestcase.py | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/fail2ban/server/filter.py b/fail2ban/server/filter.py index 7d1bcbaf..47e87a83 100644 --- a/fail2ban/server/filter.py +++ b/fail2ban/server/filter.py @@ -205,7 +205,7 @@ class Filter(JailThread): elif pattern.upper() == "EPOCH": template = DateEpoch() template.setName("Epoch") - elif patter.upper() == "TAI64N": + elif pattern.upper() == "TAI64N": template = DateTai64n() template.setName("TAI64N") else: @@ -233,10 +233,10 @@ class Filter(JailThread): elif len(templates) == 1: if hasattr(templates[0], "getPattern"): pattern = templates[0].getPattern() + if templates[0].getRegex()[0] == "^": + pattern = "^" + pattern else: pattern = None - if templates[0].getRegex()[0] == "^": - pattern = "^" + pattern return pattern, templates[0].getName() ## diff --git a/fail2ban/tests/servertestcase.py b/fail2ban/tests/servertestcase.py index 2e8c23c9..dfd59ee8 100644 --- a/fail2ban/tests/servertestcase.py +++ b/fail2ban/tests/servertestcase.py @@ -239,6 +239,12 @@ class Transmitter(TransmitterBase): self.setGetTest("datepattern", "%%%Y%m%d%H%M%S", ("%%%Y%m%d%H%M%S", "%YearMonthDay24hourMinuteSecond"), jail=self.jailName) + self.setGetTest( + "datepattern", "Epoch", (None, "Epoch"), jail=self.jailName) + self.setGetTest( + "datepattern", "TAI64N", (None, "TAI64N"), jail=self.jailName) + self.setGetTest( + "datepattern", "ISO8601", (None, "ISO8601"), jail=self.jailName) self.setGetTestNOK("datepattern", "%Cat%a%%%g", jail=self.jailName) def testJailUseDNS(self):