mirror of https://github.com/fail2ban/fail2ban
- Fixed fail2ban-regex. It support "includes" in configuration files.
- Modified "includes" to be more generic. We will probably support URL in the future. - Small refactoring. git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/branches/FAIL2BAN-0_8@656 a942ae1a-1317-0410-a47c-b1dcaea8d605_tent/ipv6_via_aInfo
parent
6779814d91
commit
174ce7027a
|
@ -15,6 +15,7 @@
|
|||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
# Author: Yaroslav Halchenko
|
||||
# Modified: Cyril Jaquier
|
||||
# $Revision$
|
||||
|
||||
__author__ = 'Yaroslav Halhenko'
|
||||
|
@ -23,8 +24,11 @@ __date__ = '$Date: $'
|
|||
__copyright__ = 'Copyright (c) 2007 Yaroslav Halchenko'
|
||||
__license__ = 'GPL'
|
||||
|
||||
import logging, os
|
||||
from ConfigParser import SafeConfigParser
|
||||
from ConfigParser import NoOptionError, NoSectionError
|
||||
|
||||
# Gets the instance of the logger.
|
||||
logSys = logging.getLogger("fail2ban.client.config")
|
||||
|
||||
class SafeConfigParserWithIncludes(SafeConfigParser):
|
||||
"""
|
||||
|
@ -38,10 +42,10 @@ class SafeConfigParserWithIncludes(SafeConfigParser):
|
|||
Example:
|
||||
|
||||
[INCLUDES]
|
||||
files_before = 1.conf
|
||||
before = 1.conf
|
||||
3.conf
|
||||
|
||||
files_after = 1.conf
|
||||
after = 1.conf
|
||||
|
||||
It is a simple implementation, so just basic care is taken about
|
||||
recursion. Includes preserve right order, ie new files are
|
||||
|
@ -55,35 +59,42 @@ files_after = 1.conf
|
|||
|
||||
"""
|
||||
|
||||
SECTION_NAME = "INCLUDES"
|
||||
|
||||
#@staticmethod
|
||||
def getIncludedFiles(filename, sectionName='INCLUDES',
|
||||
defaults={}, seen=[]):
|
||||
def getIncludes(resource, seen = []):
|
||||
"""
|
||||
Given 1 config filename returns list of included files
|
||||
Given 1 config resource returns list of included files
|
||||
(recursively) with the original one as well
|
||||
Simple loops are taken care about
|
||||
"""
|
||||
filenames = []
|
||||
#print "Opening file " + filename
|
||||
d = defaults.copy() # so that we do not poison our defaults
|
||||
parser = SafeConfigParser(defaults = d)
|
||||
parser.read(filename)
|
||||
newFiles = [ ('files_before', []), ('files_after', []) ]
|
||||
if sectionName in parser.sections():
|
||||
|
||||
# Use a short class name ;)
|
||||
SCPWI = SafeConfigParserWithIncludes
|
||||
|
||||
parser = SafeConfigParser()
|
||||
parser.read(resource)
|
||||
|
||||
resourceDir = os.path.dirname(resource)
|
||||
|
||||
newFiles = [ ('before', []), ('after', []) ]
|
||||
if SCPWI.SECTION_NAME in parser.sections():
|
||||
for option_name, option_list in newFiles:
|
||||
if option_name in parser.options(sectionName):
|
||||
newFileNames = parser.get(sectionName, option_name)
|
||||
for newFileName in newFileNames.split('\n'):
|
||||
if newFileName in seen: continue
|
||||
option_list += SafeConfigParserWithIncludes.\
|
||||
getIncludedFiles(newFileName,
|
||||
defaults=defaults,
|
||||
seen=seen + [filename])
|
||||
if option_name in parser.options(SCPWI.SECTION_NAME):
|
||||
newResources = parser.get(SCPWI.SECTION_NAME, option_name)
|
||||
for newResource in newResources.split('\n'):
|
||||
if os.path.isabs(newResource):
|
||||
r = newResource
|
||||
else:
|
||||
r = "%s/%s" % (resourceDir, newResource)
|
||||
if r in seen:
|
||||
continue
|
||||
s = seen + [resource]
|
||||
option_list += SCPWI.getIncludes(r, s)
|
||||
# combine lists
|
||||
filenames = newFiles[0][1] + [filename] + newFiles[1][1]
|
||||
#print "Includes list for " + filename + " is " + `filenames`
|
||||
return filenames
|
||||
getIncludedFiles = staticmethod(getIncludedFiles)
|
||||
return newFiles[0][1] + [resource] + newFiles[1][1]
|
||||
#print "Includes list for " + resource + " is " + `resources`
|
||||
getIncludes = staticmethod(getIncludes)
|
||||
|
||||
|
||||
def read(self, filenames):
|
||||
|
@ -91,8 +102,7 @@ files_after = 1.conf
|
|||
if not isinstance(filenames, list):
|
||||
filenames = [ filenames ]
|
||||
for filename in filenames:
|
||||
fileNamesFull += SafeConfigParserWithIncludes.\
|
||||
getIncludedFiles(filename, defaults=self._defaults)
|
||||
#print "Opening config files " + `fileNamesFull`
|
||||
fileNamesFull += SafeConfigParserWithIncludes.getIncludes(filename)
|
||||
logSys.debug("Reading files: %s" % fileNamesFull)
|
||||
return SafeConfigParser.read(self, fileNamesFull)
|
||||
|
||||
|
|
|
@ -36,9 +36,7 @@ class ConfigReader(SafeConfigParserWithIncludes):
|
|||
BASE_DIRECTORY = "/etc/fail2ban/"
|
||||
|
||||
def __init__(self):
|
||||
SafeConfigParserWithIncludes.__init__(self,
|
||||
{'configpath' : \
|
||||
ConfigReader.BASE_DIRECTORY} )
|
||||
SafeConfigParserWithIncludes.__init__(self)
|
||||
self.__opts = None
|
||||
|
||||
#@staticmethod
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[INCLUDES]
|
||||
|
||||
# Load customizations if any available
|
||||
files_after = %(configpath)s/filter.d/common.local
|
||||
after = common.local
|
||||
|
||||
|
||||
[DEFAULT]
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
# Read common prefixes. If any customizations available -- read them from
|
||||
# common.local
|
||||
files_before = %(configpath)s/filter.d/common.conf
|
||||
before = common.conf
|
||||
|
||||
|
||||
[Definition]
|
||||
|
|
|
@ -222,7 +222,7 @@ class Fail2banRegex:
|
|||
try:
|
||||
self.__filter.addFailRegex(regex.getFailRegex())
|
||||
try:
|
||||
ret = self.__filter.findFailure(line)
|
||||
ret = self.__filter.processLine(line)
|
||||
if not len(ret) == 0:
|
||||
if found == True:
|
||||
ret[0].append(True)
|
||||
|
|
|
@ -235,9 +235,6 @@ class Filter(JailThread):
|
|||
|
||||
|
||||
def processLine(self, line):
|
||||
if not self._isActive():
|
||||
# The jail has been stopped
|
||||
return
|
||||
try:
|
||||
# Decode line to UTF-8
|
||||
l = line.decode('utf-8')
|
||||
|
@ -246,25 +243,27 @@ class Filter(JailThread):
|
|||
timeMatch = self.dateDetector.matchTime(l)
|
||||
if not timeMatch:
|
||||
# There is no valid time in this line
|
||||
return
|
||||
return []
|
||||
# Lets split into time part and log part of the line
|
||||
timeLine = timeMatch.group()
|
||||
# Lets leave the beginning in as well, so if there is no
|
||||
# anchore at the beginning of the time regexp, we don't
|
||||
# at least allow injection. Should be harmless otherwise
|
||||
logLine = l[:timeMatch.start()] + l[timeMatch.end():]
|
||||
for element in self.findFailure(timeLine, logLine):
|
||||
return self.findFailure(timeLine, logLine)
|
||||
|
||||
def processLineAndAdd(self, line):
|
||||
for element in self.processLine(line):
|
||||
ip = element[0]
|
||||
unixTime = element[1]
|
||||
if unixTime < MyTime.time() - self.__findTime:
|
||||
if unixTime < MyTime.time() - self.getFindTime():
|
||||
break
|
||||
if self.inIgnoreIPList(ip):
|
||||
logSys.debug("Ignore "+ip)
|
||||
logSys.debug("Ignore %s" % ip)
|
||||
continue
|
||||
logSys.debug("Found "+ip)
|
||||
logSys.debug("Found %s" % ip)
|
||||
self.failManager.addFailure(FailTicket(ip, unixTime))
|
||||
|
||||
|
||||
##
|
||||
# Returns true if the line should be ignored.
|
||||
#
|
||||
|
@ -409,32 +408,7 @@ class FileFilter(Filter):
|
|||
if not self._isActive():
|
||||
# The jail has been stopped
|
||||
break
|
||||
try:
|
||||
# Decode line to UTF-8
|
||||
line = line.decode('utf-8')
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
timeMatch = self.dateDetector.matchTime(line)
|
||||
if not timeMatch:
|
||||
# There is no valid time in this line
|
||||
line = container.readline()
|
||||
continue
|
||||
# Lets split into time part and log part of the line
|
||||
timeLine = timeMatch.group()
|
||||
# Lets leave the beginning in as well, so if there is no
|
||||
# anchore at the beginning of the time regexp, we don't
|
||||
# at least allow injection. Should be harmless otherwise
|
||||
logLine = line[:timeMatch.start()] + line[timeMatch.end():]
|
||||
for element in self.findFailure(timeLine, logLine):
|
||||
ip = element[0]
|
||||
unixTime = element[1]
|
||||
if unixTime < MyTime.time() - self.getFindTime():
|
||||
break
|
||||
if self.inIgnoreIPList(ip):
|
||||
logSys.debug("Ignore "+ip)
|
||||
continue
|
||||
logSys.debug("Found "+ip)
|
||||
self.failManager.addFailure(FailTicket(ip, unixTime))
|
||||
self.processLineAndAdd(line)
|
||||
# Read a new line.
|
||||
line = container.readline()
|
||||
container.close()
|
||||
|
|
Loading…
Reference in New Issue