mirror of https://github.com/fail2ban/fail2ban
try to start server in foreground
# Conflicts: # fail2ban/server/server.pypull/1321/head
parent
134c33cc6d
commit
44490664f5
|
@ -54,6 +54,7 @@ class Fail2banClient:
|
|||
PROMPT = "fail2ban> "
|
||||
|
||||
def __init__(self):
|
||||
self.__server = None
|
||||
self.__argv = None
|
||||
self.__stream = None
|
||||
self.__configurator = Configurator()
|
||||
|
@ -89,13 +90,16 @@ class Fail2banClient:
|
|||
print " -c <DIR> configuration directory"
|
||||
print " -s <FILE> socket path"
|
||||
print " -p <FILE> pidfile path"
|
||||
print " --loglevel <LEVEL> logging level"
|
||||
print " --logtarget <FILE>|STDOUT|STDERR|SYSLOG"
|
||||
print " --syslogsocket auto|file"
|
||||
print " -d dump configuration. For debugging"
|
||||
print " -i interactive mode"
|
||||
print " -v increase verbosity"
|
||||
print " -q decrease verbosity"
|
||||
print " -x force execution of the server (remove socket file)"
|
||||
print " -b start server in background (default)"
|
||||
print " -f start server in foreground (note that the client forks once itself)"
|
||||
print " -f start server in foreground"
|
||||
print " -h, --help display this help message"
|
||||
print " -V, --version print the version"
|
||||
print
|
||||
|
@ -128,6 +132,8 @@ class Fail2banClient:
|
|||
self.__conf["socket"] = opt[1]
|
||||
elif opt[0] == "-p":
|
||||
self.__conf["pidfile"] = opt[1]
|
||||
elif opt[0].startswith("--log") or opt[0].startswith("--sys"):
|
||||
self.__conf[ opt[0][2:] ] = opt[1]
|
||||
elif opt[0] == "-d":
|
||||
self.__conf["dump"] = True
|
||||
elif opt[0] == "-v":
|
||||
|
@ -234,24 +240,32 @@ class Fail2banClient:
|
|||
"Directory %s exists but not accessible for writing"
|
||||
% (socket_dir,))
|
||||
return False
|
||||
# Start the server
|
||||
self.__startServerAsync(self.__conf["socket"],
|
||||
self.__conf["pidfile"],
|
||||
self.__conf["force"],
|
||||
self.__conf["background"])
|
||||
try:
|
||||
# Wait for the server to start
|
||||
self.__waitOnServer()
|
||||
# Configure the server
|
||||
self.__processCmd(self.__stream, False)
|
||||
return True
|
||||
except ServerExecutionException:
|
||||
logSys.error("Could not start server. Maybe an old "
|
||||
"socket file is still present. Try to "
|
||||
"remove " + self.__conf["socket"] + ". If "
|
||||
"you used fail2ban-client to start the "
|
||||
"server, adding the -x option will do it")
|
||||
|
||||
# Check already running
|
||||
if not self.__conf["force"] and os.path.exists(self.__conf["socket"]):
|
||||
logSys.error("Fail2ban seems to be in unexpected state (not running but socket exists)")
|
||||
return False
|
||||
|
||||
# Start the server
|
||||
t = None
|
||||
if self.__conf["background"]:
|
||||
# Start server daemon as fork of client process:
|
||||
self.__startServerAsync()
|
||||
# Send config stream to server:
|
||||
return self.__processStartStreamAfterWait()
|
||||
else:
|
||||
# In foreground mode we should start server/client communication in other thread:
|
||||
from threading import Thread
|
||||
t = Thread(target=Fail2banClient.__processStartStreamAfterWait, args=(self,))
|
||||
t.start()
|
||||
# Start server direct here in main thread:
|
||||
try:
|
||||
self.__startServerDirect()
|
||||
except KeyboardInterrupt:
|
||||
None
|
||||
|
||||
return True
|
||||
|
||||
elif len(cmd) == 1 and cmd[0] == "reload":
|
||||
if self.__ping():
|
||||
ret = self.__readConfig()
|
||||
|
@ -281,12 +295,50 @@ class Fail2banClient:
|
|||
return self.__processCmd([cmd])
|
||||
|
||||
|
||||
def __processStartStreamAfterWait(self):
|
||||
try:
|
||||
# Wait for the server to start
|
||||
self.__waitOnServer()
|
||||
# Configure the server
|
||||
self.__processCmd(self.__stream, False)
|
||||
except ServerExecutionException:
|
||||
logSys.error("Could not start server. Maybe an old "
|
||||
"socket file is still present. Try to "
|
||||
"remove " + self.__conf["socket"] + ". If "
|
||||
"you used fail2ban-client to start the "
|
||||
"server, adding the -x option will do it")
|
||||
if not self.__conf["background"]:
|
||||
self.__server.quit()
|
||||
sys.exit(-1)
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
##
|
||||
# Start Fail2Ban server in main thread without fork (foreground).
|
||||
#
|
||||
# Start the Fail2ban server in foreground (daemon mode or not).
|
||||
|
||||
def __startServerDirect(self):
|
||||
from fail2ban.server.server import Server
|
||||
try:
|
||||
self.__server = Server(False)
|
||||
self.__server.start(self.__conf["socket"],
|
||||
self.__conf["pidfile"], self.__conf["force"],
|
||||
conf=self.__conf)
|
||||
except Exception, e:
|
||||
logSys.exception(e)
|
||||
if self.__server:
|
||||
self.__server.quit()
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
##
|
||||
# Start Fail2Ban server.
|
||||
#
|
||||
# Start the Fail2ban server in daemon mode.
|
||||
|
||||
def __startServerAsync(self, socket, pidfile, force = False, background = True):
|
||||
def __startServerAsync(self):
|
||||
# Forks the current process.
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
|
@ -294,18 +346,15 @@ class Fail2banClient:
|
|||
args.append(self.SERVER)
|
||||
# Set the socket path.
|
||||
args.append("-s")
|
||||
args.append(socket)
|
||||
args.append(self.__conf["socket"])
|
||||
# Set the pidfile
|
||||
args.append("-p")
|
||||
args.append(pidfile)
|
||||
args.append(self.__conf["pidfile"])
|
||||
# Force the execution if needed.
|
||||
if force:
|
||||
if self.__conf["force"]:
|
||||
args.append("-x")
|
||||
# Start in foreground mode if requested.
|
||||
if background:
|
||||
args.append("-b")
|
||||
else:
|
||||
args.append("-f")
|
||||
# Start in background as requested.
|
||||
args.append("-b")
|
||||
|
||||
try:
|
||||
# Use the current directory.
|
||||
|
@ -361,7 +410,7 @@ class Fail2banClient:
|
|||
# Reads the command line options.
|
||||
try:
|
||||
cmdOpts = 'hc:s:p:xfbdviqV'
|
||||
cmdLongOpts = ['help', 'version']
|
||||
cmdLongOpts = ['loglevel', 'logtarget', 'syslogsocket', 'help', 'version']
|
||||
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
|
||||
except getopt.GetoptError:
|
||||
self.dispUsage()
|
||||
|
@ -396,7 +445,17 @@ class Fail2banClient:
|
|||
self.__conf["socket"] = conf["socket"]
|
||||
if self.__conf["pidfile"] is None:
|
||||
self.__conf["pidfile"] = conf["pidfile"]
|
||||
logSys.info("Using socket file " + self.__conf["socket"])
|
||||
if self.__conf.get("logtarget", None) is None:
|
||||
self.__conf["logtarget"] = conf["logtarget"]
|
||||
if self.__conf.get("loglevel", None) is None:
|
||||
self.__conf["loglevel"] = conf["loglevel"]
|
||||
if self.__conf.get("syslogsocket", None) is None:
|
||||
self.__conf["syslogsocket"] = conf["syslogsocket"]
|
||||
|
||||
logSys.info("Using socket file %s", self.__conf["socket"])
|
||||
|
||||
logSys.info("Using pid file %s, [%s] logging to %s",
|
||||
self.__conf["pidfile"], self.__conf["loglevel"], self.__conf["logtarget"])
|
||||
|
||||
if self.__conf["dump"]:
|
||||
ret = self.__readConfig()
|
||||
|
|
|
@ -129,7 +129,8 @@ class Fail2banServer:
|
|||
return True
|
||||
except Exception, e:
|
||||
logSys.exception(e)
|
||||
self.__server.quit()
|
||||
if self.__server:
|
||||
self.__server.quit()
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -40,8 +40,13 @@ class Fail2banReader(ConfigReader):
|
|||
ConfigReader.read(self, "fail2ban")
|
||||
|
||||
def getEarlyOptions(self):
|
||||
opts = [["string", "socket", "/var/run/fail2ban/fail2ban.sock"],
|
||||
["string", "pidfile", "/var/run/fail2ban/fail2ban.pid"]]
|
||||
opts = [
|
||||
["string", "socket", "/var/run/fail2ban/fail2ban.sock"],
|
||||
["string", "pidfile", "/var/run/fail2ban/fail2ban.pid"],
|
||||
["string", "loglevel", "INFO"],
|
||||
["string", "logtarget", "/var/log/fail2ban.log"],
|
||||
["string", "syslogsocket", "auto"]
|
||||
]
|
||||
return ConfigReader.getOptions(self, "Definition", opts)
|
||||
|
||||
def getOptions(self):
|
||||
|
|
|
@ -67,10 +67,6 @@ class Server:
|
|||
'FreeBSD': '/var/run/log',
|
||||
'Linux': '/dev/log',
|
||||
}
|
||||
self.setSyslogSocket("auto")
|
||||
# Set logging level
|
||||
self.setLogLevel("INFO")
|
||||
self.setLogTarget("STDOUT")
|
||||
|
||||
def __sigTERMhandler(self, signum, frame):
|
||||
logSys.debug("Caught signal %d. Exiting" % signum)
|
||||
|
@ -80,7 +76,12 @@ class Server:
|
|||
logSys.debug("Caught signal %d. Flushing logs" % signum)
|
||||
self.flushLogs()
|
||||
|
||||
def start(self, sock, pidfile, force = False):
|
||||
def start(self, sock, pidfile, force=False, conf={}):
|
||||
# First set all logging parameters:
|
||||
self.setSyslogSocket(conf.get("syslogsocket", "auto"))
|
||||
self.setLogLevel(conf.get("loglevel", "INFO"))
|
||||
self.setLogTarget(conf.get("logtarget", "STDOUT"))
|
||||
|
||||
logSys.info("Starting Fail2ban v%s", version.version)
|
||||
|
||||
# Install signal handlers
|
||||
|
@ -392,8 +393,9 @@ class Server:
|
|||
# @param target the logging target
|
||||
|
||||
def setLogTarget(self, target):
|
||||
try:
|
||||
self.__loggingLock.acquire()
|
||||
with self.__loggingLock:
|
||||
if self.__logTarget == target:
|
||||
return True
|
||||
# set a format which is simpler for console use
|
||||
formatter = logging.Formatter("%(asctime)s %(name)-24s[%(process)d]: %(levelname)-7s %(message)s")
|
||||
if target == "SYSLOG":
|
||||
|
@ -461,8 +463,6 @@ class Server:
|
|||
# Sets the logging target.
|
||||
self.__logTarget = target
|
||||
return True
|
||||
finally:
|
||||
self.__loggingLock.release()
|
||||
|
||||
##
|
||||
# Sets the syslog socket.
|
||||
|
|
Loading…
Reference in New Issue