mirror of https://github.com/fail2ban/fail2ban
failregex: introduced capturing alternate groups, for example non-empty values of `alt_user_1`, `alt_user_2` will overwrite `user` if it is empty (or `alt_host` -> `host`, etc.)
parent
8028d3940d
commit
5603055a58
|
@ -89,6 +89,11 @@ def mapTag2Opt(tag):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return tag.lower()
|
return tag.lower()
|
||||||
|
|
||||||
|
|
||||||
|
# alternate names to be merged, e. g. alt_user_1 -> user ...
|
||||||
|
ALTNAME_PRE = 'alt_'
|
||||||
|
ALTNAME_CRE = re.compile(r'^' + ALTNAME_PRE + r'(.*)(?:_\d+)?$')
|
||||||
|
|
||||||
##
|
##
|
||||||
# Regular expression class.
|
# Regular expression class.
|
||||||
#
|
#
|
||||||
|
@ -114,6 +119,14 @@ class Regex:
|
||||||
try:
|
try:
|
||||||
self._regexObj = re.compile(regex, re.MULTILINE if multiline else 0)
|
self._regexObj = re.compile(regex, re.MULTILINE if multiline else 0)
|
||||||
self._regex = regex
|
self._regex = regex
|
||||||
|
self._altValues = {}
|
||||||
|
for k in filter(
|
||||||
|
lambda k: len(k) > len(ALTNAME_PRE) and k.startswith(ALTNAME_PRE),
|
||||||
|
self._regexObj.groupindex
|
||||||
|
):
|
||||||
|
n = ALTNAME_CRE.match(k).group(1)
|
||||||
|
self._altValues[k] = n
|
||||||
|
self._altValues = list(self._altValues.items()) if len(self._altValues) else None
|
||||||
except sre_constants.error:
|
except sre_constants.error:
|
||||||
raise RegexException("Unable to compile regular expression '%s'" %
|
raise RegexException("Unable to compile regular expression '%s'" %
|
||||||
regex)
|
regex)
|
||||||
|
@ -248,7 +261,16 @@ class Regex:
|
||||||
#
|
#
|
||||||
|
|
||||||
def getGroups(self):
|
def getGroups(self):
|
||||||
return self._matchCache.groupdict()
|
if not self._altValues:
|
||||||
|
return self._matchCache.groupdict()
|
||||||
|
# merge alternate values (e. g. 'alt_user_1' -> 'user' or 'alt_host' -> 'host'):
|
||||||
|
fail = self._matchCache.groupdict()
|
||||||
|
#fail = fail.copy()
|
||||||
|
for k,n in self._altValues:
|
||||||
|
v = fail.get(k)
|
||||||
|
if v and not fail.get(n):
|
||||||
|
fail[n] = v
|
||||||
|
return fail
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns skipped lines.
|
# Returns skipped lines.
|
||||||
|
|
|
@ -692,43 +692,46 @@ class Filter(JailThread):
|
||||||
|
|
||||||
# Iterates over all the regular expressions.
|
# Iterates over all the regular expressions.
|
||||||
for failRegexIndex, failRegex in enumerate(self.__failRegex):
|
for failRegexIndex, failRegex in enumerate(self.__failRegex):
|
||||||
if logSys.getEffectiveLevel() <= logging.HEAVYDEBUG: # pragma: no cover
|
|
||||||
logSys.log(5, " Looking for failregex %d - %r", failRegexIndex, failRegex.getRegex())
|
|
||||||
failRegex.search(self.__lineBuffer, orgBuffer)
|
|
||||||
if not failRegex.hasMatched():
|
|
||||||
continue
|
|
||||||
# The failregex matched.
|
|
||||||
logSys.log(7, " Matched failregex %d: %s", failRegexIndex, failRegex.getGroups())
|
|
||||||
# Checks if we must ignore this match.
|
|
||||||
if self.ignoreLine(failRegex.getMatchedTupleLines()) \
|
|
||||||
is not None:
|
|
||||||
# The ignoreregex matched. Remove ignored match.
|
|
||||||
self.__lineBuffer = failRegex.getUnmatchedTupleLines()
|
|
||||||
logSys.log(7, " Matched ignoreregex and was ignored")
|
|
||||||
if not self.checkAllRegex:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
if date is None:
|
|
||||||
logSys.warning(
|
|
||||||
"Found a match for %r but no valid date/time "
|
|
||||||
"found for %r. Please try setting a custom "
|
|
||||||
"date pattern (see man page jail.conf(5)). "
|
|
||||||
"If format is complex, please "
|
|
||||||
"file a detailed issue on"
|
|
||||||
" https://github.com/fail2ban/fail2ban/issues "
|
|
||||||
"in order to get support for this format.",
|
|
||||||
"\n".join(failRegex.getMatchedLines()), timeText)
|
|
||||||
continue
|
|
||||||
self.__lineBuffer = failRegex.getUnmatchedTupleLines()
|
|
||||||
# retrieve failure-id, host, etc from failure match:
|
# retrieve failure-id, host, etc from failure match:
|
||||||
try:
|
try:
|
||||||
|
if logSys.getEffectiveLevel() <= logging.HEAVYDEBUG: # pragma: no cover
|
||||||
|
logSys.log(5, " Looking for failregex %d - %r", failRegexIndex, failRegex.getRegex())
|
||||||
|
failRegex.search(self.__lineBuffer, orgBuffer)
|
||||||
|
if not failRegex.hasMatched():
|
||||||
|
continue
|
||||||
|
# current failure data (matched group dict):
|
||||||
|
fail = failRegex.getGroups()
|
||||||
|
# The failregex matched.
|
||||||
|
logSys.log(7, " Matched failregex %d: %s", failRegexIndex, fail)
|
||||||
|
# Checks if we must ignore this match.
|
||||||
|
if self.ignoreLine(failRegex.getMatchedTupleLines()) \
|
||||||
|
is not None:
|
||||||
|
# The ignoreregex matched. Remove ignored match.
|
||||||
|
self.__lineBuffer = failRegex.getUnmatchedTupleLines()
|
||||||
|
logSys.log(7, " Matched ignoreregex and was ignored")
|
||||||
|
if not self.checkAllRegex:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
if date is None:
|
||||||
|
logSys.warning(
|
||||||
|
"Found a match for %r but no valid date/time "
|
||||||
|
"found for %r. Please try setting a custom "
|
||||||
|
"date pattern (see man page jail.conf(5)). "
|
||||||
|
"If format is complex, please "
|
||||||
|
"file a detailed issue on"
|
||||||
|
" https://github.com/fail2ban/fail2ban/issues "
|
||||||
|
"in order to get support for this format.",
|
||||||
|
"\n".join(failRegex.getMatchedLines()), timeText)
|
||||||
|
continue
|
||||||
|
# we should check all regex (bypass on multi-line, otherwise too complex):
|
||||||
|
if not self.checkAllRegex or self.getMaxLines() > 1:
|
||||||
|
self.__lineBuffer = failRegex.getUnmatchedTupleLines()
|
||||||
|
# merge data if multi-line failure:
|
||||||
raw = returnRawHost
|
raw = returnRawHost
|
||||||
if preGroups:
|
if preGroups:
|
||||||
fail = preGroups.copy()
|
currFail, fail = fail, preGroups.copy()
|
||||||
fail.update(failRegex.getGroups())
|
fail.update(currFail)
|
||||||
else:
|
|
||||||
fail = failRegex.getGroups()
|
|
||||||
# first try to check we have mlfid case (caching of connection id by multi-line):
|
# first try to check we have mlfid case (caching of connection id by multi-line):
|
||||||
mlfid = fail.get('mlfid')
|
mlfid = fail.get('mlfid')
|
||||||
if mlfid is not None:
|
if mlfid is not None:
|
||||||
|
|
|
@ -144,6 +144,7 @@ def testSampleRegexsFactory(name, basedir):
|
||||||
regexsUsedRe = set()
|
regexsUsedRe = set()
|
||||||
|
|
||||||
# process each test-file (note: array filenames can grow during processing):
|
# process each test-file (note: array filenames can grow during processing):
|
||||||
|
faildata = {}
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(filenames):
|
while i < len(filenames):
|
||||||
filename = filenames[i]; i += 1;
|
filename = filenames[i]; i += 1;
|
||||||
|
@ -195,6 +196,7 @@ def testSampleRegexsFactory(name, basedir):
|
||||||
regexList = flt.getFailRegex()
|
regexList = flt.getFailRegex()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
fail = {}
|
||||||
ret = flt.processLine(line)
|
ret = flt.processLine(line)
|
||||||
if not ret:
|
if not ret:
|
||||||
# Bypass if filter constraint specified:
|
# Bypass if filter constraint specified:
|
||||||
|
@ -246,8 +248,8 @@ def testSampleRegexsFactory(name, basedir):
|
||||||
regexsUsedIdx.add(failregex)
|
regexsUsedIdx.add(failregex)
|
||||||
regexsUsedRe.add(regexList[failregex])
|
regexsUsedRe.add(regexList[failregex])
|
||||||
except AssertionError as e: # pragma: no cover
|
except AssertionError as e: # pragma: no cover
|
||||||
raise AssertionError("%s: %s on: %s:%i, line:\n%s" % (
|
raise AssertionError("%s: %s on: %s:%i, line:\n%s\nfaildata:%r, fail:%r" % (
|
||||||
fltName, e, logFile.filename(), logFile.filelineno(), line))
|
fltName, e, logFile.filename(), logFile.filelineno(), line, faildata, fail))
|
||||||
|
|
||||||
# check missing samples for regex using each filter-options combination:
|
# check missing samples for regex using each filter-options combination:
|
||||||
for fltName, flt in self._filters.iteritems():
|
for fltName, flt in self._filters.iteritems():
|
||||||
|
|
Loading…
Reference in New Issue