mirror of https://github.com/fail2ban/fail2ban
really skips invalid jails (because of theirs wrong configuration) - server starts nevertheless, as long as one jail was successful configured;
message about wrong jail configuration logged in client log (stdout, systemd journal etc.) and in server log as errorpull/1619/head
parent
261f875748
commit
77dc5a334c
|
@ -118,70 +118,78 @@ class JailReader(ConfigReader):
|
||||||
defsec = self._cfg.get_defaults()
|
defsec = self._cfg.get_defaults()
|
||||||
defsec["fail2ban_version"] = version
|
defsec["fail2ban_version"] = version
|
||||||
|
|
||||||
# Read first options only needed for merge defaults ('known/...' from filter):
|
try:
|
||||||
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)
|
|
||||||
|
|
||||||
# Read second all options (so variables like %(known/param) can be interpolated):
|
# Read first options only needed for merge defaults ('known/...' from filter):
|
||||||
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts1st, shouldExist=True)
|
||||||
if not self.__opts:
|
if not self.__opts:
|
||||||
return False
|
raise ValueError("Init jail options failed")
|
||||||
|
|
||||||
# cumulate filter options again (ignore given in jail):
|
if self.isEnabled():
|
||||||
if self.__filter:
|
# Read filter
|
||||||
self.__filter.getOptions(self.__opts)
|
if self.__opts["filter"]:
|
||||||
|
filterName, filterOpt = JailReader.extractOptions(
|
||||||
# Read action
|
self.__opts["filter"])
|
||||||
for act in self.__opts["action"].split('\n'):
|
self.__filter = FilterReader(
|
||||||
try:
|
filterName, self.__name, filterOpt, share_config=self.share_config, basedir=self.getBaseDir())
|
||||||
if not act: # skip empty actions
|
ret = self.__filter.read()
|
||||||
continue
|
# merge options from filter as 'known/...':
|
||||||
actName, actOpt = JailReader.extractOptions(act)
|
self.__filter.getOptions(self.__opts)
|
||||||
if actName.endswith(".py"):
|
ConfigReader.merge_section(self, self.__name, self.__filter.getCombined(), 'known/')
|
||||||
self.__actions.append([
|
if not ret:
|
||||||
"set",
|
raise ValueError("Unable to read the filter %r" % filterName)
|
||||||
self.__name,
|
else:
|
||||||
"addaction",
|
self.__filter = None
|
||||||
actOpt.pop("actname", os.path.splitext(actName)[0]),
|
logSys.warning("No filter set for jail %s" % self.__name)
|
||||||
os.path.join(
|
|
||||||
self.getBaseDir(), "action.d", actName),
|
# Read second all options (so variables like %(known/param) can be interpolated):
|
||||||
json.dumps(actOpt),
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
||||||
])
|
if not self.__opts:
|
||||||
else:
|
raise ValueError("Read jail options failed")
|
||||||
action = ActionReader(
|
|
||||||
actName, self.__name, actOpt,
|
# cumulate filter options again (ignore given in jail):
|
||||||
share_config=self.share_config, basedir=self.getBaseDir())
|
if self.__filter:
|
||||||
ret = action.read()
|
self.__filter.getOptions(self.__opts)
|
||||||
if ret:
|
|
||||||
action.getOptions(self.__opts)
|
# Read action
|
||||||
self.__actions.append(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:
|
else:
|
||||||
raise AttributeError("Unable to read action")
|
action = ActionReader(
|
||||||
except Exception as e:
|
actName, self.__name, actOpt,
|
||||||
logSys.error("Error in action definition " + act)
|
share_config=self.share_config, basedir=self.getBaseDir())
|
||||||
logSys.debug("Caught exception: %s" % (e,))
|
ret = action.read()
|
||||||
return False
|
if ret:
|
||||||
if not len(self.__actions):
|
action.getOptions(self.__opts)
|
||||||
logSys.warning("No actions were defined for %s" % self.__name)
|
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
|
return True
|
||||||
|
|
||||||
def convert(self, allow_no_files=False):
|
def convert(self, allow_no_files=False):
|
||||||
|
@ -195,6 +203,10 @@ class JailReader(ConfigReader):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
stream = []
|
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():
|
for opt, value in self.__opts.iteritems():
|
||||||
if opt == "logpath" and \
|
if opt == "logpath" and \
|
||||||
not self.__opts.get('backend', None).startswith("systemd"):
|
not self.__opts.get('backend', None).startswith("systemd"):
|
||||||
|
|
|
@ -66,7 +66,7 @@ class JailsReader(ConfigReader):
|
||||||
sections = [ section ]
|
sections = [ section ]
|
||||||
|
|
||||||
# Get the options of all jails.
|
# Get the options of all jails.
|
||||||
parse_status = True
|
parse_status = None
|
||||||
for sec in sections:
|
for sec in sections:
|
||||||
if sec == 'INCLUDES':
|
if sec == 'INCLUDES':
|
||||||
continue
|
continue
|
||||||
|
@ -77,11 +77,17 @@ class JailsReader(ConfigReader):
|
||||||
ret = jail.getOptions()
|
ret = jail.getOptions()
|
||||||
if ret:
|
if ret:
|
||||||
if jail.isEnabled():
|
if jail.isEnabled():
|
||||||
|
# at least one jail was successful:
|
||||||
|
parse_status = True
|
||||||
# We only add enabled jails
|
# We only add enabled jails
|
||||||
self.__jails.append(jail)
|
self.__jails.append(jail)
|
||||||
else:
|
else:
|
||||||
logSys.error("Errors in jail %r. Skipping..." % sec)
|
logSys.error("Errors in jail %r. Skipping..." % sec)
|
||||||
parse_status = False
|
self.__jails.append(jail)
|
||||||
|
if parse_status is None:
|
||||||
|
parse_status = False
|
||||||
|
if parse_status is None:
|
||||||
|
parse_status = True
|
||||||
return parse_status
|
return parse_status
|
||||||
|
|
||||||
def convert(self, allow_no_files=False):
|
def convert(self, allow_no_files=False):
|
||||||
|
@ -103,7 +109,8 @@ class JailsReader(ConfigReader):
|
||||||
stream.extend(jail.convert(allow_no_files=allow_no_files))
|
stream.extend(jail.convert(allow_no_files=allow_no_files))
|
||||||
# Start jails
|
# Start jails
|
||||||
for jail in self.__jails:
|
for jail in self.__jails:
|
||||||
stream.append(["start", jail.getName()])
|
if not jail.options.get('config-error'):
|
||||||
|
stream.append(["start", jail.getName()])
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,9 @@ class Transmitter:
|
||||||
return self.status(command[1:])
|
return self.status(command[1:])
|
||||||
elif command[0] == "version":
|
elif command[0] == "version":
|
||||||
return version.version
|
return version.version
|
||||||
|
elif command[0] == "config-error":
|
||||||
|
logSys.error(command[1])
|
||||||
|
return None
|
||||||
raise Exception("Invalid command")
|
raise Exception("Invalid command")
|
||||||
|
|
||||||
def __commandSet(self, command, multiple=False):
|
def __commandSet(self, command, multiple=False):
|
||||||
|
|
Loading…
Reference in New Issue