optimizes processing of server-configuration stream by start and reload (no interim outputs produced, several calls of get-functions avoided also).

pull/2362/head
sebres 2019-02-21 15:54:56 +01:00
parent 34dba44816
commit 883864c774
4 changed files with 67 additions and 26 deletions

View File

@ -186,8 +186,7 @@ class Fail2banClient(Fail2banCmdLine, Thread):
logSys.error("Fail2ban seems to be in unexpected state (not running but the socket exists)") logSys.error("Fail2ban seems to be in unexpected state (not running but the socket exists)")
return None return None
stream.append(['server-status']) return [["server-stream", stream], ['server-status']]
return stream
## ##
def __startServer(self, background=True): def __startServer(self, background=True):

View File

@ -491,8 +491,6 @@ class Server:
ifexists |= (name is None) ifexists |= (name is None)
for jail in jails: for jail in jails:
cnt += jail.actions.removeBannedIP(value, ifexists=ifexists) cnt += jail.actions.removeBannedIP(value, ifexists=ifexists)
if value and not cnt:
logSys.info("%s is not banned", value)
return cnt return cnt
def getBanTime(self, name): def getBanTime(self, name):

View File

@ -43,6 +43,7 @@ class Transmitter:
def __init__(self, server): def __init__(self, server):
self.__server = server self.__server = server
self.__quiet = 0
## ##
# Proceeds a command. # Proceeds a command.
@ -69,9 +70,10 @@ class Transmitter:
# #
def __commandHandler(self, command): def __commandHandler(self, command):
if command[0] == "ping": name = command[0]
if name == "ping":
return "pong" return "pong"
elif command[0] == "add": elif name == "add":
name = command[1] name = command[1]
if name == "--all": if name == "--all":
raise Exception("Reserved name %r" % (name,)) raise Exception("Reserved name %r" % (name,))
@ -81,11 +83,15 @@ class Transmitter:
backend = "auto" backend = "auto"
self.__server.addJail(name, backend) self.__server.addJail(name, backend)
return name return name
elif command[0] == "start": elif name == "multi-set":
return self.__commandSet(command[1:], True)
elif name == "set":
return self.__commandSet(command[1:])
elif name == "start":
name = command[1] name = command[1]
self.__server.startJail(name) self.__server.startJail(name)
return None return None
elif command[0] == "stop": elif name == "stop":
if len(command) == 1: if len(command) == 1:
self.__server.quit() self.__server.quit()
elif command[1] == "--all": elif command[1] == "--all":
@ -94,44 +100,50 @@ class Transmitter:
name = command[1] name = command[1]
self.__server.stopJail(name) self.__server.stopJail(name)
return None return None
elif command[0] == "reload": elif name == "reload":
opts = command[1:3] opts = command[1:3]
self.__quiet = 1
try: try:
self.__server.reloadJails(*opts, begin=True) self.__server.reloadJails(*opts, begin=True)
for cmd in command[3]: for cmd in command[3]:
self.__commandHandler(cmd) self.__commandHandler(cmd)
finally: finally:
self.__quiet = 0
self.__server.reloadJails(*opts, begin=False) self.__server.reloadJails(*opts, begin=False)
return 'OK' return 'OK'
elif len(command) >= 2 and command[0] == "unban": elif name == "unban" and len(command) >= 2:
# unban in all jails: # unban in all jails:
value = command[1:] value = command[1:]
# if all ips: # if all ips:
if len(value) == 1 and value[0] == "--all": if len(value) == 1 and value[0] == "--all":
return self.__server.setUnbanIP() return self.__server.setUnbanIP()
return self.__server.setUnbanIP(None, value) return self.__server.setUnbanIP(None, value)
elif command[0] == "echo": elif name == "echo":
return command[1:] return command[1:]
elif command[0] == "server-status": elif name == "server-status":
logSys.debug("Status: ready") logSys.debug("Status: ready")
return "Server ready" return "Server ready"
elif command[0] == "sleep": elif name == "server-stream":
self.__quiet = 1
try:
for cmd in command[1]:
self.__commandHandler(cmd)
finally:
self.__quiet = 0
return None
elif name == "sleep":
value = command[1] value = command[1]
time.sleep(float(value)) time.sleep(float(value))
return None return None
elif command[0] == "flushlogs": elif name == "flushlogs":
return self.__server.flushLogs() return self.__server.flushLogs()
elif command[0] == "multi-set": elif name == "get":
return self.__commandSet(command[1:], True)
elif command[0] == "set":
return self.__commandSet(command[1:])
elif command[0] == "get":
return self.__commandGet(command[1:]) return self.__commandGet(command[1:])
elif command[0] == "status": elif name == "status":
return self.status(command[1:]) return self.status(command[1:])
elif command[0] == "version": elif name == "version":
return version.version return version.version
elif command[0] == "config-error": elif name == "config-error":
logSys.error(command[1]) logSys.error(command[1])
return None return None
raise Exception("Invalid command") raise Exception("Invalid command")
@ -142,16 +154,19 @@ class Transmitter:
if name == "loglevel": if name == "loglevel":
value = command[1] value = command[1]
self.__server.setLogLevel(value) self.__server.setLogLevel(value)
if self.__quiet: return
return self.__server.getLogLevel() return self.__server.getLogLevel()
elif name == "logtarget": elif name == "logtarget":
value = command[1] value = command[1]
if self.__server.setLogTarget(value): if self.__server.setLogTarget(value):
if self.__quiet: return
return self.__server.getLogTarget() return self.__server.getLogTarget()
else: else:
raise Exception("Failed to change log target") raise Exception("Failed to change log target")
elif name == "syslogsocket": elif name == "syslogsocket":
value = command[1] value = command[1]
if self.__server.setSyslogSocket(value): if self.__server.setSyslogSocket(value):
if self.__quiet: return
return self.__server.getSyslogSocket() return self.__server.getSyslogSocket()
else: else:
raise Exception("Failed to change syslog socket") raise Exception("Failed to change syslog socket")
@ -162,6 +177,7 @@ class Transmitter:
if db is None: if db is None:
return None return None
else: else:
if self.__quiet: return
return db.filename return db.filename
elif name == "dbpurgeage": elif name == "dbpurgeage":
db = self.__server.getDatabase() db = self.__server.getDatabase()
@ -170,6 +186,7 @@ class Transmitter:
return None return None
else: else:
db.purgeage = command[1] db.purgeage = command[1]
if self.__quiet: return
return db.purgeage return db.purgeage
# Jail # Jail
elif command[1] == "idle": elif command[1] == "idle":
@ -179,27 +196,33 @@ class Transmitter:
self.__server.setIdleJail(name, False) self.__server.setIdleJail(name, False)
else: else:
raise Exception("Invalid idle option, must be 'on' or 'off'") raise Exception("Invalid idle option, must be 'on' or 'off'")
if self.__quiet: return
return self.__server.getIdleJail(name) return self.__server.getIdleJail(name)
# Filter # Filter
elif command[1] == "ignoreself": elif command[1] == "ignoreself":
value = command[2] value = command[2]
self.__server.setIgnoreSelf(name, value) self.__server.setIgnoreSelf(name, value)
if self.__quiet: return
return self.__server.getIgnoreSelf(name) return self.__server.getIgnoreSelf(name)
elif command[1] == "addignoreip": elif command[1] == "addignoreip":
for value in command[2:]: for value in command[2:]:
self.__server.addIgnoreIP(name, value) self.__server.addIgnoreIP(name, value)
if self.__quiet: return
return self.__server.getIgnoreIP(name) return self.__server.getIgnoreIP(name)
elif command[1] == "delignoreip": elif command[1] == "delignoreip":
value = command[2] value = command[2]
self.__server.delIgnoreIP(name, value) self.__server.delIgnoreIP(name, value)
if self.__quiet: return
return self.__server.getIgnoreIP(name) return self.__server.getIgnoreIP(name)
elif command[1] == "ignorecommand": elif command[1] == "ignorecommand":
value = command[2] value = command[2]
self.__server.setIgnoreCommand(name, value) self.__server.setIgnoreCommand(name, value)
if self.__quiet: return
return self.__server.getIgnoreCommand(name) return self.__server.getIgnoreCommand(name)
elif command[1] == "ignorecache": elif command[1] == "ignorecache":
value = command[2] value = command[2]
self.__server.setIgnoreCache(name, value) self.__server.setIgnoreCache(name, value)
if self.__quiet: return
return self.__server.getIgnoreCache(name) return self.__server.getIgnoreCache(name)
elif command[1] == "addlogpath": elif command[1] == "addlogpath":
value = command[2] value = command[2]
@ -212,78 +235,96 @@ class Transmitter:
elif len(command) > 4: elif len(command) > 4:
raise ValueError("Only one file can be added at a time") raise ValueError("Only one file can be added at a time")
self.__server.addLogPath(name, value, tail) self.__server.addLogPath(name, value, tail)
if self.__quiet: return
return self.__server.getLogPath(name) return self.__server.getLogPath(name)
elif command[1] == "dellogpath": elif command[1] == "dellogpath":
value = command[2] value = command[2]
self.__server.delLogPath(name, value) self.__server.delLogPath(name, value)
if self.__quiet: return
return self.__server.getLogPath(name) return self.__server.getLogPath(name)
elif command[1] == "logencoding": elif command[1] == "logencoding":
value = command[2] value = command[2]
self.__server.setLogEncoding(name, value) self.__server.setLogEncoding(name, value)
if self.__quiet: return
return self.__server.getLogEncoding(name) return self.__server.getLogEncoding(name)
elif command[1] == "addjournalmatch": # pragma: systemd no cover elif command[1] == "addjournalmatch": # pragma: systemd no cover
value = command[2:] value = command[2:]
self.__server.addJournalMatch(name, value) self.__server.addJournalMatch(name, value)
if self.__quiet: return
return self.__server.getJournalMatch(name) return self.__server.getJournalMatch(name)
elif command[1] == "deljournalmatch": # pragma: systemd no cover elif command[1] == "deljournalmatch": # pragma: systemd no cover
value = command[2:] value = command[2:]
self.__server.delJournalMatch(name, value) self.__server.delJournalMatch(name, value)
if self.__quiet: return
return self.__server.getJournalMatch(name) return self.__server.getJournalMatch(name)
elif command[1] == "prefregex": elif command[1] == "prefregex":
value = command[2] value = command[2]
self.__server.setPrefRegex(name, value) self.__server.setPrefRegex(name, value)
if self.__quiet: return
return self.__server.getPrefRegex(name) return self.__server.getPrefRegex(name)
elif command[1] == "addfailregex": elif command[1] == "addfailregex":
value = command[2] value = command[2]
self.__server.addFailRegex(name, value, multiple=multiple) self.__server.addFailRegex(name, value, multiple=multiple)
if multiple: if multiple:
return True return True
if self.__quiet: return
return self.__server.getFailRegex(name) return self.__server.getFailRegex(name)
elif command[1] == "delfailregex": elif command[1] == "delfailregex":
value = int(command[2]) value = int(command[2])
self.__server.delFailRegex(name, value) self.__server.delFailRegex(name, value)
if self.__quiet: return
return self.__server.getFailRegex(name) return self.__server.getFailRegex(name)
elif command[1] == "addignoreregex": elif command[1] == "addignoreregex":
value = command[2] value = command[2]
self.__server.addIgnoreRegex(name, value, multiple=multiple) self.__server.addIgnoreRegex(name, value, multiple=multiple)
if multiple: if multiple:
return True return True
if self.__quiet: return
return self.__server.getIgnoreRegex(name) return self.__server.getIgnoreRegex(name)
elif command[1] == "delignoreregex": elif command[1] == "delignoreregex":
value = int(command[2]) value = int(command[2])
self.__server.delIgnoreRegex(name, value) self.__server.delIgnoreRegex(name, value)
if self.__quiet: return
return self.__server.getIgnoreRegex(name) return self.__server.getIgnoreRegex(name)
elif command[1] == "usedns": elif command[1] == "usedns":
value = command[2] value = command[2]
self.__server.setUseDns(name, value) self.__server.setUseDns(name, value)
if self.__quiet: return
return self.__server.getUseDns(name) return self.__server.getUseDns(name)
elif command[1] == "findtime": elif command[1] == "findtime":
value = command[2] value = command[2]
self.__server.setFindTime(name, value) self.__server.setFindTime(name, value)
if self.__quiet: return
return self.__server.getFindTime(name) return self.__server.getFindTime(name)
elif command[1] == "datepattern": elif command[1] == "datepattern":
value = command[2] value = command[2]
self.__server.setDatePattern(name, value) self.__server.setDatePattern(name, value)
if self.__quiet: return
return self.__server.getDatePattern(name) return self.__server.getDatePattern(name)
elif command[1] == "logtimezone": elif command[1] == "logtimezone":
value = command[2] value = command[2]
self.__server.setLogTimeZone(name, value) self.__server.setLogTimeZone(name, value)
if self.__quiet: return
return self.__server.getLogTimeZone(name) return self.__server.getLogTimeZone(name)
elif command[1] == "maxretry": elif command[1] == "maxretry":
value = command[2] value = command[2]
self.__server.setMaxRetry(name, int(value)) self.__server.setMaxRetry(name, int(value))
if self.__quiet: return
return self.__server.getMaxRetry(name) return self.__server.getMaxRetry(name)
elif command[1] == "maxlines": elif command[1] == "maxlines":
value = command[2] value = command[2]
self.__server.setMaxLines(name, int(value)) self.__server.setMaxLines(name, int(value))
if self.__quiet: return
return self.__server.getMaxLines(name) return self.__server.getMaxLines(name)
# command # command
elif command[1] == "bantime": elif command[1] == "bantime":
value = command[2] value = command[2]
self.__server.setBanTime(name, value) self.__server.setBanTime(name, value)
if self.__quiet: return
return self.__server.getBanTime(name) return self.__server.getBanTime(name)
elif command[1] == "attempt": elif command[1] == "attempt":
value = command[2:] value = command[2:]
if self.__quiet: return
return self.__server.addAttemptIP(name, *value) return self.__server.addAttemptIP(name, *value)
elif command[1] == "banip": elif command[1] == "banip":
value = command[2:] value = command[2:]
@ -301,6 +342,7 @@ class Transmitter:
if len(command) > 3: if len(command) > 3:
args.extend([command[3], json.loads(command[4])]) args.extend([command[3], json.loads(command[4])])
self.__server.addAction(name, *args) self.__server.addAction(name, *args)
if self.__quiet: return
return args[0] return args[0]
elif command[1] == "delaction": elif command[1] == "delaction":
value = command[2] value = command[2]
@ -324,10 +366,12 @@ class Transmitter:
actionkey = command[3] actionkey = command[3]
if callable(getattr(action, actionkey, None)): if callable(getattr(action, actionkey, None)):
actionvalue = json.loads(command[4]) if len(command)>4 else {} actionvalue = json.loads(command[4]) if len(command)>4 else {}
if self.__quiet: return
return getattr(action, actionkey)(**actionvalue) return getattr(action, actionkey)(**actionvalue)
else: else:
actionvalue = command[4] actionvalue = command[4]
setattr(action, actionkey, actionvalue) setattr(action, actionkey, actionvalue)
if self.__quiet: return
return getattr(action, actionkey) return getattr(action, actionkey)
raise Exception("Invalid command %r (no set action or not yet implemented)" % (command[1],)) raise Exception("Invalid command %r (no set action or not yet implemented)" % (command[1],))

View File

@ -878,9 +878,9 @@ class JailsReaderTest(LogCaptureTestCase):
% (option, commands)) % (option, commands))
# Set up of logging should come first # Set up of logging should come first
self.assertEqual(find_set('syslogsocket'), 0) self.assertTrue(
self.assertEqual(find_set('loglevel'), 1) find_set('syslogsocket') < find_set('loglevel') < find_set('logtarget')
self.assertEqual(find_set('logtarget'), 2) )
# then dbfile should be before dbpurgeage # then dbfile should be before dbpurgeage
self.assertTrue(find_set('dbpurgeage') > find_set('dbfile')) self.assertTrue(find_set('dbpurgeage') > find_set('dbfile'))