From 5891d2d2188216d3f1797c5fc63ac331a6ca63cb Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Fri, 10 Feb 2012 22:51:31 -0500 Subject: [PATCH] ENH: fail2ban-regex -- quieter by default and added --verbose mode now # of hits groupped into regexp listings since it makes little to no sense to have it separate --- fail2ban-regex | 87 ++++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/fail2ban-regex b/fail2ban-regex index ffaca6ec..041ee8a6 100755 --- a/fail2ban-regex +++ b/fail2ban-regex @@ -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)