|
|
|
@ -118,70 +118,78 @@ class JailReader(ConfigReader):
|
|
|
|
|
defsec = self._cfg.get_defaults()
|
|
|
|
|
defsec["fail2ban_version"] = version
|
|
|
|
|
|
|
|
|
|
# Read first options only needed for merge defaults ('known/...' from filter):
|
|
|
|
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts1st, shouldExist=True)
|
|
|
|
|
if not self.__opts:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
if self.isEnabled():
|
|
|
|
|
# Read filter
|
|
|
|
|
if self.__opts["filter"]:
|
|
|
|
|
filterName, filterOpt = JailReader.extractOptions(
|
|
|
|
|
self.__opts["filter"])
|
|
|
|
|
self.__filter = FilterReader(
|
|
|
|
|
filterName, self.__name, filterOpt, share_config=self.share_config, basedir=self.getBaseDir())
|
|
|
|
|
ret = self.__filter.read()
|
|
|
|
|
# merge options from filter as 'known/...':
|
|
|
|
|
self.__filter.getOptions(self.__opts)
|
|
|
|
|
ConfigReader.merge_section(self, self.__name, self.__filter.getCombined(), 'known/')
|
|
|
|
|
if not ret:
|
|
|
|
|
logSys.error("Unable to read the filter")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
self.__filter = None
|
|
|
|
|
logSys.warning("No filter set for jail %s" % self.__name)
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
|
|
# Read second all options (so variables like %(known/param) can be interpolated):
|
|
|
|
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
|
|
|
|
# Read first options only needed for merge defaults ('known/...' from filter):
|
|
|
|
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts1st, shouldExist=True)
|
|
|
|
|
if not self.__opts:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# cumulate filter options again (ignore given in jail):
|
|
|
|
|
if self.__filter:
|
|
|
|
|
self.__filter.getOptions(self.__opts)
|
|
|
|
|
|
|
|
|
|
# Read action
|
|
|
|
|
for act in self.__opts["action"].split('\n'):
|
|
|
|
|
try:
|
|
|
|
|
if not act: # skip empty actions
|
|
|
|
|
continue
|
|
|
|
|
actName, actOpt = JailReader.extractOptions(act)
|
|
|
|
|
if actName.endswith(".py"):
|
|
|
|
|
self.__actions.append([
|
|
|
|
|
"set",
|
|
|
|
|
self.__name,
|
|
|
|
|
"addaction",
|
|
|
|
|
actOpt.pop("actname", os.path.splitext(actName)[0]),
|
|
|
|
|
os.path.join(
|
|
|
|
|
self.getBaseDir(), "action.d", actName),
|
|
|
|
|
json.dumps(actOpt),
|
|
|
|
|
])
|
|
|
|
|
else:
|
|
|
|
|
action = ActionReader(
|
|
|
|
|
actName, self.__name, actOpt,
|
|
|
|
|
share_config=self.share_config, basedir=self.getBaseDir())
|
|
|
|
|
ret = action.read()
|
|
|
|
|
if ret:
|
|
|
|
|
action.getOptions(self.__opts)
|
|
|
|
|
self.__actions.append(action)
|
|
|
|
|
raise ValueError("Init jail options failed")
|
|
|
|
|
|
|
|
|
|
if self.isEnabled():
|
|
|
|
|
# Read filter
|
|
|
|
|
if self.__opts["filter"]:
|
|
|
|
|
filterName, filterOpt = JailReader.extractOptions(
|
|
|
|
|
self.__opts["filter"])
|
|
|
|
|
self.__filter = FilterReader(
|
|
|
|
|
filterName, self.__name, filterOpt, share_config=self.share_config, basedir=self.getBaseDir())
|
|
|
|
|
ret = self.__filter.read()
|
|
|
|
|
# merge options from filter as 'known/...':
|
|
|
|
|
self.__filter.getOptions(self.__opts)
|
|
|
|
|
ConfigReader.merge_section(self, self.__name, self.__filter.getCombined(), 'known/')
|
|
|
|
|
if not ret:
|
|
|
|
|
raise ValueError("Unable to read the filter %r" % filterName)
|
|
|
|
|
else:
|
|
|
|
|
self.__filter = None
|
|
|
|
|
logSys.warning("No filter set for jail %s" % self.__name)
|
|
|
|
|
|
|
|
|
|
# Read second all options (so variables like %(known/param) can be interpolated):
|
|
|
|
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
|
|
|
|
if not self.__opts:
|
|
|
|
|
raise ValueError("Read jail options failed")
|
|
|
|
|
|
|
|
|
|
# cumulate filter options again (ignore given in jail):
|
|
|
|
|
if self.__filter:
|
|
|
|
|
self.__filter.getOptions(self.__opts)
|
|
|
|
|
|
|
|
|
|
# Read action
|
|
|
|
|
for act in self.__opts["action"].split('\n'):
|
|
|
|
|
try:
|
|
|
|
|
if not act: # skip empty actions
|
|
|
|
|
continue
|
|
|
|
|
actName, actOpt = JailReader.extractOptions(act)
|
|
|
|
|
if actName.endswith(".py"):
|
|
|
|
|
self.__actions.append([
|
|
|
|
|
"set",
|
|
|
|
|
self.__name,
|
|
|
|
|
"addaction",
|
|
|
|
|
actOpt.pop("actname", os.path.splitext(actName)[0]),
|
|
|
|
|
os.path.join(
|
|
|
|
|
self.getBaseDir(), "action.d", actName),
|
|
|
|
|
json.dumps(actOpt),
|
|
|
|
|
])
|
|
|
|
|
else:
|
|
|
|
|
raise AttributeError("Unable to read action")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logSys.error("Error in action definition " + act)
|
|
|
|
|
logSys.debug("Caught exception: %s" % (e,))
|
|
|
|
|
return False
|
|
|
|
|
if not len(self.__actions):
|
|
|
|
|
logSys.warning("No actions were defined for %s" % self.__name)
|
|
|
|
|
action = ActionReader(
|
|
|
|
|
actName, self.__name, actOpt,
|
|
|
|
|
share_config=self.share_config, basedir=self.getBaseDir())
|
|
|
|
|
ret = action.read()
|
|
|
|
|
if ret:
|
|
|
|
|
action.getOptions(self.__opts)
|
|
|
|
|
self.__actions.append(action)
|
|
|
|
|
else:
|
|
|
|
|
raise AttributeError("Unable to read action")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
logSys.debug("Caught exception: %s" % (e,))
|
|
|
|
|
raise ValueError("Error in action definition %r" % e)
|
|
|
|
|
if not len(self.__actions):
|
|
|
|
|
logSys.warning("No actions were defined for %s" % self.__name)
|
|
|
|
|
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
e = str(e)
|
|
|
|
|
logSys.error(e)
|
|
|
|
|
if not self.__opts:
|
|
|
|
|
self.__opts = dict()
|
|
|
|
|
self.__opts['config-error'] = e
|
|
|
|
|
return False
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def convert(self, allow_no_files=False):
|
|
|
|
@ -195,6 +203,10 @@ class JailReader(ConfigReader):
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
stream = []
|
|
|
|
|
e = self.__opts.get('config-error')
|
|
|
|
|
if e:
|
|
|
|
|
stream.extend([['config-error', "Jail '%s' skipped, because of wrong configuration: %s" % (self.__name, e)]])
|
|
|
|
|
return stream
|
|
|
|
|
for opt, value in self.__opts.iteritems():
|
|
|
|
|
if opt == "logpath" and \
|
|
|
|
|
not self.__opts.get('backend', None).startswith("systemd"):
|
|
|
|
|