new jail option `skip_if_nologs` to ignore jail if no `logpath` matches found, fail2ban continue to start with warnings/errors, thus other jails become running;

closes gh-2756
pull/3823/head
sebres 2024-08-23 12:16:08 +02:00
parent 54c0effceb
commit 78af48862f
4 changed files with 28 additions and 4 deletions

View File

@ -28,6 +28,8 @@ ver. 1.1.1-dev-1 (20??/??/??) - development nightly edition
several log messages will be tagged with as originating from a process named "sshd-session" rather than "sshd" (gh-3782) several log messages will be tagged with as originating from a process named "sshd-session" rather than "sshd" (gh-3782)
### New Features and Enhancements ### New Features and Enhancements
* new jail option `skip_if_nologs` to ignore jail if no `logpath` matches found, fail2ban continue to start with warnings/errors,
thus other jails become running (gh-2756)
* `action.d/*-ipset.conf`: * `action.d/*-ipset.conf`:
- parameter `ipsettype` to set type of ipset, e. g. hash:ip, hash:net, etc (gh-3760) - parameter `ipsettype` to set type of ipset, e. g. hash:ip, hash:net, etc (gh-3760)
* `action.d/firewallcmd-rich-*.conf` - fixed incorrect quoting, disabling port variable expansion * `action.d/firewallcmd-rich-*.conf` - fixed incorrect quoting, disabling port variable expansion

View File

@ -116,11 +116,15 @@ class JailReader(ConfigReader):
"logtimezone": ["string", None], "logtimezone": ["string", None],
"logencoding": ["string", None], "logencoding": ["string", None],
"logpath": ["string", None], "logpath": ["string", None],
"skip_if_nologs": ["bool", False],
"action": ["string", ""] "action": ["string", ""]
} }
_configOpts.update(FilterReader._configOpts) _configOpts.update(FilterReader._configOpts)
_ignoreOpts = set(['action', 'filter', 'enabled', 'backend'] + list(FilterReader._configOpts.keys())) _ignoreOpts = set(
['action', 'filter', 'enabled', 'backend', 'skip_if_nologs'] +
list(FilterReader._configOpts.keys())
)
def getOptions(self, addOpts=None): def getOptions(self, addOpts=None):
@ -274,9 +278,14 @@ class JailReader(ConfigReader):
["set", self.__name, "addlogpath", p, tail]) ["set", self.__name, "addlogpath", p, tail])
if not found_files: if not found_files:
msg = "Have not found any log file for %s jail" % self.__name msg = "Have not found any log file for %s jail" % self.__name
if not allow_no_files: skip_if_nologs = self.__opts.get('skip_if_nologs', False)
if not allow_no_files and not skip_if_nologs:
raise ValueError(msg) raise ValueError(msg)
logSys.warning(msg) logSys.warning(msg)
if skip_if_nologs:
self.__opts['config-error'] = msg
stream = [['config-error', "Jail '%s' skipped, because of missing log files." % (self.__name,)]]
return stream
elif opt == "ignoreip": elif opt == "ignoreip":
stream.append(["set", self.__name, "addignoreip"] + splitwords(value)) stream.append(["set", self.__name, "addignoreip"] + splitwords(value))
elif opt not in JailReader._ignoreOpts: elif opt not in JailReader._ignoreOpts:

View File

@ -733,6 +733,7 @@ class JailsReaderTest(LogCaptureTestCase):
['start', 'test-known-interp'], ['start', 'test-known-interp'],
['add', 'missinglogfiles', 'auto'], ['add', 'missinglogfiles', 'auto'],
['set', 'missinglogfiles', 'addfailregex', '<IP>'], ['set', 'missinglogfiles', 'addfailregex', '<IP>'],
['config-error', "Jail 'missinglogfiles_skip' skipped, because of missing log files."],
['add', 'brokenaction', 'auto'], ['add', 'brokenaction', 'auto'],
['set', 'brokenaction', 'addfailregex', '<IP>'], ['set', 'brokenaction', 'addfailregex', '<IP>'],
['set', 'brokenaction', 'addaction', 'brokenaction'], ['set', 'brokenaction', 'addaction', 'brokenaction'],
@ -1022,6 +1023,11 @@ filter = testfilter1
self.assertRaisesRegex(ValueError, r"Have not found any log file for .* jail", self.assertRaisesRegex(ValueError, r"Have not found any log file for .* jail",
self._testLogPath, backend='polling') self._testLogPath, backend='polling')
def testLogPathSkipJailIfNoLogs(self):
s = self._testLogPath(backend='polling', skip_if_nologs=True)
self.assertLogged('Have not found any log file for')
self.assertEqual(s, [['config-error', "Jail 'testjail1' skipped, because of missing log files."]])
def testLogPathSystemdBackend(self): def testLogPathSystemdBackend(self):
try: # pragma: systemd no cover try: # pragma: systemd no cover
from ..server.filtersystemd import FilterSystemd from ..server.filtersystemd import FilterSystemd
@ -1031,7 +1037,7 @@ filter = testfilter1
self._testLogPath(backend='systemd[journalflags=2]') self._testLogPath(backend='systemd[journalflags=2]')
@with_tmpdir @with_tmpdir
def _testLogPath(self, basedir, backend): def _testLogPath(self, basedir, backend, skip_if_nologs=False):
jailfd = open(os.path.join(basedir, "jail.conf"), 'w') jailfd = open(os.path.join(basedir, "jail.conf"), 'w')
jailfd.write(""" jailfd.write("""
[testjail1] [testjail1]
@ -1043,8 +1049,10 @@ action =
filter = filter =
failregex = test <HOST> failregex = test <HOST>
""" % (backend, basedir)) """ % (backend, basedir))
if skip_if_nologs:
jailfd.write("skip_if_nologs = true\n")
jailfd.close() jailfd.close()
jails = JailsReader(basedir=basedir) jails = JailsReader(basedir=basedir)
self.assertTrue(jails.read()) self.assertTrue(jails.read())
self.assertTrue(jails.getOptions()) self.assertTrue(jails.getOptions())
jails.convert() return jails.convert()

View File

@ -23,6 +23,11 @@ failregex = %(known/failregex)s
enabled = true enabled = true
logpath = /weapons/of/mass/destruction logpath = /weapons/of/mass/destruction
[missinglogfiles_skip]
enabled = true
skip_if_nologs = true
logpath = /weapons/of/mass/destruction
[brokenactiondef] [brokenactiondef]
enabled = true enabled = true
action = joho[foo action = joho[foo