- Added "-s" option to specify the socket path

- Modified the server server/socket/transmitter design

git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@406 a942ae1a-1317-0410-a47c-b1dcaea8d605
0.x
Cyril Jaquier 2006-10-04 22:17:53 +00:00
parent 85293c63e4
commit 7989e66270
9 changed files with 48 additions and 55 deletions

View File

@ -12,6 +12,7 @@ ver. 0.7.4 (2006/09/28) - beta
- Improved configuration files. Thanks to Yaroslav Halchenko - Improved configuration files. Thanks to Yaroslav Halchenko
- Added man page for "fail2ban-regex" - Added man page for "fail2ban-regex"
- Moved ban/unban messages from "info" level to "warn" - Moved ban/unban messages from "info" level to "warn"
- Added "-s" option to specify the socket path
ver. 0.7.3 (2006/09/28) - beta ver. 0.7.3 (2006/09/28) - beta
---------- ----------

View File

@ -30,14 +30,13 @@ import socket
class CSocket: class CSocket:
END_STRING = "<F2B_END_COMMAND>" END_STRING = "<F2B_END_COMMAND>"
SOCKET_FILE = "/tmp/fail2ban.sock"
def __init__(self): def __init__(self, sock = "/tmp/fail2ban.sock"):
# Create an INET, STREAMing socket # Create an INET, STREAMing socket
#self.csock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #self.csock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__csock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.__csock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
#self.csock.connect(("localhost", 2222)) #self.csock.connect(("localhost", 2222))
self.__csock.connect(CSocket.SOCKET_FILE) self.__csock.connect(sock)
def send(self, msg): def send(self, msg):
# Convert every list member to string # Convert every list member to string

View File

@ -58,6 +58,7 @@ class Fail2banClient:
self.__conf["force"] = False self.__conf["force"] = False
self.__conf["verbose"] = 2 self.__conf["verbose"] = 2
self.__conf["interactive"] = False self.__conf["interactive"] = False
self.__conf["socket"] = "/tmp/fail2ban.sock"
def dispVersion(self): def dispVersion(self):
print "Fail2Ban v" + version print "Fail2Ban v" + version
@ -79,6 +80,7 @@ class Fail2banClient:
print print
print "Options:" print "Options:"
print " -c <DIR> configuration directory" print " -c <DIR> configuration directory"
print " -s <FILE> socket path"
print " -d dump configuration. For debugging" print " -d dump configuration. For debugging"
print " -i interactive mode" print " -i interactive mode"
print " -v increase verbosity" print " -v increase verbosity"
@ -118,6 +120,8 @@ class Fail2banClient:
for opt in optList: for opt in optList:
if opt[0] == "-c": if opt[0] == "-c":
self.__conf["conf"] = opt[1] self.__conf["conf"] = opt[1]
elif opt[0] == "-s":
self.__conf["socket"] = opt[1]
elif opt[0] == "-d": elif opt[0] == "-d":
self.__conf["dump"] = True self.__conf["dump"] = True
elif opt[0] == "-v": elif opt[0] == "-v":
@ -136,15 +140,14 @@ class Fail2banClient:
sys.exit(0) sys.exit(0)
def __ping(self): def __ping(self):
return self.processCmd([["ping"]], False) return self.__processCmd([["ping"]], False)
@staticmethod def __processCmd(self, cmd, showRet = True):
def processCmd(cmd, showRet = True):
beautifier = Beautifier() beautifier = Beautifier()
for c in cmd: for c in cmd:
beautifier.setInputCmd(c) beautifier.setInputCmd(c)
try: try:
client = CSocket() client = CSocket(self.__conf["socket"])
ret = client.send(c) ret = client.send(c)
if ret[0] == 0: if ret[0] == 0:
logSys.debug("OK : " + `ret[1]`) logSys.debug("OK : " + `ret[1]`)
@ -183,7 +186,7 @@ class Fail2banClient:
# Wait for the server to start # Wait for the server to start
self.__waitOnServer() self.__waitOnServer()
# Configure the server # Configure the server
self.processCmd(self.__stream, False) self.__processCmd(self.__stream, False)
return True return True
except ServerExecutionException: except ServerExecutionException:
logSys.error("Could not start server. Try -x option") logSys.error("Could not start server. Try -x option")
@ -191,14 +194,14 @@ class Fail2banClient:
elif len(cmd) == 1 and cmd[0] == "reload": elif len(cmd) == 1 and cmd[0] == "reload":
if self.__ping(): if self.__ping():
self.__readConfig() self.__readConfig()
self.processCmd([['stop', 'all']], False) self.__processCmd([['stop', 'all']], False)
# Configure the server # Configure the server
return self.processCmd(self.__stream, False) return self.__processCmd(self.__stream, False)
else: else:
logSys.error("Could not find server") logSys.error("Could not find server")
return False return False
else: else:
return self.processCmd([cmd]) return self.__processCmd([cmd])
## ##
@ -244,7 +247,7 @@ class Fail2banClient:
# Reads the command line options. # Reads the command line options.
try: try:
cmdOpts = 'hc:xdviqV' cmdOpts = 'hc:s:xdviqV'
cmdLongOpts = ['help', 'version'] cmdLongOpts = ['help', 'version']
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts) optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
except getopt.GetoptError: except getopt.GetoptError:
@ -327,4 +330,3 @@ if __name__ == "__main__":
sys.exit(0) sys.exit(0)
else: else:
sys.exit(-1) sys.exit(-1)

View File

@ -50,6 +50,7 @@ class Fail2banServer:
self.__conf = dict() self.__conf = dict()
self.__conf["background"] = True self.__conf["background"] = True
self.__conf["force"] = False self.__conf["force"] = False
self.__conf["socket"] = "/tmp/fail2ban.sock"
def dispVersion(self): def dispVersion(self):
print "Fail2Ban v" + version print "Fail2Ban v" + version
@ -75,6 +76,7 @@ class Fail2banServer:
print "Options:" print "Options:"
print " -b start in background" print " -b start in background"
print " -f start in foreground" print " -f start in foreground"
print " -s <FILE> socket path"
print " -x force execution of the server" print " -x force execution of the server"
print " -h, --help display this help message" print " -h, --help display this help message"
print " -V, --version print the version" print " -V, --version print the version"
@ -89,6 +91,8 @@ class Fail2banServer:
self.__conf["background"] = True self.__conf["background"] = True
if opt[0] == "-f": if opt[0] == "-f":
self.__conf["background"] = False self.__conf["background"] = False
if opt[0] == "-s":
self.__conf["socket"] = opt[1]
if opt[0] == "-x": if opt[0] == "-x":
self.__conf["force"] = True self.__conf["force"] = True
if opt[0] in ["-h", "--help"]: if opt[0] in ["-h", "--help"]:
@ -104,7 +108,7 @@ class Fail2banServer:
# Reads the command line options. # Reads the command line options.
try: try:
cmdOpts = 'bfxhV' cmdOpts = 'bfs:xhV'
cmdLongOpts = ['help', 'version'] cmdLongOpts = ['help', 'version']
optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts) optList, args = getopt.getopt(self.__argv[1:], cmdOpts, cmdLongOpts)
except getopt.GetoptError: except getopt.GetoptError:
@ -114,7 +118,7 @@ class Fail2banServer:
try: try:
self.__server = Server(self.__conf["background"]) self.__server = Server(self.__conf["background"])
self.__server.start(self.__conf["force"]) self.__server.start(self.__conf["socket"], self.__conf["force"])
return True return True
except Exception, e: except Exception, e:
print e print e

View File

@ -13,6 +13,9 @@ and bans the corresponding IP addresses using firewall rules.
\fB\-c\fR <DIR> \fB\-c\fR <DIR>
configuration directory configuration directory
.TP .TP
\fB\-s\fR <FILE>
socket path
.TP
\fB\-d\fR \fB\-d\fR
dump configuration. For debugging dump configuration. For debugging
.TP .TP

View File

@ -19,6 +19,9 @@ start in background
\fB\-f\fR \fB\-f\fR
start in foreground start in foreground
.TP .TP
\fB\-s\fR <FILE>
socket path
.TP
\fB\-x\fR \fB\-x\fR
force execution of the server force execution of the server
.TP .TP

View File

@ -26,6 +26,8 @@ __license__ = "GPL"
from jails import Jails from jails import Jails
from transmitter import Transmitter from transmitter import Transmitter
from ssocket import SSocket
from ssocket import SSocketErrorException
import logging, logging.handlers, sys, os, signal import logging, logging.handlers, sys, os, signal
# Gets the instance of the logger. # Gets the instance of the logger.
@ -37,13 +39,14 @@ class Server:
self.__jails = Jails() self.__jails = Jails()
self.__daemon = daemon self.__daemon = daemon
self.__transm = Transmitter(self) self.__transm = Transmitter(self)
self.__socket = SSocket(self.__transm)
self.__logLevel = 3 self.__logLevel = 3
self.__logTarget = "STDOUT" self.__logTarget = "STDOUT"
# Set logging level # Set logging level
self.setLogLevel(self.__logLevel) self.setLogLevel(self.__logLevel)
self.setLogTarget(self.__logTarget) self.setLogTarget(self.__logTarget)
def start(self, force): def start(self, sock, force = False):
logSys.info("Starting Fail2ban") logSys.info("Starting Fail2ban")
# First set the mask to only allow access to owner # First set the mask to only allow access to owner
os.umask(0077) os.umask(0077)
@ -56,12 +59,18 @@ class Server:
raise ServerInitializationError("Could not create daemon") raise ServerInitializationError("Could not create daemon")
# Start the communication # Start the communication
logSys.debug("Starting communication") logSys.debug("Starting communication")
self.__transm.start(force) try:
self.__socket.initialize(sock, force)
self.__socket.start()
self.__socket.join()
except SSocketErrorException:
logSys.error("Could not start server")
logSys.info("Exiting Fail2ban") logSys.info("Exiting Fail2ban")
def quit(self): def quit(self):
self.stopAllJail() self.stopAllJail()
self.__transm.stop() # Stop communication
self.__socket.stop()
def addJail(self, name): def addJail(self, name):
self.__jails.add(name) self.__jails.add(name)

View File

@ -34,21 +34,22 @@ logSys = logging.getLogger("fail2ban.comm")
class SSocket(Thread): class SSocket(Thread):
END_STRING = "<F2B_END_COMMAND>" END_STRING = "<F2B_END_COMMAND>"
SOCKET_FILE = "/tmp/fail2ban.sock"
def __init__(self, transmitter): def __init__(self, transmitter):
Thread.__init__(self) Thread.__init__(self)
self.__transmit = transmitter self.__transmit = transmitter
self.__isRunning = False self.__isRunning = False
self.__socket = "/tmp/fail2ban.sock"
logSys.debug("Created SSocket") logSys.debug("Created SSocket")
def initialize(self, force = False): def initialize(self, sock = "/tmp/fail2ban.sock", force = False):
self.__socket = sock
# Remove socket # Remove socket
if os.path.exists(SSocket.SOCKET_FILE): if os.path.exists(sock):
logSys.error("Fail2ban seems to be already running") logSys.error("Fail2ban seems to be already running")
if force: if force:
logSys.warn("Forcing execution of the server") logSys.warn("Forcing execution of the server")
os.remove(SSocket.SOCKET_FILE) os.remove(sock)
else: else:
raise SSocketErrorException("Server already running") raise SSocketErrorException("Server already running")
# Create an INET, STREAMing socket # Create an INET, STREAMing socket
@ -62,7 +63,7 @@ class SSocket(Thread):
self.ssock.settimeout(1) self.ssock.settimeout(1)
# Bind the socket to a public host and a well-known port # Bind the socket to a public host and a well-known port
#self.ssock.bind(("localhost", 2222)) #self.ssock.bind(("localhost", 2222))
self.ssock.bind(SSocket.SOCKET_FILE) self.ssock.bind(sock)
# Become a server socket # Become a server socket
self.ssock.listen(5) self.ssock.listen(5)
@ -78,9 +79,9 @@ class SSocket(Thread):
pass pass
self.ssock.close() self.ssock.close()
# Remove socket # Remove socket
if os.path.exists(SSocket.SOCKET_FILE): if os.path.exists(self.__socket):
logSys.debug("Removed socket file " + SSocket.SOCKET_FILE) logSys.debug("Removed socket file " + self.__socket)
os.remove(SSocket.SOCKET_FILE) os.remove(self.__socket)
logSys.debug("Socket shutdown") logSys.debug("Socket shutdown")
return True return True

View File

@ -24,8 +24,6 @@ __date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL" __license__ = "GPL"
from ssocket import SSocket
from ssocket import SSocketErrorException
from threading import Lock from threading import Lock
import logging, time import logging, time
@ -37,33 +35,6 @@ class Transmitter:
def __init__(self, server): def __init__(self, server):
self.__lock = Lock() self.__lock = Lock()
self.__server = server self.__server = server
self.__socket = SSocket(self)
##
# Start the transmittion server.
#
# This function wait for the socket thread.
def start(self, force):
try:
self.__lock.acquire()
self.__socket.initialize(force)
self.__socket.start()
self.__lock.release()
self.__socket.join()
except SSocketErrorException:
logSys.error("Could not start server")
self.__lock.release()
##
# Stop the transmitter.
#
# @bug Fix the issue with join(). When using servertestcase.py, errors
# happen which disappear when using join() in this function.
def stop(self):
self.__socket.stop()
self.__socket.join()
def proceed(self, action): def proceed(self, action):
# Deserialize object # Deserialize object