change IP address string to object handling part 1

pull/1374/head
Alexander Koeppe 2016-03-02 06:56:57 +01:00
parent 674e15c851
commit 5fe2912c03
5 changed files with 36 additions and 25 deletions

View File

@ -42,6 +42,7 @@ from .banmanager import BanManager
from .jailthread import JailThread from .jailthread import JailThread
from .action import ActionBase, CommandAction, CallingMap from .action import ActionBase, CommandAction, CallingMap
from .mytime import MyTime from .mytime import MyTime
from .filter import IPAddr
from ..helpers import getLogger from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
@ -178,7 +179,7 @@ class Actions(JailThread, Mapping):
def getBanTime(self): def getBanTime(self):
return self.__banManager.getBanTime() return self.__banManager.getBanTime()
def removeBannedIP(self, ip): def removeBannedIP(self, ipstr):
"""Removes banned IP calling actions' unban method """Removes banned IP calling actions' unban method
Remove a banned IP now, rather than waiting for it to expire, Remove a banned IP now, rather than waiting for it to expire,
@ -186,14 +187,16 @@ class Actions(JailThread, Mapping):
Parameters Parameters
---------- ----------
ip : str ipstr : str
The IP address to unban The IP address string to unban
Raises Raises
------ ------
ValueError ValueError
If `ip` is not banned If `ip` is not banned
""" """
# Create new IPAddr object from IP string
ip = IPAddr(ipstr)
# Always delete ip from database (also if currently not banned) # Always delete ip from database (also if currently not banned)
if self._jail.database is not None: if self._jail.database is not None:
self._jail.database.delBan(self._jail, ip) self._jail.database.delBan(self._jail, ip)

View File

@ -152,9 +152,9 @@ class BanManager:
for banData in self.__banList: for banData in self.__banList:
ip = banData.getIP() ip = banData.getIP()
# Reference: http://www.team-cymru.org/Services/ip-to-asn.html#dns # Reference: http://www.team-cymru.org/Services/ip-to-asn.html#dns
# TODO: IPv6 compatibility question = ip.getPTR("origin.asn.cymru.com" if ip.isIPv4()
reversed_ip = ".".join(reversed(ip.split("."))) else "origin6.asn.cymru.com"
question = "%s.origin.asn.cymru.com" % reversed_ip )
try: try:
answers = dns.resolver.query(question, "TXT") answers = dns.resolver.query(question, "TXT")
for rdata in answers: for rdata in answers:

View File

@ -32,6 +32,7 @@ from threading import RLock
from .mytime import MyTime from .mytime import MyTime
from .ticket import FailTicket from .ticket import FailTicket
from .filter import IPAddr
from ..helpers import getLogger from ..helpers import getLogger
# Gets the instance of the logger. # Gets the instance of the logger.
@ -413,7 +414,7 @@ class Fail2BanDb(object):
#TODO: Implement data parts once arbitrary match keys completed #TODO: Implement data parts once arbitrary match keys completed
cur.execute( cur.execute(
"INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)", "INSERT INTO bans(jail, ip, timeofban, data) VALUES(?, ?, ?, ?)",
(jail.name, ticket.getIP(), int(round(ticket.getTime())), (jail.name, ticket.getIP().ntoa(), int(round(ticket.getTime())),
{"matches": ticket.getMatches(), {"matches": ticket.getMatches(),
"failures": ticket.getAttempt()})) "failures": ticket.getAttempt()}))
@ -428,7 +429,7 @@ class Fail2BanDb(object):
ip : str ip : str
IP to be removed. IP to be removed.
""" """
queryArgs = (jail.name, ip); queryArgs = (jail.name, ip.ntoa());
cur.execute( cur.execute(
"DELETE FROM bans WHERE jail = ? AND ip = ?", "DELETE FROM bans WHERE jail = ? AND ip = ?",
queryArgs); queryArgs);
@ -446,7 +447,7 @@ class Fail2BanDb(object):
queryArgs.append(MyTime.time() - bantime) queryArgs.append(MyTime.time() - bantime)
if ip is not None: if ip is not None:
query += " AND ip=?" query += " AND ip=?"
queryArgs.append(ip) queryArgs.append(ip.ntoa())
query += " ORDER BY ip, timeofban" query += " ORDER BY ip, timeofban"
return cur.execute(query, queryArgs) return cur.execute(query, queryArgs)
@ -462,7 +463,7 @@ class Fail2BanDb(object):
Ban time in seconds, such that bans returned would still be Ban time in seconds, such that bans returned would still be
valid now. Negative values are equivalent to `None`. valid now. Negative values are equivalent to `None`.
Default `None`; no limit. Default `None`; no limit.
ip : str ip : IPAddr object
IP Address to filter bans by. Default `None`; all IPs. IP Address to filter bans by. Default `None`; all IPs.
Returns Returns
@ -471,7 +472,8 @@ class Fail2BanDb(object):
List of `Ticket`s for bans stored in database. List of `Ticket`s for bans stored in database.
""" """
tickets = [] tickets = []
for ip, timeofban, data in self._getBans(**kwargs): for ipstr, timeofban, data in self._getBans(**kwargs):
ip = IPAddr(ipstr)
#TODO: Implement data parts once arbitrary match keys completed #TODO: Implement data parts once arbitrary match keys completed
tickets.append(FailTicket(ip, timeofban, data.get('matches'))) tickets.append(FailTicket(ip, timeofban, data.get('matches')))
tickets[-1].setAttempt(data.get('failures', 1)) tickets[-1].setAttempt(data.get('failures', 1))
@ -491,7 +493,7 @@ class Fail2BanDb(object):
Ban time in seconds, such that bans returned would still be Ban time in seconds, such that bans returned would still be
valid now. Negative values are equivalent to `None`. valid now. Negative values are equivalent to `None`.
Default `None`; no limit. Default `None`; no limit.
ip : str ip : IPAddr object
IP Address to filter bans by. Default `None`; all IPs. IP Address to filter bans by. Default `None`; all IPs.
Returns Returns
@ -512,6 +514,8 @@ class Fail2BanDb(object):
ticket = None ticket = None
results = list(self._getBans(ip=ip, jail=jail, bantime=bantime)) results = list(self._getBans(ip=ip, jail=jail, bantime=bantime))
# Convert IP strings to IPAddr objects
results = map(lambda i:(IPAddr(i[0]),)+i[1:], results)
if results: if results:
prev_banip = results[0][0] prev_banip = results[0][0]
matches = [] matches = []

View File

@ -303,13 +303,19 @@ class Filter(JailThread):
def getIgnoreCommand(self): def getIgnoreCommand(self):
return self.__ignoreCommand return self.__ignoreCommand
##
# create new IPAddr object from IP address string
def newIP(self, ipstr):
return IPAddr(ipstr)
## ##
# Ban an IP - http://blogs.buanzo.com.ar/2009/04/fail2ban-patch-ban-ip-address-manually.html # Ban an IP - http://blogs.buanzo.com.ar/2009/04/fail2ban-patch-ban-ip-address-manually.html
# Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar> # Arturo 'Buanzo' Busleiman <buanzo@buanzo.com.ar>
# #
# to enable banip fail2ban-client BAN command # to enable banip fail2ban-client BAN command
def addBannedIP(self, ip): def addBannedIP(self, ipstr):
ip = IPAddr(ipstr)
if self.inIgnoreIPList(ip): if self.inIgnoreIPList(ip):
logSys.warning('Requested to manually ban an ignored IP %s. User knows best. Proceeding to ban it.' % ip) logSys.warning('Requested to manually ban an ignored IP %s. User knows best. Proceeding to ban it.' % ip)
@ -433,7 +439,7 @@ class Filter(JailThread):
logSys.debug("Ignore line since time %s < %s - %s" logSys.debug("Ignore line since time %s < %s - %s"
% (unixTime, MyTime.time(), self.getFindTime())) % (unixTime, MyTime.time(), self.getFindTime()))
break break
if self.inIgnoreIPList(ip.ntoa(), log_ignore=True): if self.inIgnoreIPList(ip, log_ignore=True):
continue continue
logSys.info("[%s] Found %s" % (self.jail.name, ip)) logSys.info("[%s] Found %s" % (self.jail.name, ip))
## print "D: Adding a ticket for %s" % ((ip, unixTime, [line]),) ## print "D: Adding a ticket for %s" % ((ip, unixTime, [line]),)
@ -528,17 +534,16 @@ class Filter(JailThread):
try: try:
host = failRegex.getHost() host = failRegex.getHost()
if returnRawHost: if returnRawHost:
ipaddr = IPAddr(host) ip = IPAddr(host)
failList.append([failRegexIndex, ipaddr, date, failList.append([failRegexIndex, ip, date,
failRegex.getMatchedLines()]) failRegex.getMatchedLines()])
if not checkAllRegex: if not checkAllRegex:
break break
else: else:
ipMatch = DNSUtils.textToIp(host, self.__useDns) ips = DNSUtils.textToIp(host, self.__useDns)
if ipMatch: if ips:
for ip in ipMatch: for ip in ips:
ipaddr = IPAddr(ip) failList.append([failRegexIndex, ip,
failList.append([failRegexIndex, ipaddr,
date, failRegex.getMatchedLines()]) date, failRegex.getMatchedLines()])
if not checkAllRegex: if not checkAllRegex:
break break

View File

@ -48,7 +48,9 @@ class Ticket:
def __str__(self): def __str__(self):
return "%s: ip=%s time=%s #attempts=%d matches=%r" % \ return "%s: ip=%s time=%s #attempts=%d matches=%r" % \
(self.__class__.__name__.split('.')[-1], self.__ip, self.__time, self.__attempt, self.__matches) (self.__class__.__name__.split('.')[-1],
self.__ip.ntoa(), self.__time, self.__attempt,
self.__matches)
def __repr__(self): def __repr__(self):
return str(self) return str(self)
@ -63,9 +65,6 @@ class Ticket:
return False return False
def setIP(self, value): def setIP(self, value):
if isinstance(value, basestring):
# guarantee using regular str instead of unicode for the IP
value = str(value)
self.__ip = value self.__ip = value
def getIP(self): def getIP(self):