mirror of https://github.com/fail2ban/fail2ban
Update extended status to accept additional argument, flavor
Default to as-in behavior, or flavor=="basic"pull/924/head
parent
dfe4d02f65
commit
486214585e
|
@ -41,9 +41,10 @@ ver. 0.9.2 (2014/XX/XXX) - wanna-be-released
|
||||||
- Monit config for fail2ban in /files/monit
|
- Monit config for fail2ban in /files/monit
|
||||||
- New actions:
|
- New actions:
|
||||||
- action.d/firewallcmd-multiport and action.d/firewallcmd-allports Thanks Donald Yandt
|
- action.d/firewallcmd-multiport and action.d/firewallcmd-allports Thanks Donald Yandt
|
||||||
- New status commands:
|
- New status argument, flavor:
|
||||||
- fail2ban-client status <jail> extended
|
- fail2ban-client status <jail> [flavor]
|
||||||
- prints Cymru data (ASN, Country RIR) per banned IP
|
- empty or "basic" works as-is
|
||||||
|
- "cymru" additionally prints (ASN, Country RIR) per banned IP
|
||||||
- Requires dnspython or dnspython3
|
- Requires dnspython or dnspython3
|
||||||
|
|
||||||
- Enhancements:
|
- Enhancements:
|
||||||
|
|
|
@ -370,21 +370,20 @@ class Actions(JailThread, Mapping):
|
||||||
self._jail.name, name, aInfo, e,
|
self._jail.name, name, aInfo, e,
|
||||||
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
exc_info=logSys.getEffectiveLevel()<=logging.DEBUG)
|
||||||
|
|
||||||
@property
|
def status(self, flavor="basic"):
|
||||||
def status(self):
|
|
||||||
"""Status of current and total ban counts and current banned IP list.
|
"""Status of current and total ban counts and current banned IP list.
|
||||||
"""
|
"""
|
||||||
|
# TODO: Allow this list to be printed as 'status' output
|
||||||
|
supported_flavors = ["basic", "cymru"]
|
||||||
|
if flavor is None or flavor not in supported_flavors:
|
||||||
|
logSys.warning("Unsupported extended jail status flavor %r. Supported: %s" % (flavor, supported_flavors))
|
||||||
|
# Always print this information (basic)
|
||||||
ret = [("Currently banned", self.__banManager.size()),
|
ret = [("Currently banned", self.__banManager.size()),
|
||||||
("Total banned", self.__banManager.getBanTotal()),
|
("Total banned", self.__banManager.getBanTotal()),
|
||||||
("Banned IP list", self.__banManager.getBanList())]
|
("Banned IP list", self.__banManager.getBanList())]
|
||||||
return ret
|
if flavor == "cymru":
|
||||||
|
|
||||||
@property
|
|
||||||
def statusExtended(self):
|
|
||||||
"""Jail status plus banned IPs' ASN, Country and RIR
|
|
||||||
"""
|
|
||||||
cymru_info = self.__banManager.getBanListExtendedCymruInfo()
|
cymru_info = self.__banManager.getBanListExtendedCymruInfo()
|
||||||
ret = self.status +\
|
ret += \
|
||||||
[("Banned ASN list", self.__banManager.geBanListExtendedASN(cymru_info)),
|
[("Banned ASN list", self.__banManager.geBanListExtendedASN(cymru_info)),
|
||||||
("Banned Country list", self.__banManager.geBanListExtendedCountry(cymru_info)),
|
("Banned Country list", self.__banManager.geBanListExtendedCountry(cymru_info)),
|
||||||
("Banned RIR list", self.__banManager.geBanListExtendedRIR(cymru_info))]
|
("Banned RIR list", self.__banManager.geBanListExtendedRIR(cymru_info))]
|
||||||
|
|
|
@ -529,8 +529,7 @@ class Filter(JailThread):
|
||||||
logSys.error(e)
|
logSys.error(e)
|
||||||
return failList
|
return failList
|
||||||
|
|
||||||
@property
|
def status(self, flavor="basic"):
|
||||||
def status(self):
|
|
||||||
"""Status of failures detected by filter.
|
"""Status of failures detected by filter.
|
||||||
"""
|
"""
|
||||||
ret = [("Currently failed", self.failManager.size()),
|
ret = [("Currently failed", self.failManager.size()),
|
||||||
|
@ -686,11 +685,10 @@ class FileFilter(Filter):
|
||||||
db.updateLog(self.jail, container)
|
db.updateLog(self.jail, container)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
def status(self, flavor="basic"):
|
||||||
def status(self):
|
|
||||||
"""Status of Filter plus files being monitored.
|
"""Status of Filter plus files being monitored.
|
||||||
"""
|
"""
|
||||||
ret = super(FileFilter, self).status
|
ret = super(FileFilter, self).status(flavor=flavor)
|
||||||
path = [m.getFileName() for m in self.getLogPath()]
|
path = [m.getFileName() for m in self.getLogPath()]
|
||||||
ret.append(("File list", path))
|
ret.append(("File list", path))
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -259,9 +259,8 @@ class FilterSystemd(JournalFilter): # pragma: systemd no cover
|
||||||
or "jailless") +" filter terminated")
|
or "jailless") +" filter terminated")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
def status(self, flavor="basic"):
|
||||||
def status(self):
|
ret = super(FilterSystemd, self).status(flavor=flavor)
|
||||||
ret = super(FilterSystemd, self).status
|
|
||||||
ret.append(("Journal matches",
|
ret.append(("Journal matches",
|
||||||
[" + ".join(" ".join(match) for match in self.__matches)]))
|
[" + ".join(" ".join(match) for match in self.__matches)]))
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -174,22 +174,12 @@ class Jail:
|
||||||
self.filter.idle = value
|
self.filter.idle = value
|
||||||
self.actions.idle = value
|
self.actions.idle = value
|
||||||
|
|
||||||
@property
|
def status(self, flavor="basic"):
|
||||||
def status(self):
|
|
||||||
"""The status of the jail.
|
"""The status of the jail.
|
||||||
"""
|
"""
|
||||||
return [
|
return [
|
||||||
("Filter", self.filter.status),
|
("Filter", self.filter.status(flavor=flavor)),
|
||||||
("Actions", self.actions.status),
|
("Actions", self.actions.status(flavor=flavor)),
|
||||||
]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def statusExtended(self):
|
|
||||||
"""The extended status of the jail.
|
|
||||||
"""
|
|
||||||
return [
|
|
||||||
("Filter", self.filter.status),
|
|
||||||
("Actions", self.actions.statusExtended),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def putFailTicket(self, ticket):
|
def putFailTicket(self, ticket):
|
||||||
|
|
|
@ -26,7 +26,7 @@ __license__ = "GPL"
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from abc import abstractproperty, abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
from ..helpers import excepthook
|
from ..helpers import excepthook
|
||||||
|
|
||||||
|
@ -66,18 +66,12 @@ class JailThread(Thread):
|
||||||
excepthook(*sys.exc_info())
|
excepthook(*sys.exc_info())
|
||||||
self.run = run_with_except_hook
|
self.run = run_with_except_hook
|
||||||
|
|
||||||
@abstractproperty
|
@abstractmethod
|
||||||
def status(self): # pragma: no cover - abstract
|
def status(self, flavor="basic"): # pragma: no cover - abstract
|
||||||
"""Abstract - Should provide status information.
|
"""Abstract - Should provide status information.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractproperty
|
|
||||||
def statusExtended(self): # pragma: no cover - abstract
|
|
||||||
"""Abstract - Should provide extended status information.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Sets active flag and starts thread.
|
"""Sets active flag and starts thread.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -320,11 +320,8 @@ class Server:
|
||||||
finally:
|
finally:
|
||||||
self.__lock.release()
|
self.__lock.release()
|
||||||
|
|
||||||
def statusJail(self, name):
|
def statusJail(self, name, flavor="basic"):
|
||||||
return self.__jails[name].status
|
return self.__jails[name].status(flavor=flavor)
|
||||||
|
|
||||||
def statusJailExtended(self, name):
|
|
||||||
return self.__jails[name].statusExtended
|
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
|
|
||||||
|
|
|
@ -335,8 +335,6 @@ class Transmitter:
|
||||||
return self.__server.statusJail(name)
|
return self.__server.statusJail(name)
|
||||||
elif len(command) == 2:
|
elif len(command) == 2:
|
||||||
name = command[0]
|
name = command[0]
|
||||||
if command[1] == "extended":
|
flavor = command[1]
|
||||||
return self.__server.statusJailExtended(name)
|
return self.__server.statusJail(name, flavor=flavor)
|
||||||
else:
|
|
||||||
raise Exception("Invalid command (invalid status extension)")
|
|
||||||
raise Exception("Invalid command (no status)")
|
raise Exception("Invalid command (no status)")
|
||||||
|
|
|
@ -474,8 +474,44 @@ class Transmitter(TransmitterBase):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def testJailStatusExtended(self):
|
def testJailStatusBasic(self):
|
||||||
self.assertEqual(self.transm.proceed(["status", self.jailName, "extended"]),
|
self.assertEqual(self.transm.proceed(["status", self.jailName, "basic"]),
|
||||||
|
(0,
|
||||||
|
[
|
||||||
|
('Filter', [
|
||||||
|
('Currently failed', 0),
|
||||||
|
('Total failed', 0),
|
||||||
|
('File list', [])]
|
||||||
|
),
|
||||||
|
('Actions', [
|
||||||
|
('Currently banned', 0),
|
||||||
|
('Total banned', 0),
|
||||||
|
('Banned IP list', [])]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def testJailStatusBasicKwarg(self):
|
||||||
|
self.assertEqual(self.transm.proceed(["status", self.jailName, "INVALID"]),
|
||||||
|
(0,
|
||||||
|
[
|
||||||
|
('Filter', [
|
||||||
|
('Currently failed', 0),
|
||||||
|
('Total failed', 0),
|
||||||
|
('File list', [])]
|
||||||
|
),
|
||||||
|
('Actions', [
|
||||||
|
('Currently banned', 0),
|
||||||
|
('Total banned', 0),
|
||||||
|
('Banned IP list', [])]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
def testJailStatusCymru(self):
|
||||||
|
self.assertEqual(self.transm.proceed(["status", self.jailName, "cymru"]),
|
||||||
(0,
|
(0,
|
||||||
[
|
[
|
||||||
('Filter', [
|
('Filter', [
|
||||||
|
@ -495,6 +531,7 @@ class Transmitter(TransmitterBase):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def testAction(self):
|
def testAction(self):
|
||||||
action = "TestCaseAction"
|
action = "TestCaseAction"
|
||||||
cmdList = [
|
cmdList = [
|
||||||
|
@ -622,10 +659,6 @@ class Transmitter(TransmitterBase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.transm.proceed(["status", "INVALID", "COMMAND"])[0],1)
|
self.transm.proceed(["status", "INVALID", "COMMAND"])[0],1)
|
||||||
|
|
||||||
def testStatusJailExtendedNOK(self):
|
|
||||||
self.assertEqual(
|
|
||||||
self.transm.proceed(["status", self.jailName, "INVALID_COMMAND"])[0],1)
|
|
||||||
|
|
||||||
def testJournalMatch(self):
|
def testJournalMatch(self):
|
||||||
if not filtersystemd: # pragma: no cover
|
if not filtersystemd: # pragma: no cover
|
||||||
if sys.version_info >= (2, 7):
|
if sys.version_info >= (2, 7):
|
||||||
|
|
Loading…
Reference in New Issue