ENH: Allow separate blacklist category for badips.py action

pull/641/head
Steven Hiscocks 2014-02-14 17:45:08 +00:00
parent cf81ddd8e2
commit 5c7630c4be
2 changed files with 36 additions and 5 deletions

View File

@ -43,7 +43,7 @@ class BadIPsAction(ActionBase):
Request, headers={'User-Agent': "Fail2Ban %s" % f2bVersion}) Request, headers={'User-Agent': "Fail2Ban %s" % f2bVersion})
def __init__(self, jail, name, category, score=5, age="24h", def __init__(self, jail, name, category, score=5, age="24h",
banaction=None, updateperiod=900): banaction=None, bancategory=None, updateperiod=900):
"""Initialise action. """Initialise action.
Parameters Parameters
@ -53,7 +53,7 @@ class BadIPsAction(ActionBase):
name : str name : str
Name assigned to the action. Name assigned to the action.
category : str category : str
Valid badips.com category. Valid badips.com category for reporting failures.
score : int, optional score : int, optional
Minimum score for bad IPs. Default 5. Minimum score for bad IPs. Default 5.
age : str, optional age : str, optional
@ -63,6 +63,11 @@ class BadIPsAction(ActionBase):
Name of banaction to use for blacklisting bad IPs. If `None`, Name of banaction to use for blacklisting bad IPs. If `None`,
no blacklist of IPs will take place. no blacklist of IPs will take place.
Default `None`. Default `None`.
bancategory : str, optional
Name of category to use for blacklisting, which can differ
from category used for reporting. e.g. may want to report
"postfix", but want to use whole "mail" category for blacklist.
Default `category`.
updateperiod : int, optional updateperiod : int, optional
Time in seconds between updating bad IPs blacklist. Time in seconds between updating bad IPs blacklist.
Default 900 (15 minutes) Default 900 (15 minutes)
@ -78,6 +83,7 @@ class BadIPsAction(ActionBase):
self.score = score self.score = score
self.age = age self.age = age
self.banaction = banaction self.banaction = banaction
self.bancategory = bancategory or category
self.updateperiod = updateperiod self.updateperiod = updateperiod
self._bannedips = set() self._bannedips = set()
@ -85,7 +91,7 @@ class BadIPsAction(ActionBase):
self._timer = None self._timer = None
@classmethod @classmethod
def getCategories(cls): def getCategories(cls, incParents=False):
"""Get badips.com categories. """Get badips.com categories.
Returns Returns
@ -111,6 +117,10 @@ class BadIPsAction(ActionBase):
categories = json.loads(response.read().decode('utf-8'))['categories'] categories = json.loads(response.read().decode('utf-8'))['categories']
categories_names = set( categories_names = set(
value['Name'] for value in categories) value['Name'] for value in categories)
if incParents:
categories_names.update(set(
value['Parent'] for value in categories
if "Parent" in value))
return categories_names return categories_names
@classmethod @classmethod
@ -151,7 +161,7 @@ class BadIPsAction(ActionBase):
@property @property
def category(self): def category(self):
"""badips.com category for fetching/reporting IPs. """badips.com category for reporting IPs.
""" """
return self._category return self._category
@ -164,6 +174,21 @@ class BadIPsAction(ActionBase):
raise ValueError("Invalid category: %s" % category) raise ValueError("Invalid category: %s" % category)
self._category = category self._category = category
@property
def bancategory(self):
"""badips.com bancategory for fetching IPs.
"""
return self._bancategory
@bancategory.setter
def bancategory(self, bancategory):
if bancategory not in self.getCategories(incParents=True):
self._logSys.error("Category name '%s' not valid. "
"see badips.com for list of valid categories",
bancategory)
raise ValueError("Invalid bancategory: %s" % bancategory)
self._bancategory = bancategory
@property @property
def score(self): def score(self):
"""badips.com minimum score for fetching IPs. """badips.com minimum score for fetching IPs.
@ -268,7 +293,7 @@ class BadIPsAction(ActionBase):
self._timer = None self._timer = None
try: try:
ips = self.getList(self.category, self.score, self.age) ips = self.getList(self.bancategory, self.score, self.age)
# Remove old IPs no longer listed # Remove old IPs no longer listed
self._unbanIPs(self._bannedips - ips) self._unbanIPs(self._bannedips - ips)
# Add new IPs which are now listed # Add new IPs which are now listed

View File

@ -61,6 +61,12 @@ class BadIPsActionTest(unittest.TestCase):
self.assertRaises( self.assertRaises(
ValueError, setattr, self.action, "category", "invalid-category") ValueError, setattr, self.action, "category", "invalid-category")
# Not valid for reporting category...
self.assertRaises(
ValueError, setattr, self.action, "category", "mail")
# but valid for blacklisting.
self.action.bancategory = "mail"
def testScore(self): def testScore(self):
self.assertRaises(ValueError, setattr, self.action, "score", -5) self.assertRaises(ValueError, setattr, self.action, "score", -5)
self.action.score = 5 self.action.score = 5