- Added file support to fail2ban-regex. Benchmark feature has been removed

git-svn-id: https://fail2ban.svn.sourceforge.net/svnroot/fail2ban/trunk@523 a942ae1a-1317-0410-a47c-b1dcaea8d605
0.x
Cyril Jaquier 2007-01-21 22:21:13 +00:00
parent a257fdc87d
commit 7bcfd2ace9
5 changed files with 225 additions and 78 deletions

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/python -O
# This file is part of Fail2Ban.
#
# Fail2Ban is free software; you can redistribute it and/or modify
@ -25,12 +25,14 @@ __date__ = "$Date$"
__copyright__ = "Copyright (c) 2004 Cyril Jaquier"
__license__ = "GPL"
import locale, getopt, sys, time, logging, gc
import getopt, sys, time, logging, os
# Inserts our own modules path first in the list
# fix for bug #343821
sys.path.insert(1, "/usr/share/fail2ban")
from ConfigParser import SafeConfigParser
from ConfigParser import NoOptionError, NoSectionError, MissingSectionHeaderError
from common.version import version
from server.filter import Filter
from server.regex import RegexException
@ -38,13 +40,38 @@ from server.regex import RegexException
# Gets the instance of the logger.
logSys = logging.getLogger("fail2ban.regex")
class RegexStat:
def __init__(self, failregex):
self.__stats = 0
self.__failregex = failregex
self.__ipList = list()
def inc(self):
self.__stats += 1
def getStats(self):
return self.__stats
def getFailRegex(self):
return self.__failregex
def appendIP(self, value):
self.__ipList.extend(value)
def getIPList(self):
return self.__ipList
class Fail2banRegex:
test = None
def __init__(self):
self.__filter = Filter(None)
self.__failregex = list()
# Setup logging
logging.getLogger("fail2ban").handlers = []
self.__hdlr = logging.StreamHandler(sys.stdout)
self.__hdlr = logging.StreamHandler(Fail2banRegex.test)
# set a format which is simpler for console use
formatter = logging.Formatter("%(message)s")
# tell the handler to use this format
@ -52,7 +79,8 @@ class Fail2banRegex:
logging.getLogger("fail2ban").addHandler(self.__hdlr)
logging.getLogger("fail2ban").setLevel(logging.ERROR)
def dispVersion(self):
@staticmethod
def dispVersion():
print "Fail2Ban v" + version
print
print "Copyright (c) 2004-2006 Cyril Jaquier"
@ -62,14 +90,26 @@ class Fail2banRegex:
print "Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>."
print "Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>."
def dispUsage(self):
print "Usage: "+sys.argv[0]+" <logline> <failregex>"
@staticmethod
def dispUsage():
print "Usage: "+sys.argv[0]+" [OPTIONS] <LOG> <REGEX>"
print
print "Fail2Ban v" + version + " reads log file that contains password failure report"
print "and bans the corresponding IP addresses using firewall rules."
print
print "This tools can test and benchmark your regular expressions for the \"failregex\""
print "option."
print "This tools can test regular expressions for \"fail2ban\"."
print
print "Options:"
print " -h, --help display this help message"
print " -V, --version print the version"
print
print "Log:"
print " string a string representing a log line"
print " filename path to a log file (/var/log/auth.log)"
print
print "Regex:"
print " string a string representing a 'failregex'"
print " filename path to a filter file (filter.d/sshd.conf)"
print
print "Report bugs to <lostcontrol@users.sourceforge.net>"
@ -78,87 +118,149 @@ class Fail2banRegex:
"""
for opt in optList:
if opt[0] in ["-h", "--help"]:
self.dispUsage()
sys.exit(0)
elif opt[0] in ["-V", "--version"]:
self.dispVersion()
sys.exit(0)
self.dispUsage()
sys.exit(0)
elif opt[0] in ["-V", "--version"]:
self.dispVersion()
sys.exit(0)
@staticmethod
def logIsFile(value):
return os.path.isfile(value)
def readRegex(self, value):
if os.path.isfile(value):
reader = SafeConfigParser()
try:
reader.read(value)
self.__failregex = [RegexStat(m)
for m in reader.get("Definition", "failregex").split('\n')]
except NoSectionError:
print "No [Definition] section in " + value
return False
except NoOptionError:
print "No failregex option in " + value
return False
except MissingSectionHeaderError:
print "No section headers in " + value
return False
else:
self.__failregex = [RegexStat(value)]
return True
def testRegex(self, line, regex):
print
try:
def testRegex(self, line):
for regex in self.__failregex:
logging.getLogger("fail2ban").setLevel(logging.DEBUG)
self.__filter.addFailRegex(regex)
ret = self.__filter.findFailure(line)
print
logging.getLogger("fail2ban").setLevel(logging.CRITICAL)
except RegexException, e:
print e
return False
except IndexError:
print "Sorry, but no <host> found in regex"
return False
if len(ret) == 0:
try:
self.__filter.addFailRegex(regex.getFailRegex())
try:
ret = self.__filter.findFailure(line)
if not len(ret) == 0:
regex.inc()
regex.appendIP(ret)
except RegexException, e:
print e
return False
except IndexError:
print "Sorry, but no <host> found in regex"
return False
finally:
self.__filter.delFailRegex(0)
logging.getLogger("fail2ban").setLevel(logging.CRITICAL)
def printStats(self):
print
print "Results"
print "======="
print
# Print title
cnt = 1
print "Failregex:"
for failregex in self.__failregex:
print "[" + str(cnt) + "] " + failregex.getFailRegex()
cnt += 1
print
# Print stats
cnt = 1
total = 0
print "Number of matches:"
for failregex in self.__failregex:
match = failregex.getStats()
total += match
print "[" + str(cnt) + "] " + str(match) + " match(es)"
cnt += 1
print
if total == 0:
print "Sorry, no match"
print
print "Look at the above section 'Running tests' which could contain important"
print "information."
return False
else:
print "Success, the following data were found:"
timeTuple = time.localtime(ret[0][1])
print "Date: " + time.strftime("%a %b %d %H:%M:%S %Y", timeTuple)
ipList = ""
for i in ret:
ipList = ipList + " " + i[0]
print "IP :" + ipList
# Print stats
cnt = 1
print "Addresses found:"
for failregex in self.__failregex:
print "[" + str(cnt) + "]"
for ip in failregex.getIPList():
timeTuple = time.localtime(ip[1])
timeString = time.strftime("%a %b %d %H:%M:%S %Y", timeTuple)
print " " + ip[0] + " (" + timeString + ")"
cnt += 1
print
print "Date template hits:"
for template in self.__filter.dateDetector.getTemplates():
print `template.getHits()` + " hit: " + template.getName()
print
print "Benchmark. Executing 1000..."
gc.disable()
total = 0
maxValue = 0
maxPos = 0
minValue = 99999999
minPos = 0
for i in range(1000):
start = time.time()
ret = self.__filter.findFailure(line)
end = time.time()
diff = (end - start) * 1000
total = total + diff
minValue = min(minValue, diff)
if minValue == diff:
minPos = i
maxValue = max(maxValue, diff)
if maxValue == diff:
maxPos = i
gc.enable()
print "Performance"
print "Avg: " + `total / 1000` + " ms"
print "Max: " + `maxValue` + " ms (Run " + `maxPos` + ")"
print "Min: " + `minValue` + " ms (Run " + `minPos` + ")"
print "Success, the total number of match is " + str(total)
print
print "However, look at the above section 'Running tests' which could contain important"
print "information."
return True
if __name__ == "__main__":
regex = Fail2banRegex()
fail2banRegex = Fail2banRegex()
# Reads the command line options.
try:
cmdOpts = 'hV'
cmdLongOpts = ['help', 'version']
optList, args = getopt.getopt(sys.argv[1:], cmdOpts, cmdLongOpts)
except getopt.GetoptError:
regex.dispUsage()
fail2banRegex.dispUsage()
sys.exit(-1)
# Process command line
regex.getCmdLineOptions(optList)
fail2banRegex.getCmdLineOptions(optList)
# We need exactly 3 parameters
if len(sys.argv) <> 3:
regex.dispUsage()
if not len(sys.argv) == 3:
fail2banRegex.dispUsage()
sys.exit(-1)
else:
ret = regex.testRegex(sys.argv[1], sys.argv[2])
if ret:
if fail2banRegex.readRegex(sys.argv[2]) == False:
sys.exit(-1)
print
print "Running tests"
print "============="
print
if fail2banRegex.logIsFile(sys.argv[1]):
hdlr = open(sys.argv[1])
for line in hdlr:
fail2banRegex.testRegex(line)
else:
fail2banRegex.testRegex(sys.argv[1])
if fail2banRegex.printStats():
sys.exit(0)
else:
sys.exit(-1)

View File

@ -1,12 +1,11 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-CLIENT "1" "January 2007" "fail2ban-client v0.7.6" "User Commands"
.TH FAIL2BAN-CLIENT "1" "January 2007" "fail2ban-client v0.7.6-SVN" "User Commands"
.SH NAME
fail2ban-client \- configure and control the server
.SH SYNOPSIS
.B fail2ban-client
[\fIOPTIONS\fR]... \fI<COMMAND>\fR
.SH DESCRIPTION
Fail2Ban v0.7.6 reads log file that contains password failure report
[?1034hUsage: ../fail2ban\-client [OPTIONS]... <COMMAND>
.PP
Fail2Ban v0.7.6\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.SH OPTIONS
.TP

View File

@ -1,16 +1,36 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-REGEX "1" "January 2007" "fail2ban-regex v0.7.6" "User Commands"
.TH FAIL2BAN-REGEX "1" "January 2007" "fail2ban-regex v0.7.6-SVN" "User Commands"
.SH NAME
fail2ban-regex \- test Fail2ban "failregex" option
.SH SYNOPSIS
.B fail2ban-regex
\fI<logline> <failregex>\fR
[\fIOPTIONS\fR] \fI<LOG> <REGEX>\fR
.SH DESCRIPTION
Fail2Ban v0.7.6 reads log file that contains password failure report
Fail2Ban v0.7.6\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
This tools can test and benchmark your regular expressions for the "failregex"
option.
This tools can test regular expressions for "fail2ban".
.SH OPTIONS
.TP
\fB\-h\fR, \fB\-\-help\fR
display this help message
.TP
\fB\-V\fR, \fB\-\-version\fR
print the version
.SH LOG
.TP
\fBstring\fR
a string representing a log line
.TP
\fBfilename\fR
path to a log file (/var/log/auth.log)
.SH REGEX
.TP
\fBstring\fR
a string representing a 'failregex'
.TP
\fBfilename\fR
path to a filter file (filter.d/sshd.conf)
.SH AUTHOR
Written by Cyril Jaquier <lostcontrol@users.sourceforge.net>.
Many contributions by Yaroslav O. Halchenko <debian@onerussian.com>.

View File

@ -1,12 +1,12 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36.
.TH FAIL2BAN-SERVER "1" "January 2007" "fail2ban-server v0.7.6" "User Commands"
.TH FAIL2BAN-SERVER "1" "January 2007" "fail2ban-server v0.7.6-SVN" "User Commands"
.SH NAME
fail2ban-server \- start the server
.SH SYNOPSIS
.B fail2ban-server
[\fIOPTIONS\fR]
.SH DESCRIPTION
Fail2Ban v0.7.6 reads log file that contains password failure report
Fail2Ban v0.7.6\-SVN reads log file that contains password failure report
and bans the corresponding IP addresses using firewall rules.
.PP
Only use this command for debugging purpose. Start the server with

View File

@ -40,4 +40,30 @@ echo "[done]"
echo -n "Generating fail2ban-regex "
help2man --section=1 --no-info --include=fail2ban-regex.h2m --output fail2ban-regex.1 ../fail2ban-regex
echo "[done]"
echo -n "Patching fail2ban-regex "
# Changes the title.
sed -i -e 's/.SS "Log:"/.SH LOG/' fail2ban-regex.1
sed -i -e 's/.SS "Regex:"/.SH REGEX/' fail2ban-regex.1
# Sets bold font for commands.
IFS="
"
NEXT=0
FOUND=0
LINES=$( cat fail2ban-regex.1 )
echo -n "" > fail2ban-regex.1
for LINE in $LINES; do
if [ "$LINE" = ".SH LOG" ]; then
FOUND=1
fi
if [ $NEXT -eq 1 ] && [ $FOUND -eq 1 ]; then
echo "\fB$LINE\fR" >> fail2ban-regex.1
else
echo "$LINE" >> fail2ban-regex.1
fi
if [ "$LINE" = ".TP" ]; then
NEXT=1
else
NEXT=0
fi
done
echo "[done]"