|
|
|
@ -72,6 +72,7 @@ class Fail2banRegex:
|
|
|
|
|
self.__filter = Filter(None) |
|
|
|
|
self.__ignoreregex = list() |
|
|
|
|
self.__failregex = list() |
|
|
|
|
self.__verbose = False |
|
|
|
|
# Setup logging |
|
|
|
|
logging.getLogger("fail2ban").handlers = [] |
|
|
|
|
self.__hdlr = logging.StreamHandler(Fail2banRegex.test) |
|
|
|
@ -79,6 +80,7 @@ class Fail2banRegex:
|
|
|
|
|
formatter = logging.Formatter("%(message)s") |
|
|
|
|
# tell the handler to use this format |
|
|
|
|
self.__hdlr.setFormatter(formatter) |
|
|
|
|
self.__logging_level = self.__verbose and logging.DEBUG or logging.WARN |
|
|
|
|
logging.getLogger("fail2ban").addHandler(self.__hdlr) |
|
|
|
|
logging.getLogger("fail2ban").setLevel(logging.ERROR) |
|
|
|
|
|
|
|
|
@ -106,6 +108,7 @@ class Fail2banRegex:
|
|
|
|
|
print "Options:" |
|
|
|
|
print " -h, --help display this help message" |
|
|
|
|
print " -V, --version print the version" |
|
|
|
|
print " -v, --verbose verbose output" |
|
|
|
|
print |
|
|
|
|
print "Log:" |
|
|
|
|
print " string a string representing a log line" |
|
|
|
@ -132,6 +135,8 @@ class Fail2banRegex:
|
|
|
|
|
elif opt[0] in ["-V", "--version"]: |
|
|
|
|
self.dispVersion() |
|
|
|
|
sys.exit(0) |
|
|
|
|
elif opt[0] in ["-v", "--verbose"]: |
|
|
|
|
self.__verbose = True |
|
|
|
|
|
|
|
|
|
#@staticmethod |
|
|
|
|
def logIsFile(value): |
|
|
|
@ -199,7 +204,7 @@ class Fail2banRegex:
|
|
|
|
|
def testIgnoreRegex(self, line): |
|
|
|
|
found = False |
|
|
|
|
for regex in self.__ignoreregex: |
|
|
|
|
logging.getLogger("fail2ban").setLevel(logging.DEBUG) |
|
|
|
|
logging.getLogger("fail2ban").setLevel(self.__logging_level) |
|
|
|
|
try: |
|
|
|
|
self.__filter.addIgnoreRegex(regex.getFailRegex()) |
|
|
|
|
try: |
|
|
|
@ -211,7 +216,7 @@ class Fail2banRegex:
|
|
|
|
|
return False |
|
|
|
|
finally: |
|
|
|
|
self.__filter.delIgnoreRegex(0) |
|
|
|
|
logging.getLogger("fail2ban").setLevel(logging.CRITICAL) |
|
|
|
|
logging.getLogger("fail2ban").setLevel(self.__logging_level) |
|
|
|
|
|
|
|
|
|
def testRegex(self, line): |
|
|
|
|
found = False |
|
|
|
@ -251,30 +256,28 @@ class Fail2banRegex:
|
|
|
|
|
|
|
|
|
|
def print_failregexes(title, failregexes): |
|
|
|
|
# Print title |
|
|
|
|
print title |
|
|
|
|
print "|- Regular expressions:" |
|
|
|
|
for cnt, failregex in enumerate(failregexes): |
|
|
|
|
print "| [%d] %s" % (cnt+1, failregex.getFailRegex()) |
|
|
|
|
print "|" |
|
|
|
|
|
|
|
|
|
# Print stats |
|
|
|
|
total = 0 |
|
|
|
|
print "`- Number of matches:" |
|
|
|
|
total, out = 0, [] |
|
|
|
|
for cnt, failregex in enumerate(failregexes): |
|
|
|
|
match = failregex.getStats() |
|
|
|
|
total += match |
|
|
|
|
print " [%d] %s match(es)" % (cnt+1, match) |
|
|
|
|
if (match or self.__verbose): |
|
|
|
|
out.append("| %d) [%d] %s" % (cnt+1, match, failregex.getFailRegex())) |
|
|
|
|
print "%s: %d total" % (title, total) |
|
|
|
|
if len(out): |
|
|
|
|
print "|- #) [# of hits] regular expression" |
|
|
|
|
print '\n'.join(out) |
|
|
|
|
print '`-' |
|
|
|
|
print |
|
|
|
|
return total |
|
|
|
|
|
|
|
|
|
# Print title |
|
|
|
|
total = print_failregexes("Failregex", self.__failregex) |
|
|
|
|
_ = print_failregexes("Ignoreregex", self.__ignoreregex) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print "Summary" |
|
|
|
|
print "=======" |
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if total == 0: |
|
|
|
|
print "Sorry, no match" |
|
|
|
|
print |
|
|
|
@ -285,17 +288,19 @@ class Fail2banRegex:
|
|
|
|
|
# Print stats |
|
|
|
|
print "Addresses found:" |
|
|
|
|
for cnt, failregex in enumerate(self.__failregex): |
|
|
|
|
print "[%d]" % (cnt+1) |
|
|
|
|
for ip in failregex.getIPList(): |
|
|
|
|
timeTuple = time.localtime(ip[1]) |
|
|
|
|
timeString = time.strftime("%a %b %d %H:%M:%S %Y", timeTuple) |
|
|
|
|
print " %s (%s)%s" % ( |
|
|
|
|
ip[0], timeString, ip[2] and " (already matched)" or "") |
|
|
|
|
if self.__verbose or len(failregex.getIPList()): |
|
|
|
|
print "[%d]" % (cnt+1) |
|
|
|
|
for ip in failregex.getIPList(): |
|
|
|
|
timeTuple = time.localtime(ip[1]) |
|
|
|
|
timeString = time.strftime("%a %b %d %H:%M:%S %Y", timeTuple) |
|
|
|
|
print " %s (%s)%s" % ( |
|
|
|
|
ip[0], timeString, ip[2] and " (already matched)" or "") |
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
print "Date template hits:" |
|
|
|
|
for template in self.__filter.dateDetector.getTemplates(): |
|
|
|
|
print `template.getHits()` + " hit(s): " + template.getName() |
|
|
|
|
if self.__verbose or template.getHits(): |
|
|
|
|
print `template.getHits()` + " hit(s): " + template.getName() |
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
print "Success, the total number of match is " + str(total) |
|
|
|
@ -309,16 +314,17 @@ if __name__ == "__main__":
|
|
|
|
|
fail2banRegex = Fail2banRegex() |
|
|
|
|
# Reads the command line options. |
|
|
|
|
try: |
|
|
|
|
cmdOpts = 'hV' |
|
|
|
|
cmdLongOpts = ['help', 'version'] |
|
|
|
|
cmdOpts = 'hVc' |
|
|
|
|
cmdLongOpts = ['help', 'version', 'verbose'] |
|
|
|
|
optList, args = getopt.getopt(sys.argv[1:], cmdOpts, cmdLongOpts) |
|
|
|
|
except getopt.GetoptError: |
|
|
|
|
fail2banRegex.dispUsage() |
|
|
|
|
sys.exit(-1) |
|
|
|
|
# Process command line |
|
|
|
|
fail2banRegex.getCmdLineOptions(optList) |
|
|
|
|
# We need exactly 3 parameters |
|
|
|
|
if not len(sys.argv) in (3, 4): |
|
|
|
|
|
|
|
|
|
# We need 2 or 3 parameters |
|
|
|
|
if not len(args) in (2, 3): |
|
|
|
|
fail2banRegex.dispUsage() |
|
|
|
|
sys.exit(-1) |
|
|
|
|
else: |
|
|
|
@ -327,17 +333,17 @@ if __name__ == "__main__":
|
|
|
|
|
print "=============" |
|
|
|
|
print |
|
|
|
|
|
|
|
|
|
if len(sys.argv) == 4: |
|
|
|
|
if fail2banRegex.readIgnoreRegex(sys.argv[3]) == False: |
|
|
|
|
sys.exit(-1) |
|
|
|
|
cmd_log, cmd_regex = args[:2] |
|
|
|
|
|
|
|
|
|
if fail2banRegex.readRegex(sys.argv[2]) == False: |
|
|
|
|
sys.exit(-1) |
|
|
|
|
if len(args) == 3: |
|
|
|
|
fail2banRegex.readIgnoreRegex(args[2]) or sys.exit(-1) |
|
|
|
|
|
|
|
|
|
if fail2banRegex.logIsFile(sys.argv[1]): |
|
|
|
|
fail2banRegex.readRegex(cmd_regex) or sys.exit(-1) |
|
|
|
|
|
|
|
|
|
if fail2banRegex.logIsFile(cmd_log): |
|
|
|
|
try: |
|
|
|
|
hdlr = open(sys.argv[1]) |
|
|
|
|
print "Use log file : " + sys.argv[1] |
|
|
|
|
hdlr = open(cmd_log) |
|
|
|
|
print "Use log file : " + cmd_log |
|
|
|
|
print |
|
|
|
|
for line in hdlr: |
|
|
|
|
fail2banRegex.testIgnoreRegex(line) |
|
|
|
@ -348,15 +354,12 @@ if __name__ == "__main__":
|
|
|
|
|
sys.exit(-1) |
|
|
|
|
else: |
|
|
|
|
if len(sys.argv[1]) > 53: |
|
|
|
|
stripLog = sys.argv[1][0:50] + "..." |
|
|
|
|
stripLog = cmd_log[0:50] + "..." |
|
|
|
|
else: |
|
|
|
|
stripLog = sys.argv[1] |
|
|
|
|
stripLog = cmd_log |
|
|
|
|
print "Use single line: " + stripLog |
|
|
|
|
print |
|
|
|
|
fail2banRegex.testIgnoreRegex(sys.argv[1]) |
|
|
|
|
fail2banRegex.testRegex(sys.argv[1]) |
|
|
|
|
|
|
|
|
|
if fail2banRegex.printStats(): |
|
|
|
|
sys.exit(0) |
|
|
|
|
else: |
|
|
|
|
sys.exit(-1) |
|
|
|
|
fail2banRegex.testIgnoreRegex(cmd_log) |
|
|
|
|
fail2banRegex.testRegex(cmd_log) |
|
|
|
|
|
|
|
|
|
fail2banRegex.printStats() or sys.exit(-1) |
|
|
|
|