From 8c38907016ceb9d0a366ac9fa026e3f3ffbf6b44 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Fri, 13 Jul 2012 20:19:30 +0100 Subject: [PATCH 01/31] Misconfigured DNS should not ban *successful* ssh logins Noticed while looking at the source (to see the point of ssh-ddos). POSSIBLE BREAK-IN ATTEMPT - sounds scary? But keep reading the message. It's not a login failure. It's a warning about reverse-DNS. The login can still succeed, and if it _does_ fail, that will be logged as normal. Jul 9 05:43:00 brick sshd[18971]: Address 200.41.233.234 maps to host234.advance.com. ar, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! Jul 9 05:43:00 brick sshd[18971]: Invalid user html from 200.41.233.234 The problem (in my mind) is that some users are stuck with bad dns. The warning won't stop them from logging in. I'm pretty sure they can't even see it. But when they exceed a threshold number of logins - which could be all successful logins - fail2ban will trigger. fail2ban shouldn't adding additional checks to successful logins - it goes against the name fail2ban :) - the first X "POSSIBLE BREAK-IN ATTEMPT"s would be permitted anyway - if you want to ban bad DNS, the right way is PARANOID in /etc/hosts.deny I've checked the source of OpenSSH, and this will only affect the reverse-DNS error. (I won't be offended if you want to check for yourself though ;) $ grep -r -h -C1 'ATTEMPT' openssh-5.5p1/ logit("reverse mapping checking getaddrinfo for %.700s " "[%s] failed - POSSIBLE BREAK-IN ATTEMPT!", name, ntop); return xstrdup(ntop); -- logit("Address %.100s maps to %.600s, but this does not " "map back to the address - POSSIBLE BREAK-IN ATTEMPT!", ntop, name); $ --- config/filter.d/sshd.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/config/filter.d/sshd.conf b/config/filter.d/sshd.conf index e838cecc..4a3db7cc 100644 --- a/config/filter.d/sshd.conf +++ b/config/filter.d/sshd.conf @@ -32,7 +32,6 @@ failregex = ^%(__prefix_line)s(?:error: PAM: )?Authentication failure for .* fro ^%(__prefix_line)sUser .+ from not allowed because listed in DenyUsers\s*$ ^%(__prefix_line)sauthentication failure; logname=\S* uid=\S* euid=\S* tty=\S* ruser=\S* rhost=(?:\s+user=.*)?\s*$ ^%(__prefix_line)srefused connect from \S+ \(\)\s*$ - ^%(__prefix_line)sAddress .* POSSIBLE BREAK-IN ATTEMPT!*\s*$ ^%(__prefix_line)sUser .+ from not allowed because none of user's groups are listed in AllowGroups\s*$ # Option: ignoreregex From 2d66f31ef56dbd0bed666a4610ea60e851541ddb Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 2 Aug 2012 19:48:59 -0400 Subject: [PATCH 02/31] ENH: instead of "Invalid command" warning log exception why command failed --- server/transmitter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/transmitter.py b/server/transmitter.py index f78afaec..a618a1a1 100644 --- a/server/transmitter.py +++ b/server/transmitter.py @@ -55,7 +55,8 @@ class Transmitter: ret = self.__commandHandler(command) ack = 0, ret except Exception, e: - logSys.warn("Invalid command: " + `command`) + logSys.warn("Command %r has failed. Received %r" + % (command, e)) ack = 1, e return ack From 2a225aa6eec2f5338dd1665816774e1dd1bb7aae Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 13 Aug 2012 23:00:23 -0400 Subject: [PATCH 03/31] Added a warning within "complaint.conf" action about care with enabling it --- config/action.d/complain.conf | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/config/action.d/complain.conf b/config/action.d/complain.conf index 5e672475..6677ec49 100644 --- a/config/action.d/complain.conf +++ b/config/action.d/complain.conf @@ -12,8 +12,22 @@ # any other addresses found in the whois record, with a few exceptions. # If no addresses are found, no e-mail is sent. # -# $Revision$ +# WARNING +# ------- # +# Please do not use this action unless you are certain that fail2ban +# does not result in "false positives" for your deployment. False +# positive reports could serve a mis-favor to the original cause by +# flooding corresponding contact addresses, and complicating the work +# of administration personnel responsible for handling (verified) legit +# complains. +# +# Please consider using e.g. sendmail-whois-lines.conf action which +# would send the reports with relevant information to you, so the +# report could be first reviewed and then forwarded to a corresponding +# contact if legit. +# + [Definition] From 958a1b0a40de5285e7b0dfa8f4d15681fc0c7bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 30 Sep 2012 13:27:21 +0200 Subject: [PATCH 04/31] Lighttpd: support auth.backend = "htdigest" --- config/filter.d/lighttpd-auth.conf | 2 +- testcases/files/logs/lighttpd | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config/filter.d/lighttpd-auth.conf b/config/filter.d/lighttpd-auth.conf index 837cc501..ba438328 100644 --- a/config/filter.d/lighttpd-auth.conf +++ b/config/filter.d/lighttpd-auth.conf @@ -10,7 +10,7 @@ # Values: TEXT # failregex = .*http_auth.*password doesn\'t match.*IP: \s*$ - + .*http_auth.*wrong password.*IP: \s*$ # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. diff --git a/testcases/files/logs/lighttpd b/testcases/files/logs/lighttpd index 1697a276..c3cfcb75 100644 --- a/testcases/files/logs/lighttpd +++ b/testcases/files/logs/lighttpd @@ -1,2 +1,3 @@ #authentification failure (mod_auth) 2011-12-25 17:09:20: (http_auth.c.875) password doesn't match for /gitweb/ username: francois, IP: 4.4.4.4 +2012-09-26 10:24:35: (http_auth.c.1136) digest: auth failed for xxx : wrong password, IP: 4.4.4.4 From 282724a7f9e8885764b023b0e8d5e38b19734937 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Sun, 30 Sep 2012 11:30:24 -0400 Subject: [PATCH 05/31] ENH: join both failregex for lighttpd-auth into a single one they are close in meaning should provide a slight run-time performance benefit --- config/filter.d/lighttpd-auth.conf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/filter.d/lighttpd-auth.conf b/config/filter.d/lighttpd-auth.conf index ba438328..1931373c 100644 --- a/config/filter.d/lighttpd-auth.conf +++ b/config/filter.d/lighttpd-auth.conf @@ -9,8 +9,7 @@ # Notes.: regex to match wrong passwords as notified by lighttpd's auth Module # Values: TEXT # -failregex = .*http_auth.*password doesn\'t match.*IP: \s*$ - .*http_auth.*wrong password.*IP: \s*$ +failregex = .*http_auth.*(password doesn\'t match|wrong password).*IP: \s*$ # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. From 6ee2c0a01436daa2c95773b26852ba9d5dc52871 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 3 Oct 2012 09:12:37 -0400 Subject: [PATCH 06/31] DOC: untabified for proper formatting + trailing spaces --- DEVELOP | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/DEVELOP b/DEVELOP index feb4249f..025b58b4 100644 --- a/DEVELOP +++ b/DEVELOP @@ -7,18 +7,18 @@ How to develop for Fail2Ban ================================================================================ -Fail2Ban uses GIT (http://git-scm.com/) distributed source control. This gives -each developer their own complete copy of the entire repository. Developers can -add and switch branches and commit changes when ever they want and then ask a +Fail2Ban uses GIT (http://git-scm.com/) distributed source control. This gives +each developer their own complete copy of the entire repository. Developers can +add and switch branches and commit changes when ever they want and then ask a maintainer to merge their changes. -Fail2Ban uses GitHub (https://github.com/fail2ban/fail2ban) to manage access to -the Git repository. GitHub provides free hosting for open-source projects as +Fail2Ban uses GitHub (https://github.com/fail2ban/fail2ban) to manage access to +the Git repository. GitHub provides free hosting for open-source projects as well as a web-based Git repository browser and an issue tracker. -If you are familiar with Python and you have a bug fix or a feature that you -would like to add to Fail2Ban, the best way to do so it to use the GitHub Pull -Request feature. You can find more details on the Fail2Ban wiki +If you are familiar with Python and you have a bug fix or a feature that you +would like to add to Fail2Ban, the best way to do so it to use the GitHub Pull +Request feature. You can find more details on the Fail2Ban wiki (http://www.fail2ban.org/wiki/index.php/Get_Involved) Testing @@ -26,7 +26,7 @@ Testing Existing tests can be run by executing `fail2ban-testcases`. -Documentation about creating tests (when tests are required and some guidelines +Documentation about creating tests (when tests are required and some guidelines for creating good tests) will be added soon. Coding Standards @@ -60,7 +60,7 @@ one):: JailThread -> Filter -> FileFilter -> {FilterPoll, FilterPyinotify, ...} | | * FileContainer | + FailManager - | + DateDetector + | + DateDetector \- -> Actions * Actions + BanManager From 83109bce144f443a48ef31165a5389b7b83f4e0e Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 8 Oct 2012 22:14:51 -0400 Subject: [PATCH 07/31] BF: escape the content of since its value could contain arbitrary symbols --- server/action.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/server/action.py b/server/action.py index faf50653..387c115c 100644 --- a/server/action.py +++ b/server/action.py @@ -230,7 +230,14 @@ class Action: def execActionStop(self): stopCmd = Action.replaceTag(self.__actionStop, self.__cInfo) return Action.executeCmd(stopCmd) - + + def escapeTag(tag): + for c in '\\#&;`|*?~<>^()[]{}$\n': + if c in tag: + tag = tag.replace(c, '\\' + c) + return tag + escapeTag = staticmethod(escapeTag) + ## # Replaces tags in query with property values in aInfo. # @@ -243,8 +250,13 @@ class Action: """ Replace tags in query """ string = query - for tag in aInfo: - string = string.replace('<' + tag + '>', str(aInfo[tag])) + for tag, value in aInfo.iteritems(): + value = str(value) # assure string + if tag == 'matches': + # That one needs to be escaped since its content is + # out of our control + value = escapeTag(value) + string = string.replace('<' + tag + '>', value) # New line string = string.replace("
", '\n') return string From 652b5a77e09e6e996e81e5cb235b525149243e12 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Wed, 10 Oct 2012 08:39:18 -0400 Subject: [PATCH 08/31] BF: fixing current version string to contain the patch index, i.e. ".1" Thanks Fabian Fischer --- ChangeLog | 2 +- common/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d79aa02..fd4a14ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ |_| \__,_|_|_/___|_.__/\__,_|_||_| ================================================================================ -Fail2Ban (version 0.8.7) 2012/07/31 +Fail2Ban (version 0.8.7.1) 2012/07/31 ================================================================================ ver. 0.8.7.1 (2012/07/31) - stable diff --git a/common/version.py b/common/version.py index cec7a8fb..d2fefcc2 100644 --- a/common/version.py +++ b/common/version.py @@ -25,4 +25,4 @@ __author__ = "Cyril Jaquier" __copyright__ = "Copyright (c) 2004 Cyril Jaquier, 2011-2012 Yaroslav Halchenko" __license__ = "GPL" -version = "0.8.7" +version = "0.8.7.1" From 9510619b7b89f9adb3ad44f3f5377d3abd43bcbf Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 1 Nov 2012 15:24:32 -0400 Subject: [PATCH 09/31] ENH: minor -- print out why skipping a backend while testing --- fail2ban-testcases | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fail2ban-testcases b/fail2ban-testcases index 0160781d..ea95e9c5 100755 --- a/fail2ban-testcases +++ b/fail2ban-testcases @@ -142,14 +142,14 @@ filters = [FilterPoll] # always available try: from server.filtergamin import FilterGamin filters.append(FilterGamin) -except: - pass +except Exception, e: + print "I: Skipping gamin backend testing. Got exception '%s'" % e try: from server.filterpyinotify import FilterPyinotify filters.append(FilterPyinotify) -except: - pass +except Exception, e: + print "I: Skipping pyinotify backend testing. Got exception '%s'" % e for Filter_ in filters: tests.addTest(unittest.makeSuite( From 5becaf8ef2b8cd37d65de8079ce38d5e2c05be6d Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Thu, 1 Nov 2012 15:34:20 -0400 Subject: [PATCH 10/31] BF: (python 2.[45]) store backends names in a list to use .index later on (Closes gh-83) .index() got into tuple's API only in 2.6 --- fail2ban-testcases | 1 + server/jail.py | 4 +++- testcases/filtertestcase.py | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/fail2ban-testcases b/fail2ban-testcases index ea95e9c5..cc616c0e 100755 --- a/fail2ban-testcases +++ b/fail2ban-testcases @@ -125,6 +125,7 @@ tests.addTest(unittest.makeSuite(filtertestcase.LogFile)) tests.addTest(unittest.makeSuite(filtertestcase.LogFileMonitor)) tests.addTest(unittest.makeSuite(filtertestcase.GetFailures)) tests.addTest(unittest.makeSuite(filtertestcase.DNSUtilsTests)) +tests.addTest(unittest.makeSuite(filtertestcase.JailTests)) # DateDetector tests.addTest(unittest.makeSuite(datedetectortestcase.DateDetectorTest)) diff --git a/server/jail.py b/server/jail.py index 4ab83db4..dee64e7f 100644 --- a/server/jail.py +++ b/server/jail.py @@ -33,7 +33,9 @@ logSys = logging.getLogger("fail2ban.jail") class Jail: #Known backends. Each backend should have corresponding __initBackend method - _BACKENDS = ('pyinotify', 'gamin', 'polling') + # yoh: stored in a list instead of a tuple since only + # list had .index until 2.6 + _BACKENDS = ['pyinotify', 'gamin', 'polling'] def __init__(self, name, backend = "auto"): self.__name = name diff --git a/testcases/filtertestcase.py b/testcases/filtertestcase.py index eade537f..c10fa78d 100644 --- a/testcases/filtertestcase.py +++ b/testcases/filtertestcase.py @@ -28,6 +28,7 @@ import sys import time import tempfile +from server.jail import Jail from server.filterpoll import FilterPoll from server.filter import FileFilter, DNSUtils from server.failmanager import FailManager @@ -626,3 +627,10 @@ class DNSUtilsTests(unittest.TestCase): self.assertEqual(res, ['192.0.43.10']) else: self.assertEqual(res, []) + +class JailTests(unittest.TestCase): + + def testSetBackend_gh83(self): + # smoke test + jail = Jail('test', backend='polling') # Must not fail to initiate + From 09355663f7a3c0409e08efdebf98b1bbf47d1d9c Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Nov 2012 16:54:19 -0500 Subject: [PATCH 11/31] BF: (python 2.4) -- access to staticmethod should go via Class TODO: get away from using all those staticmethods in f2b --- server/action.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/action.py b/server/action.py index 387c115c..bd750337 100644 --- a/server/action.py +++ b/server/action.py @@ -255,7 +255,7 @@ class Action: if tag == 'matches': # That one needs to be escaped since its content is # out of our control - value = escapeTag(value) + value = Action.escapeTag(value) string = string.replace('<' + tag + '>', value) # New line string = string.replace("
", '\n') From 8e64c281dd178e29a6ef50928f4552757043e05b Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Nov 2012 20:09:15 -0500 Subject: [PATCH 12/31] BF: in code we should use MyTime wrapper instead of time module directly to allow for some tests to work correctly --- server/filter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/filter.py b/server/filter.py index d69f02aa..f71a0a06 100644 --- a/server/filter.py +++ b/server/filter.py @@ -220,7 +220,7 @@ class Filter(JailThread): # to enable banip fail2ban-client BAN command def addBannedIP(self, ip): - unixTime = time.time() + unixTime = MyTime.time() for i in xrange(self.failManager.getMaxRetry()): self.failManager.addFailure(FailTicket(ip, unixTime)) From 6288ec27577cb5ddeab9151b5a72c3803cf1041c Mon Sep 17 00:00:00 2001 From: David Engeset Date: Mon, 5 Nov 2012 15:07:33 -0800 Subject: [PATCH 13/31] Added in command option to unban and IP, just like using 'banip'. Command looks like: fail2ban-client set unbanip --- server/actions.py | 13 +++++++++++++ server/banmanager.py | 26 +++++++++++++++++++++++++- server/server.py | 3 +++ server/transmitter.py | 3 +++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/server/actions.py b/server/actions.py index f936de18..79783395 100644 --- a/server/actions.py +++ b/server/actions.py @@ -120,6 +120,19 @@ class Actions(JailThread): def getBanTime(self): return self.__banManager.getBanTime() + ## + # Remove a banned IP now, rather than waiting for it to expire, even if set to never expire. + # + # @return the IP string or 'None' if not unbanned. + def removeBannedIP(self, ip): + # Find the ticket with the IP. + ticket = self.__banManager.getTicketByIP(ip) + if ticket != False: + # Unban the IP. + self.__unBan(ticket) + return ip + return 'None' + ## # Main loop. # diff --git a/server/banmanager.py b/server/banmanager.py index 214916b7..e9c81214 100644 --- a/server/banmanager.py +++ b/server/banmanager.py @@ -208,7 +208,7 @@ class BanManager: return unBanList finally: self.__lock.release() - + ## # Flush the ban list. # @@ -223,3 +223,27 @@ class BanManager: return uBList finally: self.__lock.release() + + ## + # Gets the ticket for the specified IP. + # + # @return the ticket for the IP or False. + def getTicketByIP(self, ip): + try: + ipticket = False + self.__lock.acquire() + + # Find the ticket the IP goes with. + for ticket in self.__banList: + if ticket.getIP() == ip: + ipticket = ticket + break + + unBanList = [ipticket] + # Remove the ticket from the ban list. + self.__banList = [ticket for ticket in self.__banList + if ticket not in unBanList] + + return ipticket + finally: + self.__lock.release() diff --git a/server/server.py b/server/server.py index b734f82a..d9532be2 100644 --- a/server/server.py +++ b/server/server.py @@ -241,6 +241,9 @@ class Server: def setBanIP(self, name, value): return self.__jails.getFilter(name).addBannedIP(value) + def setUnbanIP(self, name, value): + return self.__jails.getAction(name).removeBannedIP(value) + def getBanTime(self, name): return self.__jails.getAction(name).getBanTime() diff --git a/server/transmitter.py b/server/transmitter.py index a618a1a1..23b609a1 100644 --- a/server/transmitter.py +++ b/server/transmitter.py @@ -175,6 +175,9 @@ class Transmitter: elif command[1] == "banip": value = command[2] return self.__server.setBanIP(name,value) + elif command[1] == "unbanip": + value = command[2] + return self.__server.setUnbanIP(name,value) elif command[1] == "addaction": value = command[2] self.__server.addAction(name, value) From f14c7ae401376ad984dde151cf7b3fd6cf5081a1 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Nov 2012 20:37:06 -0500 Subject: [PATCH 14/31] ENH: refactored previous commit to make it more Pythonic (With prev commit closes gh-86, gh-81) --- server/actions.py | 2 +- server/banmanager.py | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/server/actions.py b/server/actions.py index 79783395..3461e672 100644 --- a/server/actions.py +++ b/server/actions.py @@ -127,7 +127,7 @@ class Actions(JailThread): def removeBannedIP(self, ip): # Find the ticket with the IP. ticket = self.__banManager.getTicketByIP(ip) - if ticket != False: + if ticket is not None: # Unban the IP. self.__unBan(ticket) return ip diff --git a/server/banmanager.py b/server/banmanager.py index e9c81214..596dc4e9 100644 --- a/server/banmanager.py +++ b/server/banmanager.py @@ -230,20 +230,14 @@ class BanManager: # @return the ticket for the IP or False. def getTicketByIP(self, ip): try: - ipticket = False self.__lock.acquire() - # Find the ticket the IP goes with. - for ticket in self.__banList: + # Find the ticket the IP goes with and return it + for i, ticket in enumerate(self.__banList): if ticket.getIP() == ip: - ipticket = ticket - break - - unBanList = [ipticket] - # Remove the ticket from the ban list. - self.__banList = [ticket for ticket in self.__banList - if ticket not in unBanList] - - return ipticket + # Return the ticket after removing (popping) + # if from the ban list. + return self.__banList.pop(i) finally: self.__lock.release() + return None # if none found From 2d672d1c81ae5bdeaf9e5a03f8574f9b397925c7 Mon Sep 17 00:00:00 2001 From: David Engeset Date: Mon, 5 Nov 2012 14:02:11 -0800 Subject: [PATCH 15/31] Added in while loop to process the Fail Manager after the requested banned IP was added to its queue. This solves the issue of needing to touch the log file that is being monitored to get the IP to be banned accordingly. Added in import of FailManagerEmpty exception class. --- server/filter.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/filter.py b/server/filter.py index f71a0a06..b37e37e6 100644 --- a/server/filter.py +++ b/server/filter.py @@ -27,6 +27,7 @@ __date__ = "$Date$" __copyright__ = "Copyright (c) 2004 Cyril Jaquier" __license__ = "GPL" +from failmanager import FailManagerEmpty from failmanager import FailManager from ticket import FailTicket from jailthread import JailThread @@ -224,6 +225,14 @@ class Filter(JailThread): for i in xrange(self.failManager.getMaxRetry()): self.failManager.addFailure(FailTicket(ip, unixTime)) + # Perform the banning of the IP now. + try: + while True: + ticket = self.failManager.toBan() + self.jail.putFailTicket(ticket) + except FailManagerEmpty: + self.failManager.cleanup(MyTime.time()) + return ip ## From b773ed617bf73f01ec4757d37caf63df30760b3c Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Nov 2012 21:12:03 -0500 Subject: [PATCH 16/31] DOC: minor "fixes" in DEVELOP --- DEVELOP | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/DEVELOP b/DEVELOP index 025b58b4..7a6a7b9b 100644 --- a/DEVELOP +++ b/DEVELOP @@ -58,18 +58,20 @@ one):: RF-Note just a note which might be useful to address while doing RF JailThread -> Filter -> FileFilter -> {FilterPoll, FilterPyinotify, ...} - | | * FileContainer - | + FailManager - | + DateDetector - \- -> Actions - * Actions - + BanManager - + | * FileContainer + + FailManager + + DateDetector + + Jail (provided in __init__) which contains this Filter + (used for passing tickets from FailManager to Jail's __queue) Server + Jails * Jail - + Filter + + Filter (in __filter) * tickets (in __queue) + + Actions (in __action) + * Action + + BanManager + failmanager.py ~~~~~~~~~~~~~~ @@ -147,7 +149,7 @@ one way or another provide except FailManagerEmpty: self.failManager.cleanup(MyTime.time()) -thus channeling "ban tickets" from their failManager to a +thus channeling "ban tickets" from their failManager to the corresponding jail. action.py From 1e12c220e6828f9dd8d4530eb9a3abe843d7155e Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Nov 2012 21:22:33 -0500 Subject: [PATCH 17/31] minor: added a note on now "negative" log entries on "POSSIBLE BREAK-IN ATTEMPT" --- testcases/files/logs/sshd | 1 + 1 file changed, 1 insertion(+) diff --git a/testcases/files/logs/sshd b/testcases/files/logs/sshd index 639aaf0b..8e6c1273 100644 --- a/testcases/files/logs/sshd +++ b/testcases/files/logs/sshd @@ -22,6 +22,7 @@ Feb 25 14:34:11 belka sshd[31607]: User root from ferrari.inescn.pt not allowed Nov 11 23:33:27 Server sshd[5174]: refused connect from _U2FsdGVkX19P3BCJmFBHhjLza8BcMH06WCUVwttMHpE=_@::ffff:218.249.210.161 (::ffff:218.249.210.161) #7 added exclamation mark to BREAK-IN +# Now should be a negative since we decided not to catch those Oct 15 19:51:35 server sshd[7592]: Address 1.2.3.4 maps to 1234.bbbbbb.com, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT Oct 15 19:51:35 server sshd[7592]: Address 1.2.3.4 maps to 1234.bbbbbb.com, but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT! From f52ba9923a1ad44274792f08e9d4ad0ce8dd4c3e Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Nov 2012 21:30:07 -0500 Subject: [PATCH 18/31] ENH: downgrade "already banned" from WARN to INFO level (Closes gh-79) Most of the time it is a benign latency effect so nothing to warn about. --- server/actions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/actions.py b/server/actions.py index 3461e672..94344dce 100644 --- a/server/actions.py +++ b/server/actions.py @@ -181,7 +181,7 @@ class Actions(JailThread): action.execActionBan(aInfo) return True else: - logSys.warn("[%s] %s already banned" % (self.jail.getName(), + logSys.info("[%s] %s already banned" % (self.jail.getName(), str(aInfo["ip"]))) return False From 63237a785ec6bfa00f5e3ec0117c86297bc5b4b4 Mon Sep 17 00:00:00 2001 From: Yaroslav Halchenko Date: Mon, 5 Nov 2012 21:50:49 -0500 Subject: [PATCH 19/31] DOC: forgotten --help entry for " unban " --- common/protocol.py | 1 + 1 file changed, 1 insertion(+) diff --git a/common/protocol.py b/common/protocol.py index db2b07eb..2f8ffa6c 100644 --- a/common/protocol.py +++ b/common/protocol.py @@ -64,6 +64,7 @@ protocol = [ ["set bantime