mirror of https://github.com/fail2ban/fail2ban
Merge branch '0.10' into 0.11
commit
633b179b19
|
@ -120,6 +120,9 @@ class ConfigReader():
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def merge_defaults(self, d):
|
||||||
|
self._cfg.get_defaults().update(d)
|
||||||
|
|
||||||
def merge_section(self, section, *args, **kwargs):
|
def merge_section(self, section, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
return self._cfg.merge_section(section, *args, **kwargs)
|
return self._cfg.merge_section(section, *args, **kwargs)
|
||||||
|
|
|
@ -286,6 +286,16 @@ class Fail2banRegex(object):
|
||||||
def setJournalMatch(self, v):
|
def setJournalMatch(self, v):
|
||||||
self._journalmatch = 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):
|
def readRegex(self, value, regextype):
|
||||||
assert(regextype in ('fail', 'ignore'))
|
assert(regextype in ('fail', 'ignore'))
|
||||||
regex = regextype + 'regex'
|
regex = regextype + 'regex'
|
||||||
|
@ -328,8 +338,6 @@ class Fail2banRegex(object):
|
||||||
basedir = None
|
basedir = None
|
||||||
if not os.path.isabs(fltName): # avoid join with "filter.d" inside FilterReader
|
if not os.path.isabs(fltName): # avoid join with "filter.d" inside FilterReader
|
||||||
fltName = os.path.abspath(fltName)
|
fltName = os.path.abspath(fltName)
|
||||||
if not fltOpt.get('logtype'):
|
|
||||||
fltOpt['logtype'] = ['file','journal'][int(self._backend.startswith("systemd"))]
|
|
||||||
if fltOpt:
|
if fltOpt:
|
||||||
output( "Use filter options : %r" % fltOpt )
|
output( "Use filter options : %r" % fltOpt )
|
||||||
reader = FilterReader(fltName, 'fail2ban-regex-jail', fltOpt, share_config=self.share_config, basedir=basedir)
|
reader = FilterReader(fltName, 'fail2ban-regex-jail', fltOpt, share_config=self.share_config, basedir=basedir)
|
||||||
|
@ -347,7 +355,17 @@ class Fail2banRegex(object):
|
||||||
if not ret:
|
if not ret:
|
||||||
output( "ERROR: failed to load filter %s" % value )
|
output( "ERROR: failed to load filter %s" % value )
|
||||||
return False
|
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)
|
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()
|
readercommands = reader.convert()
|
||||||
|
|
||||||
regex_values = {}
|
regex_values = {}
|
||||||
|
|
|
@ -118,8 +118,9 @@ class JailReader(ConfigReader):
|
||||||
["string", "action", ""]]
|
["string", "action", ""]]
|
||||||
|
|
||||||
# Before interpolation (substitution) add static options always available as default:
|
# Before interpolation (substitution) add static options always available as default:
|
||||||
defsec = self._cfg.get_defaults()
|
self.merge_defaults({
|
||||||
defsec["fail2ban_version"] = version
|
"fail2ban_version": version
|
||||||
|
})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
|
@ -137,15 +138,17 @@ class JailReader(ConfigReader):
|
||||||
filterName, filterOpt = extractOptions(flt)
|
filterName, filterOpt = extractOptions(flt)
|
||||||
if not filterName:
|
if not filterName:
|
||||||
raise JailDefError("Invalid filter definition %r" % flt)
|
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(
|
self.__filter = FilterReader(
|
||||||
filterName, self.__name, filterOpt,
|
filterName, self.__name, filterOpt,
|
||||||
share_config=self.share_config, basedir=self.getBaseDir())
|
share_config=self.share_config, basedir=self.getBaseDir())
|
||||||
ret = self.__filter.read()
|
ret = self.__filter.read()
|
||||||
if not ret:
|
if not ret:
|
||||||
raise JailDefError("Unable to read the filter %r" % filterName)
|
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):
|
# merge options from filter as 'known/...' (all options unfiltered):
|
||||||
self.__filter.getOptions(self.__opts, all=True)
|
self.__filter.getOptions(self.__opts, all=True)
|
||||||
ConfigReader.merge_section(self, self.__name, self.__filter.getCombined(), 'known/')
|
ConfigReader.merge_section(self, self.__name, self.__filter.getCombined(), 'known/')
|
||||||
|
|
|
@ -218,6 +218,18 @@ class Fail2banRegexTest(LogCaptureTestCase):
|
||||||
# test failure line and not-failure lines both presents:
|
# test failure line and not-failure lines both presents:
|
||||||
self.assertLogged("[29116]: User root not allowed because account is locked",
|
self.assertLogged("[29116]: User root not allowed because account is locked",
|
||||||
"[29116]: Received disconnect from 1.2.3.4", all=True)
|
"[29116]: Received disconnect from 1.2.3.4", all=True)
|
||||||
|
self.pruneLog()
|
||||||
|
# show real options:
|
||||||
|
(opts, args, fail2banRegex) = _Fail2banRegex(
|
||||||
|
"-l", "notice", # put down log-level, because of too many debug-messages
|
||||||
|
"-vv", "-c", CONFIG_DIR,
|
||||||
|
"Dec 31 11:59:59 [sshd] error: PAM: Authentication failure for kevin from 192.0.2.1",
|
||||||
|
"sshd[logtype=short]"
|
||||||
|
)
|
||||||
|
self.assertTrue(fail2banRegex.start(args))
|
||||||
|
# tet logtype is specified and set in real options:
|
||||||
|
self.assertLogged("Real filter options :", "'logtype': 'short'", all=True)
|
||||||
|
self.assertNotLogged("'logtype': 'file'", "'logtype': 'journal'", all=True)
|
||||||
|
|
||||||
def testFastSshd(self):
|
def testFastSshd(self):
|
||||||
(opts, args, fail2banRegex) = _Fail2banRegex(
|
(opts, args, fail2banRegex) = _Fail2banRegex(
|
||||||
|
|
Loading…
Reference in New Issue