BF: Remove manually unbanned IPs from persistent database

Stops them being restored when Fail2Ban is restarted. Particularly this
is an issue with bantime < 0

Fixes gh-768
pull/769/head
Steven Hiscocks 2014-07-19 15:17:32 +01:00
parent e301d6c840
commit 01d02ca5e6
4 changed files with 26 additions and 1 deletions

View File

@ -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 monit filter thanks Jason H Martin.

View File

@ -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)

View File

@ -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"

View File

@ -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