From cd32f4a13297678bdefcd19901f60aba7bdd56e4 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 26 Apr 2019 12:49:03 +0200 Subject: [PATCH] amend to ec681a336350f193f12d6c4c307b7355bd3770ca (PR gh-2387): - specify default options (`logtype`) in default sections of filter-config (this allows to overwrite such options in Definition/Init sections within filter.local or includes also without setting that in the jail); - fail2ban-regex: output real filter-options (after combine/interpolate) if verbose (`-vv`) or debug (`-l debug`). --- fail2ban/client/configreader.py | 3 +++ fail2ban/client/fail2banregex.py | 22 ++++++++++++++++++++-- fail2ban/client/jailreader.py | 13 ++++++++----- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/fail2ban/client/configreader.py b/fail2ban/client/configreader.py index 2506d98f..66b987b2 100644 --- a/fail2ban/client/configreader.py +++ b/fail2ban/client/configreader.py @@ -120,6 +120,9 @@ class ConfigReader(): except AttributeError: return False + def merge_defaults(self, d): + self._cfg.get_defaults().update(d) + def merge_section(self, section, *args, **kwargs): try: return self._cfg.merge_section(section, *args, **kwargs) diff --git a/fail2ban/client/fail2banregex.py b/fail2ban/client/fail2banregex.py index e3c63f40..d80af23f 100644 --- a/fail2ban/client/fail2banregex.py +++ b/fail2ban/client/fail2banregex.py @@ -286,6 +286,16 @@ class Fail2banRegex(object): def setJournalMatch(self, v): self._journalmatch = v + def _dumpRealOptions(self, reader, fltOpt): + realopts = {} + combopts = reader.getCombined() + # output all options that are specified in filter-argument as well as some special (mostly interested): + for k in ['logtype', 'datepattern'] + fltOpt.keys(): + # combined options win, but they contain only a sub-set in filter expected keys, + # so get the rest from definition section: + realopts[k] = combopts[k] if k in combopts else reader.get('Definition', k) + output("Real filter options : %r" % realopts) + def readRegex(self, value, regextype): assert(regextype in ('fail', 'ignore')) regex = regextype + 'regex' @@ -328,8 +338,6 @@ class Fail2banRegex(object): basedir = None if not os.path.isabs(fltName): # avoid join with "filter.d" inside FilterReader fltName = os.path.abspath(fltName) - if not fltOpt.get('logtype'): - fltOpt['logtype'] = ['file','journal'][int(self._backend.startswith("systemd"))] if fltOpt: output( "Use filter options : %r" % fltOpt ) reader = FilterReader(fltName, 'fail2ban-regex-jail', fltOpt, share_config=self.share_config, basedir=basedir) @@ -347,7 +355,17 @@ class Fail2banRegex(object): if not ret: output( "ERROR: failed to load filter %s" % value ) return False + # overwrite default logtype (considering that the filter could specify this too in Definition/Init sections): + if not fltOpt.get('logtype'): + reader.merge_defaults({ + 'logtype': ['file','journal'][int(self._backend.startswith("systemd"))] + }) + # get, interpolate and convert options: reader.getOptions(None) + # show real options if expected: + if self._verbose > 1 or logSys.getEffectiveLevel()<=logging.DEBUG: + self._dumpRealOptions(reader, fltOpt) + # to stream: readercommands = reader.convert() regex_values = {} diff --git a/fail2ban/client/jailreader.py b/fail2ban/client/jailreader.py index ba76e706..d1256b56 100644 --- a/fail2ban/client/jailreader.py +++ b/fail2ban/client/jailreader.py @@ -111,8 +111,9 @@ class JailReader(ConfigReader): ["string", "action", ""]] # Before interpolation (substitution) add static options always available as default: - defsec = self._cfg.get_defaults() - defsec["fail2ban_version"] = version + self.merge_defaults({ + "fail2ban_version": version + }) try: @@ -130,15 +131,17 @@ class JailReader(ConfigReader): filterName, filterOpt = extractOptions(flt) if not filterName: raise JailDefError("Invalid filter definition %r" % flt) - if not filterOpt.get('logtype'): - filterOpt['logtype'] = ['file','journal'][ - int(self.__opts.get('backend', '').startswith("systemd"))] self.__filter = FilterReader( filterName, self.__name, filterOpt, share_config=self.share_config, basedir=self.getBaseDir()) ret = self.__filter.read() if not ret: raise JailDefError("Unable to read the filter %r" % filterName) + if not filterOpt.get('logtype'): + # overwrite default logtype backend-related (considering that the filter settings may be overwritten): + self.__filter.merge_defaults({ + 'logtype': ['file','journal'][int(self.__opts.get('backend', '').startswith("systemd"))] + }) # merge options from filter as 'known/...' (all options unfiltered): self.__filter.getOptions(self.__opts, all=True) ConfigReader.merge_section(self, self.__name, self.__filter.getCombined(), 'known/')