diff --git a/ChangeLog b/ChangeLog index ea92ce04..a190b79c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,8 @@ ver. 0.9.1 (2014/xx/xx) - better, faster, stronger * Per-distribution paths to the exim's main log * Ignored IPs are no longer banned when being restored from persistent database + * Manually unbanned IPs are now removed from persistent database, such they + wont be banned again when Fail2Ban is restarted - New features: - Added diff --git a/config/filter.d/courier-smtp.conf b/config/filter.d/courier-smtp.conf index 2b9a13f2..7df385bf 100644 --- a/config/filter.d/courier-smtp.conf +++ b/config/filter.d/courier-smtp.conf @@ -12,7 +12,8 @@ before = common.conf _daemon = courieresmtpd -failregex = ^%(__prefix_line)serror,relay=,.*: 550 User unknown\.$ +failregex = ^%(__prefix_line)serror,relay=,.*: 550 User (<.*> )?unknown\.?$ + ^%(__prefix_line)serror,relay=,msg="535 Authentication failed\.",cmd:( AUTH \S+)?( [0-9a-zA-Z\+/=]+)?$ ignoreregex = diff --git a/config/jail.conf b/config/jail.conf index d3ed9922..c2ce73c1 100644 --- a/config/jail.conf +++ b/config/jail.conf @@ -10,7 +10,7 @@ # # YOU SHOULD NOT MODIFY THIS FILE. # -# It will probably be overwitten or improved in a distribution update. +# It will probably be overwritten or improved in a distribution update. # # Provide customizations in a jail.local file or a jail.d/customisation.local. # For example to change the default bantime for all jails and to enable the diff --git a/fail2ban/server/actions.py b/fail2ban/server/actions.py index fa0e94df..c8e9c5d9 100644 --- a/fail2ban/server/actions.py +++ b/fail2ban/server/actions.py @@ -197,6 +197,8 @@ class Actions(JailThread, Mapping): if ticket is not None: # Unban the IP. self.__unBan(ticket) + if self._jail.database is not None: + self._jail.database.delBan(self._jail, ticket) else: raise ValueError("IP %s is not banned" % ip) diff --git a/fail2ban/server/database.py b/fail2ban/server/database.py index 47f1a485..351d1829 100644 --- a/fail2ban/server/database.py +++ b/fail2ban/server/database.py @@ -368,10 +368,25 @@ class Fail2BanDb(object): #TODO: Implement data parts once arbitrary match keys completed cur.execute( "INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)", - (jail.name, ticket.getIP(), round(ticket.getTime()), + (jail.name, ticket.getIP(), int(round(ticket.getTime())), {"matches": ticket.getMatches(), "failures": ticket.getAttempt()})) + @commitandrollback + def delBan(self, cur, jail, ticket): + """Delete a ban from the database. + + Parameters + ---------- + jail : Jail + Jail in which the ban has occurred. + ticket : BanTicket + Ticket of the ban to be removed. + """ + cur.execute( + "DELETE FROM bans WHERE jail = ? AND ip = ? AND timeofban = ?", + (jail.name, ticket.getIP(), int(round(ticket.getTime())))) + @commitandrollback def _getBans(self, cur, jail=None, bantime=None, ip=None): query = "SELECT ip, timeofban, data FROM bans WHERE 1" diff --git a/fail2ban/tests/databasetestcase.py b/fail2ban/tests/databasetestcase.py index 2cf8577e..f0757e5b 100644 --- a/fail2ban/tests/databasetestcase.py +++ b/fail2ban/tests/databasetestcase.py @@ -173,6 +173,12 @@ class DatabaseTest(unittest.TestCase): self.assertTrue( isinstance(self.db.getBans(jail=self.jail)[0], FailTicket)) + def testDelBan(self): + self.testAddBan() + ticket = self.db.getBans(jail=self.jail)[0] + self.db.delBan(self.jail, ticket) + self.assertEqual(len(self.db.getBans(jail=self.jail)), 0) + def testGetBansWithTime(self): if Fail2BanDb is None: # pragma: no cover return diff --git a/fail2ban/tests/files/logs/courier-smtp b/fail2ban/tests/files/logs/courier-smtp index 212df3b4..7beaf856 100644 --- a/fail2ban/tests/files/logs/courier-smtp +++ b/fail2ban/tests/files/logs/courier-smtp @@ -1,5 +1,9 @@ # failJSON: { "time": "2005-04-10T03:47:57", "match": true , "host": "1.2.3.4" } Apr 10 03:47:57 web courieresmtpd: error,relay=::ffff:1.2.3.4,ident=tmf,from=,to=: 550 User unknown. +# failJSON: { "time": "2005-07-03T23:07:20", "match": true , "host": "1.2.3.4" } +Jul 3 23:07:20 szerver courieresmtpd: error,relay=::ffff:1.2.3.4,msg="535 Authentication failed.",cmd: YWRvYmVhZG9iZQ== +# failJSON: { "time": "2005-07-04T18:39:39", "match": true , "host": "1.2.3.4" } +Jul 4 18:39:39 mail courieresmtpd: error,relay=::ffff:1.2.3.4,from=,to=: 550 User unknown # failJSON: { "time": "2005-07-06T03:42:28", "match": true , "host": "1.2.3.4" } Jul 6 03:42:28 whistler courieresmtpd: error,relay=::ffff:1.2.3.4,from=<>,to=: 550 User unknown. # failJSON: { "time": "2004-11-21T23:16:17", "match": true , "host": "1.2.3.4" }