mirror of https://github.com/fail2ban/fail2ban
- 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-b1dcaea8d6050.x
parent
85293c63e4
commit
7989e66270
|
@ -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
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue