mirror of https://github.com/fail2ban/fail2ban
Revert to upstream
parent
3114fed8d1
commit
7bbfe5c67c
|
@ -18,7 +18,7 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
# Author: Cyril Jaquier
|
# Author: Cyril Jaquier
|
||||||
#
|
#
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier"
|
__author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
|
@ -31,34 +31,32 @@ from configreader import ConfigReader
|
||||||
logSys = logging.getLogger("fail2ban.client.config")
|
logSys = logging.getLogger("fail2ban.client.config")
|
||||||
|
|
||||||
class FilterReader(ConfigReader):
|
class FilterReader(ConfigReader):
|
||||||
|
|
||||||
def __init__(self, fileName, name, **kwargs):
|
def __init__(self, fileName, name, **kwargs):
|
||||||
ConfigReader.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
self.__file = fileName
|
self.__file = fileName
|
||||||
self.__name = name
|
self.__name = name
|
||||||
|
|
||||||
def setFile(self, fileName):
|
def setFile(self, fileName):
|
||||||
self.__file = fileName
|
self.__file = fileName
|
||||||
|
|
||||||
def getFile(self):
|
def getFile(self):
|
||||||
return self.__file
|
return self.__file
|
||||||
|
|
||||||
def setName(self, name):
|
def setName(self, name):
|
||||||
self.__name = name
|
self.__name = name
|
||||||
|
|
||||||
def getName(self):
|
def getName(self):
|
||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
return ConfigReader.read(self, "filter.d/" + self.__file)
|
return ConfigReader.read(self, "filter.d/" + self.__file)
|
||||||
|
|
||||||
def getOptions(self, pOpts):
|
def getOptions(self, pOpts):
|
||||||
opts = [["string", "ignoreregex", ""],
|
opts = [["string", "ignoreregex", ""],
|
||||||
["string", "failregex", ""],
|
["string", "failregex", ""]]
|
||||||
["string", "ignorecommand", ""]
|
|
||||||
]
|
|
||||||
self.__opts = ConfigReader.getOptions(self, "Definition", opts, pOpts)
|
self.__opts = ConfigReader.getOptions(self, "Definition", opts, pOpts)
|
||||||
|
|
||||||
def convert(self):
|
def convert(self):
|
||||||
stream = list()
|
stream = list()
|
||||||
for opt in self.__opts:
|
for opt in self.__opts:
|
||||||
|
@ -71,6 +69,6 @@ class FilterReader(ConfigReader):
|
||||||
for regex in self.__opts[opt].split('\n'):
|
for regex in self.__opts[opt].split('\n'):
|
||||||
# Do not send a command if the rule is empty.
|
# Do not send a command if the rule is empty.
|
||||||
if regex != '':
|
if regex != '':
|
||||||
stream.append(["set", self.__name, "addignoreregex", regex])
|
stream.append(["set", self.__name, "addignoreregex", regex])
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
# Author: Cyril Jaquier
|
# Author: Cyril Jaquier
|
||||||
#
|
#
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier"
|
__author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
|
@ -34,25 +34,25 @@ from actionreader import ActionReader
|
||||||
logSys = logging.getLogger("fail2ban.client.config")
|
logSys = logging.getLogger("fail2ban.client.config")
|
||||||
|
|
||||||
class JailReader(ConfigReader):
|
class JailReader(ConfigReader):
|
||||||
|
|
||||||
actionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
|
actionCRE = re.compile("^((?:\w|-|_|\.)+)(?:\[(.*)\])?$")
|
||||||
|
|
||||||
def __init__(self, name, force_enable=False, **kwargs):
|
def __init__(self, name, force_enable=False, **kwargs):
|
||||||
ConfigReader.__init__(self, **kwargs)
|
ConfigReader.__init__(self, **kwargs)
|
||||||
self.__name = name
|
self.__name = name
|
||||||
self.__filter = None
|
self.__filter = None
|
||||||
self.__force_enable = force_enable
|
self.__force_enable = force_enable
|
||||||
self.__actions = list()
|
self.__actions = list()
|
||||||
|
|
||||||
def setName(self, value):
|
def setName(self, value):
|
||||||
self.__name = value
|
self.__name = value
|
||||||
|
|
||||||
def getName(self):
|
def getName(self):
|
||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
return ConfigReader.read(self, "jail")
|
return ConfigReader.read(self, "jail")
|
||||||
|
|
||||||
def isEnabled(self):
|
def isEnabled(self):
|
||||||
return self.__force_enable or self.__opts["enabled"]
|
return self.__force_enable or self.__opts["enabled"]
|
||||||
|
|
||||||
|
@ -81,13 +81,12 @@ class JailReader(ConfigReader):
|
||||||
["int", "bantime", 600],
|
["int", "bantime", 600],
|
||||||
["string", "usedns", "warn"],
|
["string", "usedns", "warn"],
|
||||||
["string", "failregex", None],
|
["string", "failregex", None],
|
||||||
["string", "ignorecommand", None],
|
|
||||||
["string", "ignoreregex", None],
|
["string", "ignoreregex", None],
|
||||||
["string", "ignoreip", None],
|
["string", "ignoreip", None],
|
||||||
["string", "filter", ""],
|
["string", "filter", ""],
|
||||||
["string", "action", ""]]
|
["string", "action", ""]]
|
||||||
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
self.__opts = ConfigReader.getOptions(self, self.__name, opts)
|
||||||
|
|
||||||
if self.isEnabled():
|
if self.isEnabled():
|
||||||
# Read filter
|
# Read filter
|
||||||
self.__filter = FilterReader(self.__opts["filter"], self.__name,
|
self.__filter = FilterReader(self.__opts["filter"], self.__name,
|
||||||
|
@ -98,7 +97,7 @@ class JailReader(ConfigReader):
|
||||||
else:
|
else:
|
||||||
logSys.error("Unable to read the filter")
|
logSys.error("Unable to read the filter")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Read action
|
# Read action
|
||||||
for act in self.__opts["action"].split('\n'):
|
for act in self.__opts["action"].split('\n'):
|
||||||
try:
|
try:
|
||||||
|
@ -119,7 +118,7 @@ class JailReader(ConfigReader):
|
||||||
if not len(self.__actions):
|
if not len(self.__actions):
|
||||||
logSys.warn("No actions were defined for %s" % self.__name)
|
logSys.warn("No actions were defined for %s" % self.__name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def convert(self, allow_no_files=False):
|
def convert(self, allow_no_files=False):
|
||||||
"""Convert read before __opts to the commands stream
|
"""Convert read before __opts to the commands stream
|
||||||
|
|
||||||
|
@ -161,8 +160,6 @@ class JailReader(ConfigReader):
|
||||||
stream.append(["set", self.__name, "usedns", self.__opts[opt]])
|
stream.append(["set", self.__name, "usedns", self.__opts[opt]])
|
||||||
elif opt == "failregex":
|
elif opt == "failregex":
|
||||||
stream.append(["set", self.__name, "addfailregex", self.__opts[opt]])
|
stream.append(["set", self.__name, "addfailregex", self.__opts[opt]])
|
||||||
elif opt == "ignorecommand":
|
|
||||||
stream.append(["set", self.__name, "ignorecommand", self.__opts[opt]])
|
|
||||||
elif opt == "ignoreregex":
|
elif opt == "ignoreregex":
|
||||||
for regex in self.__opts[opt].split('\n'):
|
for regex in self.__opts[opt].split('\n'):
|
||||||
# Do not send a command if the rule is empty.
|
# Do not send a command if the rule is empty.
|
||||||
|
@ -173,7 +170,7 @@ class JailReader(ConfigReader):
|
||||||
stream.extend(action.convert())
|
stream.extend(action.convert())
|
||||||
stream.insert(0, ["add", self.__name, backend])
|
stream.insert(0, ["add", self.__name, backend])
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
#@staticmethod
|
#@staticmethod
|
||||||
def splitAction(action):
|
def splitAction(action):
|
||||||
m = JailReader.actionCRE.match(action)
|
m = JailReader.actionCRE.match(action)
|
||||||
|
@ -205,12 +202,12 @@ class JailReader(ConfigReader):
|
||||||
actions += "<COMMA>"
|
actions += "<COMMA>"
|
||||||
else:
|
else:
|
||||||
actions += c
|
actions += c
|
||||||
|
|
||||||
# Split using ,
|
# Split using ,
|
||||||
actionsSplit = actions.split(',')
|
actionsSplit = actions.split(',')
|
||||||
# Replace the tag <COMMA> with ,
|
# Replace the tag <COMMA> with ,
|
||||||
actionsSplit = [n.replace("<COMMA>", ',') for n in actionsSplit]
|
actionsSplit = [n.replace("<COMMA>", ',') for n in actionsSplit]
|
||||||
|
|
||||||
for param in actionsSplit:
|
for param in actionsSplit:
|
||||||
p = param.split('=')
|
p = param.split('=')
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
# Author: Cyril Jaquier
|
# Author: Cyril Jaquier
|
||||||
#
|
#
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier"
|
__author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
|
@ -31,51 +31,49 @@ import textwrap
|
||||||
|
|
||||||
protocol = [
|
protocol = [
|
||||||
['', "BASIC", ""],
|
['', "BASIC", ""],
|
||||||
["start", "starts the server and the jails"],
|
["start", "starts the server and the jails"],
|
||||||
["reload", "reloads the configuration"],
|
["reload", "reloads the configuration"],
|
||||||
["reload <JAIL>", "reloads the jail <JAIL>"],
|
["reload <JAIL>", "reloads the jail <JAIL>"],
|
||||||
["stop", "stops all jails and terminate the server"],
|
["stop", "stops all jails and terminate the server"],
|
||||||
["status", "gets the current status of the server"],
|
["status", "gets the current status of the server"],
|
||||||
["ping", "tests if the server is alive"],
|
["ping", "tests if the server is alive"],
|
||||||
["help", "return this output"],
|
["help", "return this output"],
|
||||||
['', "LOGGING", ""],
|
['', "LOGGING", ""],
|
||||||
["set loglevel <LEVEL>", "sets logging level to <LEVEL>. 0 is minimal, 4 is debug"],
|
["set loglevel <LEVEL>", "sets logging level to <LEVEL>. 0 is minimal, 4 is debug"],
|
||||||
["get loglevel", "gets the logging level"],
|
["get loglevel", "gets the logging level"],
|
||||||
["set logtarget <TARGET>", "sets logging target to <TARGET>. Can be STDOUT, STDERR, SYSLOG or a file"],
|
["set logtarget <TARGET>", "sets logging target to <TARGET>. Can be STDOUT, STDERR, SYSLOG or a file"],
|
||||||
["get logtarget", "gets logging target"],
|
["get logtarget", "gets logging target"],
|
||||||
['', "JAIL CONTROL", ""],
|
['', "JAIL CONTROL", ""],
|
||||||
["add <JAIL> <BACKEND>", "creates <JAIL> using <BACKEND>"],
|
["add <JAIL> <BACKEND>", "creates <JAIL> using <BACKEND>"],
|
||||||
["start <JAIL>", "starts the jail <JAIL>"],
|
["start <JAIL>", "starts the jail <JAIL>"],
|
||||||
["stop <JAIL>", "stops the jail <JAIL>. The jail is removed"],
|
["stop <JAIL>", "stops the jail <JAIL>. The jail is removed"],
|
||||||
["status <JAIL>", "gets the current status of <JAIL>"],
|
["status <JAIL>", "gets the current status of <JAIL>"],
|
||||||
['', "JAIL CONFIGURATION", ""],
|
['', "JAIL CONFIGURATION", ""],
|
||||||
["set <JAIL> ignorecommand <VALUE>", "sets ignorecommand of <JAIL>"],
|
["set <JAIL> idle on|off", "sets the idle state of <JAIL>"],
|
||||||
["set <JAIL> idle on|off", "sets the idle state of <JAIL>"],
|
["set <JAIL> addignoreip <IP>", "adds <IP> to the ignore list of <JAIL>"],
|
||||||
["set <JAIL> addignoreip <IP>", "adds <IP> to the ignore list of <JAIL>"],
|
["set <JAIL> delignoreip <IP>", "removes <IP> from the ignore list of <JAIL>"],
|
||||||
["set <JAIL> delignoreip <IP>", "removes <IP> from the ignore list of <JAIL>"],
|
["set <JAIL> addlogpath <FILE>", "adds <FILE> to the monitoring list of <JAIL>"],
|
||||||
["set <JAIL> addlogpath <FILE>", "adds <FILE> to the monitoring list of <JAIL>"],
|
|
||||||
["set <JAIL> dellogpath <FILE>", "removes <FILE> from the monitoring list of <JAIL>"],
|
["set <JAIL> dellogpath <FILE>", "removes <FILE> from the monitoring list of <JAIL>"],
|
||||||
["set <JAIL> addfailregex <REGEX>", "adds the regular expression <REGEX> which must match failures for <JAIL>"],
|
["set <JAIL> addfailregex <REGEX>", "adds the regular expression <REGEX> which must match failures for <JAIL>"],
|
||||||
["set <JAIL> delfailregex <INDEX>", "removes the regular expression at <INDEX> for failregex"],
|
["set <JAIL> delfailregex <INDEX>", "removes the regular expression at <INDEX> for failregex"],
|
||||||
["set <JAIL> addignoreregex <REGEX>", "adds the regular expression <REGEX> which should match pattern to exclude for <JAIL>"],
|
["set <JAIL> addignoreregex <REGEX>", "adds the regular expression <REGEX> which should match pattern to exclude for <JAIL>"],
|
||||||
["set <JAIL> delignoreregex <INDEX>", "removes the regular expression at <INDEX> for ignoreregex"],
|
["set <JAIL> delignoreregex <INDEX>", "removes the regular expression at <INDEX> for ignoreregex"],
|
||||||
["set <JAIL> findtime <TIME>", "sets the number of seconds <TIME> for which the filter will look back for <JAIL>"],
|
["set <JAIL> findtime <TIME>", "sets the number of seconds <TIME> for which the filter will look back for <JAIL>"],
|
||||||
["set <JAIL> bantime <TIME>", "sets the number of seconds <TIME> a host will be banned for <JAIL>"],
|
["set <JAIL> bantime <TIME>", "sets the number of seconds <TIME> a host will be banned for <JAIL>"],
|
||||||
["set <JAIL> usedns <VALUE>", "sets the usedns mode for <JAIL>"],
|
["set <JAIL> usedns <VALUE>", "sets the usedns mode for <JAIL>"],
|
||||||
["set <JAIL> banip <IP>", "manually Ban <IP> for <JAIL>"],
|
["set <JAIL> banip <IP>", "manually Ban <IP> for <JAIL>"],
|
||||||
["set <JAIL> unbanip <IP>", "manually Unban <IP> in <JAIL>"],
|
["set <JAIL> unbanip <IP>", "manually Unban <IP> in <JAIL>"],
|
||||||
["set <JAIL> maxretry <RETRY>", "sets the number of failures <RETRY> before banning the host for <JAIL>"],
|
["set <JAIL> maxretry <RETRY>", "sets the number of failures <RETRY> before banning the host for <JAIL>"],
|
||||||
["set <JAIL> addaction <ACT>", "adds a new action named <NAME> for <JAIL>"],
|
["set <JAIL> addaction <ACT>", "adds a new action named <NAME> for <JAIL>"],
|
||||||
["set <JAIL> delaction <ACT>", "removes the action <NAME> from <JAIL>"],
|
["set <JAIL> delaction <ACT>", "removes the action <NAME> from <JAIL>"],
|
||||||
["set <JAIL> setcinfo <ACT> <KEY> <VALUE>", "sets <VALUE> for <KEY> of the action <NAME> for <JAIL>"],
|
["set <JAIL> setcinfo <ACT> <KEY> <VALUE>", "sets <VALUE> for <KEY> of the action <NAME> for <JAIL>"],
|
||||||
["set <JAIL> delcinfo <ACT> <KEY>", "removes <KEY> for the action <NAME> for <JAIL>"],
|
["set <JAIL> delcinfo <ACT> <KEY>", "removes <KEY> for the action <NAME> for <JAIL>"],
|
||||||
["set <JAIL> actionstart <ACT> <CMD>", "sets the start command <CMD> of the action <ACT> for <JAIL>"],
|
["set <JAIL> actionstart <ACT> <CMD>", "sets the start command <CMD> of the action <ACT> for <JAIL>"],
|
||||||
["set <JAIL> actionstop <ACT> <CMD>", "sets the stop command <CMD> of the action <ACT> for <JAIL>"],
|
["set <JAIL> actionstop <ACT> <CMD>", "sets the stop command <CMD> of the action <ACT> for <JAIL>"],
|
||||||
["set <JAIL> actioncheck <ACT> <CMD>", "sets the check command <CMD> of the action <ACT> for <JAIL>"],
|
["set <JAIL> actioncheck <ACT> <CMD>", "sets the check command <CMD> of the action <ACT> for <JAIL>"],
|
||||||
["set <JAIL> actionban <ACT> <CMD>", "sets the ban command <CMD> of the action <ACT> for <JAIL>"],
|
["set <JAIL> actionban <ACT> <CMD>", "sets the ban command <CMD> of the action <ACT> for <JAIL>"],
|
||||||
["set <JAIL> actionunban <ACT> <CMD>", "sets the unban command <CMD> of the action <ACT> for <JAIL>"],
|
["set <JAIL> actionunban <ACT> <CMD>", "sets the unban command <CMD> of the action <ACT> for <JAIL>"],
|
||||||
['', "JAIL INFORMATION", ""],
|
['', "JAIL INFORMATION", ""],
|
||||||
["get <JAIL> ignorecommand", "gets ignorecommand of <JAIL>"],
|
|
||||||
["get <JAIL> logpath", "gets the list of the monitored files for <JAIL>"],
|
["get <JAIL> logpath", "gets the list of the monitored files for <JAIL>"],
|
||||||
["get <JAIL> ignoreip", "gets the list of ignored IP addresses for <JAIL>"],
|
["get <JAIL> ignoreip", "gets the list of ignored IP addresses for <JAIL>"],
|
||||||
["get <JAIL> failregex", "gets the list of regular expressions which matches the failures for <JAIL>"],
|
["get <JAIL> failregex", "gets the list of regular expressions which matches the failures for <JAIL>"],
|
||||||
|
|
|
@ -34,9 +34,6 @@ ignoreip = 127.0.0.1/8
|
||||||
# "bantime" is the number of seconds that a host is banned.
|
# "bantime" is the number of seconds that a host is banned.
|
||||||
bantime = 600
|
bantime = 600
|
||||||
|
|
||||||
# External command with space separated output ips to ignore
|
|
||||||
# ignorecommand = /path/to/command
|
|
||||||
|
|
||||||
# A host is banned if it has generated "maxretry" during the last "findtime"
|
# A host is banned if it has generated "maxretry" during the last "findtime"
|
||||||
# seconds.
|
# seconds.
|
||||||
findtime = 600
|
findtime = 600
|
||||||
|
|
|
@ -21,7 +21,8 @@ __author__ = "Cyril Jaquier and Fail2Ban Contributors"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2013 Yaroslav Halchenko"
|
||||||
__license__ = "GPL"
|
__license__ = "GPL"
|
||||||
|
|
||||||
#import sys, os, getopt
|
import sys
|
||||||
|
|
||||||
from failmanager import FailManagerEmpty
|
from failmanager import FailManagerEmpty
|
||||||
from failmanager import FailManager
|
from failmanager import FailManager
|
||||||
from ticket import FailTicket
|
from ticket import FailTicket
|
||||||
|
@ -42,7 +43,6 @@ logSys = logging.getLogger("fail2ban.filter")
|
||||||
# that matches a given regular expression. This class is instantiated by
|
# that matches a given regular expression. This class is instantiated by
|
||||||
# a Jail object.
|
# a Jail object.
|
||||||
|
|
||||||
|
|
||||||
class Filter(JailThread):
|
class Filter(JailThread):
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -67,13 +67,12 @@ class Filter(JailThread):
|
||||||
self.__findTime = 6000
|
self.__findTime = 6000
|
||||||
## The ignore IP list.
|
## The ignore IP list.
|
||||||
self.__ignoreIpList = []
|
self.__ignoreIpList = []
|
||||||
## External command
|
|
||||||
self.__ignoreCommand = False
|
|
||||||
|
|
||||||
self.dateDetector = DateDetector()
|
self.dateDetector = DateDetector()
|
||||||
self.dateDetector.addDefaultTemplate()
|
self.dateDetector.addDefaultTemplate()
|
||||||
logSys.debug("Created %s" % self)
|
logSys.debug("Created %s" % self)
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "%s(%r)" % (self.__class__.__name__, self.jail)
|
return "%s(%r)" % (self.__class__.__name__, self.jail)
|
||||||
|
|
||||||
|
@ -92,6 +91,7 @@ class Filter(JailThread):
|
||||||
logSys.error(e)
|
logSys.error(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
def delFailRegex(self, index):
|
def delFailRegex(self, index):
|
||||||
try:
|
try:
|
||||||
del self.__failRegex[index]
|
del self.__failRegex[index]
|
||||||
|
@ -123,7 +123,7 @@ class Filter(JailThread):
|
||||||
self.__ignoreRegex.append(regex)
|
self.__ignoreRegex.append(regex)
|
||||||
except RegexException, e:
|
except RegexException, e:
|
||||||
logSys.error(e)
|
logSys.error(e)
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def delIgnoreRegex(self, index):
|
def delIgnoreRegex(self, index):
|
||||||
try:
|
try:
|
||||||
|
@ -209,24 +209,9 @@ class Filter(JailThread):
|
||||||
# file has been modified and looks for failures.
|
# file has been modified and looks for failures.
|
||||||
# @return True when the thread exits nicely
|
# @return True when the thread exits nicely
|
||||||
|
|
||||||
def run(self): # pragma: no cover
|
def run(self): # pragma: no cover
|
||||||
raise Exception("run() is abstract")
|
raise Exception("run() is abstract")
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Set external command, for ignoredips
|
|
||||||
#
|
|
||||||
|
|
||||||
def setIgnoreCommand(self, command):
|
|
||||||
self.__ignoreCommand = command
|
|
||||||
|
|
||||||
##
|
|
||||||
# Get external command, for ignoredips
|
|
||||||
#
|
|
||||||
|
|
||||||
def getIgnoreCommand(self):
|
|
||||||
return self.__ignoreCommand
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Ban an IP - http://blogs.buanzo.com.ar/2009/04/fail2ban-patch-ban-ip-address-manually.html
|
# Ban an IP - http://blogs.buanzo.com.ar/2009/04/fail2ban-patch-ban-ip-address-manually.html
|
||||||
# Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
|
# Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
|
||||||
|
@ -239,7 +224,7 @@ class Filter(JailThread):
|
||||||
self.failManager.addFailure(FailTicket(ip, unixTime))
|
self.failManager.addFailure(FailTicket(ip, unixTime))
|
||||||
|
|
||||||
# Perform the banning of the IP now.
|
# Perform the banning of the IP now.
|
||||||
try: # pragma: no branch - exception is the only way out
|
try: # pragma: no branch - exception is the only way out
|
||||||
while True:
|
while True:
|
||||||
ticket = self.failManager.toBan()
|
ticket = self.failManager.toBan()
|
||||||
self.jail.putFailTicket(ticket)
|
self.jail.putFailTicket(ticket)
|
||||||
|
@ -264,10 +249,7 @@ class Filter(JailThread):
|
||||||
self.__ignoreIpList.remove(ip)
|
self.__ignoreIpList.remove(ip)
|
||||||
|
|
||||||
def getIgnoreIP(self):
|
def getIgnoreIP(self):
|
||||||
if self.__ignoreCommand is not False:
|
return self.__ignoreIpList
|
||||||
return self.__ignoreIpList + os.popen(self.__ignoreCommand).read().split(" ")
|
|
||||||
else:
|
|
||||||
return self.__ignoreIpList
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Check if IP address/DNS is in the ignore list.
|
# Check if IP address/DNS is in the ignore list.
|
||||||
|
@ -282,12 +264,6 @@ class Filter(JailThread):
|
||||||
# An empty string is always false
|
# An empty string is always false
|
||||||
if i == "":
|
if i == "":
|
||||||
continue
|
continue
|
||||||
# External command with ips to ignore
|
|
||||||
if self.__ignoreCommand is not False:
|
|
||||||
ignored_ips = os.popen(self.__ignoreCommand).read().split(" ")
|
|
||||||
if ip in ignored_ips:
|
|
||||||
return True
|
|
||||||
|
|
||||||
s = i.split('/', 1)
|
s = i.split('/', 1)
|
||||||
# IP address without CIDR mask
|
# IP address without CIDR mask
|
||||||
if len(s) == 1:
|
if len(s) == 1:
|
||||||
|
|
158
server/server.py
158
server/server.py
|
@ -18,7 +18,7 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
# Author: Cyril Jaquier
|
# Author: Cyril Jaquier
|
||||||
#
|
#
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier"
|
__author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
|
@ -36,7 +36,7 @@ import logging, logging.handlers, sys, os, signal
|
||||||
logSys = logging.getLogger("fail2ban.server")
|
logSys = logging.getLogger("fail2ban.server")
|
||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
|
|
||||||
def __init__(self, daemon = False):
|
def __init__(self, daemon = False):
|
||||||
self.__loggingLock = Lock()
|
self.__loggingLock = Lock()
|
||||||
self.__lock = RLock()
|
self.__lock = RLock()
|
||||||
|
@ -49,18 +49,18 @@ class Server:
|
||||||
# Set logging level
|
# Set logging level
|
||||||
self.setLogLevel(3)
|
self.setLogLevel(3)
|
||||||
self.setLogTarget("STDOUT")
|
self.setLogTarget("STDOUT")
|
||||||
|
|
||||||
def __sigTERMhandler(self, signum, frame):
|
def __sigTERMhandler(self, signum, frame):
|
||||||
logSys.debug("Caught signal %d. Exiting" % signum)
|
logSys.debug("Caught signal %d. Exiting" % signum)
|
||||||
self.quit()
|
self.quit()
|
||||||
|
|
||||||
def start(self, sock, pidfile, force = False):
|
def start(self, sock, pidfile, force = False):
|
||||||
logSys.info("Starting Fail2ban v" + version.version)
|
logSys.info("Starting Fail2ban v" + version.version)
|
||||||
|
|
||||||
# Install signal handlers
|
# Install signal handlers
|
||||||
signal.signal(signal.SIGTERM, self.__sigTERMhandler)
|
signal.signal(signal.SIGTERM, self.__sigTERMhandler)
|
||||||
signal.signal(signal.SIGINT, self.__sigTERMhandler)
|
signal.signal(signal.SIGINT, self.__sigTERMhandler)
|
||||||
|
|
||||||
# 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)
|
||||||
if self.__daemon: # pragma: no cover
|
if self.__daemon: # pragma: no cover
|
||||||
|
@ -71,7 +71,7 @@ class Server:
|
||||||
else:
|
else:
|
||||||
logSys.error("Could not create daemon")
|
logSys.error("Could not create daemon")
|
||||||
raise ServerInitializationError("Could not create daemon")
|
raise ServerInitializationError("Could not create daemon")
|
||||||
|
|
||||||
# Creates a PID file.
|
# Creates a PID file.
|
||||||
try:
|
try:
|
||||||
logSys.debug("Creating PID file %s" % pidfile)
|
logSys.debug("Creating PID file %s" % pidfile)
|
||||||
|
@ -80,7 +80,7 @@ class Server:
|
||||||
pidFile.close()
|
pidFile.close()
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
logSys.error("Unable to create PID file: %s" % e)
|
logSys.error("Unable to create PID file: %s" % e)
|
||||||
|
|
||||||
# Start the communication
|
# Start the communication
|
||||||
logSys.debug("Starting communication")
|
logSys.debug("Starting communication")
|
||||||
try:
|
try:
|
||||||
|
@ -94,7 +94,7 @@ class Server:
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
logSys.error("Unable to remove PID file: %s" % e)
|
logSys.error("Unable to remove PID file: %s" % e)
|
||||||
logSys.info("Exiting Fail2ban")
|
logSys.info("Exiting Fail2ban")
|
||||||
|
|
||||||
def quit(self):
|
def quit(self):
|
||||||
# Stop communication first because if jail's unban action
|
# Stop communication first because if jail's unban action
|
||||||
# tries to communicate via fail2ban-client we get a lockup
|
# tries to communicate via fail2ban-client we get a lockup
|
||||||
|
@ -114,13 +114,13 @@ class Server:
|
||||||
finally:
|
finally:
|
||||||
self.__loggingLock.release()
|
self.__loggingLock.release()
|
||||||
|
|
||||||
|
|
||||||
def addJail(self, name, backend):
|
def addJail(self, name, backend):
|
||||||
self.__jails.add(name, backend)
|
self.__jails.add(name, backend)
|
||||||
|
|
||||||
def delJail(self, name):
|
def delJail(self, name):
|
||||||
self.__jails.remove(name)
|
self.__jails.remove(name)
|
||||||
|
|
||||||
def startJail(self, name):
|
def startJail(self, name):
|
||||||
try:
|
try:
|
||||||
self.__lock.acquire()
|
self.__lock.acquire()
|
||||||
|
@ -128,7 +128,7 @@ class Server:
|
||||||
self.__jails.get(name).start()
|
self.__jails.get(name).start()
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
def stopJail(self, name):
|
def stopJail(self, name):
|
||||||
logSys.debug("Stopping jail %s" % name)
|
logSys.debug("Stopping jail %s" % name)
|
||||||
try:
|
try:
|
||||||
|
@ -138,7 +138,7 @@ class Server:
|
||||||
self.delJail(name)
|
self.delJail(name)
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
def stopAllJail(self):
|
def stopAllJail(self):
|
||||||
logSys.info("Stopping all jails")
|
logSys.info("Stopping all jails")
|
||||||
try:
|
try:
|
||||||
|
@ -147,140 +147,134 @@ class Server:
|
||||||
self.stopJail(jail)
|
self.stopJail(jail)
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
def isAlive(self, name):
|
def isAlive(self, name):
|
||||||
return self.__jails.get(name).isAlive()
|
return self.__jails.get(name).isAlive()
|
||||||
|
|
||||||
def setIdleJail(self, name, value):
|
def setIdleJail(self, name, value):
|
||||||
self.__jails.get(name).setIdle(value)
|
self.__jails.get(name).setIdle(value)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getIdleJail(self, name):
|
def getIdleJail(self, name):
|
||||||
return self.__jails.get(name).getIdle()
|
return self.__jails.get(name).getIdle()
|
||||||
|
|
||||||
# Filter
|
# Filter
|
||||||
def addIgnoreIP(self, name, ip):
|
def addIgnoreIP(self, name, ip):
|
||||||
self.__jails.getFilter(name).addIgnoreIP(ip)
|
self.__jails.getFilter(name).addIgnoreIP(ip)
|
||||||
|
|
||||||
def delIgnoreIP(self, name, ip):
|
def delIgnoreIP(self, name, ip):
|
||||||
self.__jails.getFilter(name).delIgnoreIP(ip)
|
self.__jails.getFilter(name).delIgnoreIP(ip)
|
||||||
|
|
||||||
def getIgnoreIP(self, name):
|
def getIgnoreIP(self, name):
|
||||||
return self.__jails.getFilter(name).getIgnoreIP()
|
return self.__jails.getFilter(name).getIgnoreIP()
|
||||||
|
|
||||||
def addLogPath(self, name, fileName):
|
def addLogPath(self, name, fileName):
|
||||||
self.__jails.getFilter(name).addLogPath(fileName)
|
self.__jails.getFilter(name).addLogPath(fileName)
|
||||||
|
|
||||||
def delLogPath(self, name, fileName):
|
def delLogPath(self, name, fileName):
|
||||||
self.__jails.getFilter(name).delLogPath(fileName)
|
self.__jails.getFilter(name).delLogPath(fileName)
|
||||||
|
|
||||||
def getLogPath(self, name):
|
def getLogPath(self, name):
|
||||||
return [m.getFileName()
|
return [m.getFileName()
|
||||||
for m in self.__jails.getFilter(name).getLogPath()]
|
for m in self.__jails.getFilter(name).getLogPath()]
|
||||||
|
|
||||||
def setFindTime(self, name, value):
|
def setFindTime(self, name, value):
|
||||||
self.__jails.getFilter(name).setFindTime(value)
|
self.__jails.getFilter(name).setFindTime(value)
|
||||||
|
|
||||||
def getFindTime(self, name):
|
def getFindTime(self, name):
|
||||||
return self.__jails.getFilter(name).getFindTime()
|
return self.__jails.getFilter(name).getFindTime()
|
||||||
|
|
||||||
def addFailRegex(self, name, value):
|
def addFailRegex(self, name, value):
|
||||||
self.__jails.getFilter(name).addFailRegex(value)
|
self.__jails.getFilter(name).addFailRegex(value)
|
||||||
|
|
||||||
def setIgnoreCommand(self, name, value):
|
|
||||||
self.__jails.getFilter(name).setIgnoreCommand(value)
|
|
||||||
def getIgnoreCommand(self, name):
|
|
||||||
self.__jails.getFilter(name).getIgnoreCommand()
|
|
||||||
|
|
||||||
|
|
||||||
def delFailRegex(self, name, index):
|
def delFailRegex(self, name, index):
|
||||||
self.__jails.getFilter(name).delFailRegex(index)
|
self.__jails.getFilter(name).delFailRegex(index)
|
||||||
|
|
||||||
def getFailRegex(self, name):
|
def getFailRegex(self, name):
|
||||||
return self.__jails.getFilter(name).getFailRegex()
|
return self.__jails.getFilter(name).getFailRegex()
|
||||||
|
|
||||||
def addIgnoreRegex(self, name, value):
|
def addIgnoreRegex(self, name, value):
|
||||||
self.__jails.getFilter(name).addIgnoreRegex(value)
|
self.__jails.getFilter(name).addIgnoreRegex(value)
|
||||||
|
|
||||||
def delIgnoreRegex(self, name, index):
|
def delIgnoreRegex(self, name, index):
|
||||||
self.__jails.getFilter(name).delIgnoreRegex(index)
|
self.__jails.getFilter(name).delIgnoreRegex(index)
|
||||||
|
|
||||||
def getIgnoreRegex(self, name):
|
def getIgnoreRegex(self, name):
|
||||||
return self.__jails.getFilter(name).getIgnoreRegex()
|
return self.__jails.getFilter(name).getIgnoreRegex()
|
||||||
|
|
||||||
def setUseDns(self, name, value):
|
def setUseDns(self, name, value):
|
||||||
self.__jails.getFilter(name).setUseDns(value)
|
self.__jails.getFilter(name).setUseDns(value)
|
||||||
|
|
||||||
def getUseDns(self, name):
|
def getUseDns(self, name):
|
||||||
return self.__jails.getFilter(name).getUseDns()
|
return self.__jails.getFilter(name).getUseDns()
|
||||||
|
|
||||||
def setMaxRetry(self, name, value):
|
def setMaxRetry(self, name, value):
|
||||||
self.__jails.getFilter(name).setMaxRetry(value)
|
self.__jails.getFilter(name).setMaxRetry(value)
|
||||||
|
|
||||||
def getMaxRetry(self, name):
|
def getMaxRetry(self, name):
|
||||||
return self.__jails.getFilter(name).getMaxRetry()
|
return self.__jails.getFilter(name).getMaxRetry()
|
||||||
|
|
||||||
# Action
|
# Action
|
||||||
def addAction(self, name, value):
|
def addAction(self, name, value):
|
||||||
self.__jails.getAction(name).addAction(value)
|
self.__jails.getAction(name).addAction(value)
|
||||||
|
|
||||||
def getLastAction(self, name):
|
def getLastAction(self, name):
|
||||||
return self.__jails.getAction(name).getLastAction()
|
return self.__jails.getAction(name).getLastAction()
|
||||||
|
|
||||||
def delAction(self, name, value):
|
def delAction(self, name, value):
|
||||||
self.__jails.getAction(name).delAction(value)
|
self.__jails.getAction(name).delAction(value)
|
||||||
|
|
||||||
def setCInfo(self, name, action, key, value):
|
def setCInfo(self, name, action, key, value):
|
||||||
self.__jails.getAction(name).getAction(action).setCInfo(key, value)
|
self.__jails.getAction(name).getAction(action).setCInfo(key, value)
|
||||||
|
|
||||||
def getCInfo(self, name, action, key):
|
def getCInfo(self, name, action, key):
|
||||||
return self.__jails.getAction(name).getAction(action).getCInfo(key)
|
return self.__jails.getAction(name).getAction(action).getCInfo(key)
|
||||||
|
|
||||||
def delCInfo(self, name, action, key):
|
def delCInfo(self, name, action, key):
|
||||||
self.__jails.getAction(name).getAction(action).delCInfo(key)
|
self.__jails.getAction(name).getAction(action).delCInfo(key)
|
||||||
|
|
||||||
def setBanTime(self, name, value):
|
def setBanTime(self, name, value):
|
||||||
self.__jails.getAction(name).setBanTime(value)
|
self.__jails.getAction(name).setBanTime(value)
|
||||||
|
|
||||||
def setBanIP(self, name, value):
|
def setBanIP(self, name, value):
|
||||||
return self.__jails.getFilter(name).addBannedIP(value)
|
return self.__jails.getFilter(name).addBannedIP(value)
|
||||||
|
|
||||||
def setUnbanIP(self, name, value):
|
def setUnbanIP(self, name, value):
|
||||||
return self.__jails.getAction(name).removeBannedIP(value)
|
return self.__jails.getAction(name).removeBannedIP(value)
|
||||||
|
|
||||||
def getBanTime(self, name):
|
def getBanTime(self, name):
|
||||||
return self.__jails.getAction(name).getBanTime()
|
return self.__jails.getAction(name).getBanTime()
|
||||||
|
|
||||||
def setActionStart(self, name, action, value):
|
def setActionStart(self, name, action, value):
|
||||||
self.__jails.getAction(name).getAction(action).setActionStart(value)
|
self.__jails.getAction(name).getAction(action).setActionStart(value)
|
||||||
|
|
||||||
def getActionStart(self, name, action):
|
def getActionStart(self, name, action):
|
||||||
return self.__jails.getAction(name).getAction(action).getActionStart()
|
return self.__jails.getAction(name).getAction(action).getActionStart()
|
||||||
|
|
||||||
def setActionStop(self, name, action, value):
|
def setActionStop(self, name, action, value):
|
||||||
self.__jails.getAction(name).getAction(action).setActionStop(value)
|
self.__jails.getAction(name).getAction(action).setActionStop(value)
|
||||||
|
|
||||||
def getActionStop(self, name, action):
|
def getActionStop(self, name, action):
|
||||||
return self.__jails.getAction(name).getAction(action).getActionStop()
|
return self.__jails.getAction(name).getAction(action).getActionStop()
|
||||||
|
|
||||||
def setActionCheck(self, name, action, value):
|
def setActionCheck(self, name, action, value):
|
||||||
self.__jails.getAction(name).getAction(action).setActionCheck(value)
|
self.__jails.getAction(name).getAction(action).setActionCheck(value)
|
||||||
|
|
||||||
def getActionCheck(self, name, action):
|
def getActionCheck(self, name, action):
|
||||||
return self.__jails.getAction(name).getAction(action).getActionCheck()
|
return self.__jails.getAction(name).getAction(action).getActionCheck()
|
||||||
|
|
||||||
def setActionBan(self, name, action, value):
|
def setActionBan(self, name, action, value):
|
||||||
self.__jails.getAction(name).getAction(action).setActionBan(value)
|
self.__jails.getAction(name).getAction(action).setActionBan(value)
|
||||||
|
|
||||||
def getActionBan(self, name, action):
|
def getActionBan(self, name, action):
|
||||||
return self.__jails.getAction(name).getAction(action).getActionBan()
|
return self.__jails.getAction(name).getAction(action).getActionBan()
|
||||||
|
|
||||||
def setActionUnban(self, name, action, value):
|
def setActionUnban(self, name, action, value):
|
||||||
self.__jails.getAction(name).getAction(action).setActionUnban(value)
|
self.__jails.getAction(name).getAction(action).setActionUnban(value)
|
||||||
|
|
||||||
def getActionUnban(self, name, action):
|
def getActionUnban(self, name, action):
|
||||||
return self.__jails.getAction(name).getAction(action).getActionUnban()
|
return self.__jails.getAction(name).getAction(action).getActionUnban()
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
def status(self):
|
def status(self):
|
||||||
try:
|
try:
|
||||||
|
@ -291,17 +285,17 @@ class Server:
|
||||||
length = len(jailList)
|
length = len(jailList)
|
||||||
if not length == 0:
|
if not length == 0:
|
||||||
jailList = jailList[:length-2]
|
jailList = jailList[:length-2]
|
||||||
ret = [("Number of jail", self.__jails.size()),
|
ret = [("Number of jail", self.__jails.size()),
|
||||||
("Jail list", jailList)]
|
("Jail list", jailList)]
|
||||||
return ret
|
return ret
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
def statusJail(self, name):
|
def statusJail(self, name):
|
||||||
return self.__jails.get(name).getStatus()
|
return self.__jails.get(name).getStatus()
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
|
|
||||||
##
|
##
|
||||||
# Set the logging level.
|
# Set the logging level.
|
||||||
#
|
#
|
||||||
|
@ -312,7 +306,7 @@ class Server:
|
||||||
# 3 = INFO
|
# 3 = INFO
|
||||||
# 4 = DEBUG
|
# 4 = DEBUG
|
||||||
# @param value the level
|
# @param value the level
|
||||||
|
|
||||||
def setLogLevel(self, value):
|
def setLogLevel(self, value):
|
||||||
try:
|
try:
|
||||||
self.__loggingLock.acquire()
|
self.__loggingLock.acquire()
|
||||||
|
@ -329,26 +323,26 @@ class Server:
|
||||||
logging.getLogger("fail2ban").setLevel(logLevel)
|
logging.getLogger("fail2ban").setLevel(logLevel)
|
||||||
finally:
|
finally:
|
||||||
self.__loggingLock.release()
|
self.__loggingLock.release()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get the logging level.
|
# Get the logging level.
|
||||||
#
|
#
|
||||||
# @see setLogLevel
|
# @see setLogLevel
|
||||||
# @return the log level
|
# @return the log level
|
||||||
|
|
||||||
def getLogLevel(self):
|
def getLogLevel(self):
|
||||||
try:
|
try:
|
||||||
self.__loggingLock.acquire()
|
self.__loggingLock.acquire()
|
||||||
return self.__logLevel
|
return self.__logLevel
|
||||||
finally:
|
finally:
|
||||||
self.__loggingLock.release()
|
self.__loggingLock.release()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Sets the logging target.
|
# Sets the logging target.
|
||||||
#
|
#
|
||||||
# target can be a file, SYSLOG, STDOUT or STDERR.
|
# target can be a file, SYSLOG, STDOUT or STDERR.
|
||||||
# @param target the logging target
|
# @param target the logging target
|
||||||
|
|
||||||
def setLogTarget(self, target):
|
def setLogTarget(self, target):
|
||||||
try:
|
try:
|
||||||
self.__loggingLock.acquire()
|
self.__loggingLock.acquire()
|
||||||
|
@ -358,7 +352,7 @@ class Server:
|
||||||
# Syslog daemons already add date to the message.
|
# Syslog daemons already add date to the message.
|
||||||
formatter = logging.Formatter("%(name)-16s: %(levelname)-6s %(message)s")
|
formatter = logging.Formatter("%(name)-16s: %(levelname)-6s %(message)s")
|
||||||
facility = logging.handlers.SysLogHandler.LOG_DAEMON
|
facility = logging.handlers.SysLogHandler.LOG_DAEMON
|
||||||
hdlr = logging.handlers.SysLogHandler("/dev/log",
|
hdlr = logging.handlers.SysLogHandler("/dev/log",
|
||||||
facility = facility)
|
facility = facility)
|
||||||
elif target == "STDOUT":
|
elif target == "STDOUT":
|
||||||
hdlr = logging.StreamHandler(sys.stdout)
|
hdlr = logging.StreamHandler(sys.stdout)
|
||||||
|
@ -400,21 +394,21 @@ class Server:
|
||||||
return True
|
return True
|
||||||
finally:
|
finally:
|
||||||
self.__loggingLock.release()
|
self.__loggingLock.release()
|
||||||
|
|
||||||
def getLogTarget(self):
|
def getLogTarget(self):
|
||||||
try:
|
try:
|
||||||
self.__loggingLock.acquire()
|
self.__loggingLock.acquire()
|
||||||
return self.__logTarget
|
return self.__logTarget
|
||||||
finally:
|
finally:
|
||||||
self.__loggingLock.release()
|
self.__loggingLock.release()
|
||||||
|
|
||||||
def __createDaemon(self): # pragma: no cover
|
def __createDaemon(self): # pragma: no cover
|
||||||
""" Detach a process from the controlling terminal and run it in the
|
""" Detach a process from the controlling terminal and run it in the
|
||||||
background as a daemon.
|
background as a daemon.
|
||||||
|
|
||||||
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731
|
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/278731
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Fork a child process so the parent can exit. This will return control
|
# Fork a child process so the parent can exit. This will return control
|
||||||
# to the command line or shell. This is required so that the new process
|
# to the command line or shell. This is required so that the new process
|
||||||
|
@ -425,9 +419,9 @@ class Server:
|
||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
return((e.errno, e.strerror)) # ERROR (return a tuple)
|
return((e.errno, e.strerror)) # ERROR (return a tuple)
|
||||||
|
|
||||||
if pid == 0: # The first child.
|
if pid == 0: # The first child.
|
||||||
|
|
||||||
# Next we call os.setsid() to become the session leader of this new
|
# Next we call os.setsid() to become the session leader of this new
|
||||||
# session. The process also becomes the process group leader of the
|
# session. The process also becomes the process group leader of the
|
||||||
# new process group. Since a controlling terminal is associated with a
|
# new process group. Since a controlling terminal is associated with a
|
||||||
|
@ -436,11 +430,11 @@ class Server:
|
||||||
# fail, since we're guaranteed that the child is not a process group
|
# fail, since we're guaranteed that the child is not a process group
|
||||||
# leader.
|
# leader.
|
||||||
os.setsid()
|
os.setsid()
|
||||||
|
|
||||||
# When the first child terminates, all processes in the second child
|
# When the first child terminates, all processes in the second child
|
||||||
# are sent a SIGHUP, so it's ignored.
|
# are sent a SIGHUP, so it's ignored.
|
||||||
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Fork a second child to prevent zombies. Since the first child is
|
# Fork a second child to prevent zombies. Since the first child is
|
||||||
# a session leader without a controlling terminal, it's possible for
|
# a session leader without a controlling terminal, it's possible for
|
||||||
|
@ -450,7 +444,7 @@ class Server:
|
||||||
pid = os.fork() # Fork a second child.
|
pid = os.fork() # Fork a second child.
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
return((e.errno, e.strerror)) # ERROR (return a tuple)
|
return((e.errno, e.strerror)) # ERROR (return a tuple)
|
||||||
|
|
||||||
if (pid == 0): # The second child.
|
if (pid == 0): # The second child.
|
||||||
# Ensure that the daemon doesn't keep any directory in use. Failure
|
# Ensure that the daemon doesn't keep any directory in use. Failure
|
||||||
# to do this could make a filesystem unmountable.
|
# to do this could make a filesystem unmountable.
|
||||||
|
@ -459,7 +453,7 @@ class Server:
|
||||||
os._exit(0) # Exit parent (the first child) of the second child.
|
os._exit(0) # Exit parent (the first child) of the second child.
|
||||||
else:
|
else:
|
||||||
os._exit(0) # Exit parent of the first child.
|
os._exit(0) # Exit parent of the first child.
|
||||||
|
|
||||||
# Close all open files. Try the system configuration variable, SC_OPEN_MAX,
|
# Close all open files. Try the system configuration variable, SC_OPEN_MAX,
|
||||||
# for the maximum number of open files to close. If it doesn't exist, use
|
# for the maximum number of open files to close. If it doesn't exist, use
|
||||||
# the default value (configurable).
|
# the default value (configurable).
|
||||||
|
@ -467,13 +461,13 @@ class Server:
|
||||||
maxfd = os.sysconf("SC_OPEN_MAX")
|
maxfd = os.sysconf("SC_OPEN_MAX")
|
||||||
except (AttributeError, ValueError):
|
except (AttributeError, ValueError):
|
||||||
maxfd = 256 # default maximum
|
maxfd = 256 # default maximum
|
||||||
|
|
||||||
for fd in range(0, maxfd):
|
for fd in range(0, maxfd):
|
||||||
try:
|
try:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
except OSError: # ERROR (ignore)
|
except OSError: # ERROR (ignore)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Redirect the standard file descriptors to /dev/null.
|
# Redirect the standard file descriptors to /dev/null.
|
||||||
os.open("/dev/null", os.O_RDONLY) # standard input (0)
|
os.open("/dev/null", os.O_RDONLY) # standard input (0)
|
||||||
os.open("/dev/null", os.O_RDWR) # standard output (1)
|
os.open("/dev/null", os.O_RDWR) # standard output (1)
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
# Author: Cyril Jaquier
|
# Author: Cyril Jaquier
|
||||||
#
|
#
|
||||||
|
|
||||||
__author__ = "Cyril Jaquier"
|
__author__ = "Cyril Jaquier"
|
||||||
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
|
||||||
|
@ -30,21 +30,21 @@ import logging, time
|
||||||
logSys = logging.getLogger("fail2ban.comm")
|
logSys = logging.getLogger("fail2ban.comm")
|
||||||
|
|
||||||
class Transmitter:
|
class Transmitter:
|
||||||
|
|
||||||
##
|
##
|
||||||
# Constructor.
|
# Constructor.
|
||||||
#
|
#
|
||||||
# @param The server reference
|
# @param The server reference
|
||||||
|
|
||||||
def __init__(self, server):
|
def __init__(self, server):
|
||||||
self.__server = server
|
self.__server = server
|
||||||
|
|
||||||
##
|
##
|
||||||
# Proceeds a command.
|
# Proceeds a command.
|
||||||
#
|
#
|
||||||
# Proceeds an incoming command.
|
# Proceeds an incoming command.
|
||||||
# @param command The incoming command
|
# @param command The incoming command
|
||||||
|
|
||||||
def proceed(self, command):
|
def proceed(self, command):
|
||||||
# Deserialize object
|
# Deserialize object
|
||||||
logSys.debug("Command: " + `command`)
|
logSys.debug("Command: " + `command`)
|
||||||
|
@ -56,12 +56,12 @@ class Transmitter:
|
||||||
% (command, e))
|
% (command, e))
|
||||||
ack = 1, e
|
ack = 1, e
|
||||||
return ack
|
return ack
|
||||||
|
|
||||||
##
|
##
|
||||||
# Handle an command.
|
# Handle an command.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
def __commandHandler(self, command):
|
def __commandHandler(self, command):
|
||||||
if command[0] == "ping":
|
if command[0] == "ping":
|
||||||
return "pong"
|
return "pong"
|
||||||
|
@ -97,9 +97,9 @@ class Transmitter:
|
||||||
elif command[0] == "get":
|
elif command[0] == "get":
|
||||||
return self.__commandGet(command[1:])
|
return self.__commandGet(command[1:])
|
||||||
elif command[0] == "status":
|
elif command[0] == "status":
|
||||||
return self.status(command[1:])
|
return self.status(command[1:])
|
||||||
raise Exception("Invalid command")
|
raise Exception("Invalid command")
|
||||||
|
|
||||||
def __commandSet(self, command):
|
def __commandSet(self, command):
|
||||||
name = command[0]
|
name = command[0]
|
||||||
# Logging
|
# Logging
|
||||||
|
@ -152,10 +152,6 @@ class Transmitter:
|
||||||
value = command[2]
|
value = command[2]
|
||||||
self.__server.addIgnoreRegex(name, value)
|
self.__server.addIgnoreRegex(name, value)
|
||||||
return self.__server.getIgnoreRegex(name)
|
return self.__server.getIgnoreRegex(name)
|
||||||
elif command[1] == "ignorecommand":
|
|
||||||
value = command[2]
|
|
||||||
self.__server.setIgnoreCommand(name, value)
|
|
||||||
return self.__server.getIgnoreCommand(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)
|
||||||
|
@ -228,7 +224,7 @@ class Transmitter:
|
||||||
self.__server.setActionUnban(name, act, value)
|
self.__server.setActionUnban(name, act, value)
|
||||||
return self.__server.getActionUnban(name, act)
|
return self.__server.getActionUnban(name, act)
|
||||||
raise Exception("Invalid command (no set action or not yet implemented)")
|
raise Exception("Invalid command (no set action or not yet implemented)")
|
||||||
|
|
||||||
def __commandGet(self, command):
|
def __commandGet(self, command):
|
||||||
name = command[0]
|
name = command[0]
|
||||||
# Logging
|
# Logging
|
||||||
|
@ -241,8 +237,6 @@ class Transmitter:
|
||||||
return self.__server.getLogPath(name)
|
return self.__server.getLogPath(name)
|
||||||
elif command[1] == "ignoreip":
|
elif command[1] == "ignoreip":
|
||||||
return self.__server.getIgnoreIP(name)
|
return self.__server.getIgnoreIP(name)
|
||||||
elif command[1] == "ignorecommand":
|
|
||||||
return self.__server.getIgnoreCommand(name)
|
|
||||||
elif command[1] == "failregex":
|
elif command[1] == "failregex":
|
||||||
return self.__server.getFailRegex(name)
|
return self.__server.getFailRegex(name)
|
||||||
elif command[1] == "ignoreregex":
|
elif command[1] == "ignoreregex":
|
||||||
|
@ -278,7 +272,7 @@ class Transmitter:
|
||||||
key = command[3]
|
key = command[3]
|
||||||
return self.__server.getCInfo(name, act, key)
|
return self.__server.getCInfo(name, act, key)
|
||||||
raise Exception("Invalid command (no get action or not yet implemented)")
|
raise Exception("Invalid command (no get action or not yet implemented)")
|
||||||
|
|
||||||
def status(self, command):
|
def status(self, command):
|
||||||
if len(command) == 0:
|
if len(command) == 0:
|
||||||
return self.__server.status()
|
return self.__server.status()
|
||||||
|
@ -286,4 +280,4 @@ class Transmitter:
|
||||||
name = command[0]
|
name = command[0]
|
||||||
return self.__server.statusJail(name)
|
return self.__server.statusJail(name)
|
||||||
raise Exception("Invalid command (no status)")
|
raise Exception("Invalid command (no status)")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue