summaryrefslogtreecommitdiff
path: root/bin/fail2ban-client
diff options
context:
space:
mode:
authorsebres <serg.brester@sebres.de>2016-02-09 14:23:40 +0100
committersebres <serg.brester@sebres.de>2016-05-12 11:51:47 +0200
commit4ce240ed4055b37b870027a41ba8e432a69dc531 (patch)
treeb4c095421195e6350d75b7786c568d18d5018de5 /bin/fail2ban-client
parent9b72522a01a323fb9ae35ed0b58690317682c0aa (diff)
downloadfail2ban-4ce240ed4055b37b870027a41ba8e432a69dc531.tar.gz
try to start server in foreground
# Conflicts: # fail2ban/server/server.py
Diffstat (limited to 'bin/fail2ban-client')
-rwxr-xr-xbin/fail2ban-client117
1 files changed, 88 insertions, 29 deletions
diff --git a/bin/fail2ban-client b/bin/fail2ban-client
index bc0c0be8..631afb31 100755
--- a/bin/fail2ban-client
+++ b/bin/fail2ban-client
@@ -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()
@@ -398,7 +447,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()