mirror of https://github.com/fail2ban/fail2ban
ip-list is sorted now (by end of ban) per default;
extended with new option `--with-time` to provide more pretty and informative result (separated by new-line, including time strings: time of ban + ban-time = end of ban): 192.0.2.1 2019-01-06 22:24:48 + 300 = 2019-01-06 22:29:48 192.0.2.2 2019-01-06 22:24:48 + 600 = 2019-01-06 22:34:48 also it is possible now to provide separator-character as extra-parameter after `get <jail> banip ?sep-char?` (default is space). removed unneeded test-cases (test code-base minimization) and unexpected manually changed files.pull/2315/head
parent
7f5f7017db
commit
df97fd33cf
|
@ -56,7 +56,7 @@ ver. 0.11.0-dev-0 (20??/??/??) - development nightly edition
|
|||
end of ban) of the ticket with ban-time of jail (as maximum), for all tickets with ban-time greater
|
||||
(or persistent); not affected if ban-time of the jail is unchanged between stop/start.
|
||||
* added new setup-option `--without-tests` to skip building and installing of tests files (gh-2287).
|
||||
* added new command `fail2ban-client get <JAIL> banip` to get the banned ip addresses (gh-1916).
|
||||
* added new command `fail2ban-client get <JAIL> banip ?--with-time|sep-char?` to get the banned ip addresses (gh-1916).
|
||||
|
||||
|
||||
ver. 0.10.4-dev-1 (20??/??/??) - development edition
|
||||
|
|
|
@ -181,7 +181,11 @@ class Beautifier:
|
|||
"methods:\n" % (inC[1], inC[3])
|
||||
msg += ", ".join(response)
|
||||
elif inC[2] == "banip" and inC[0] == "get":
|
||||
msg = " ".join(response)
|
||||
if isinstance(response, list):
|
||||
sep = " " if len(inC) <= 3 else inC[3]
|
||||
if sep == "--with-time":
|
||||
sep = "\n"
|
||||
msg = sep.join(response)
|
||||
except Exception:
|
||||
logSys.warning("Beautifier error. Please report the error")
|
||||
logSys.error("Beautify %r with %r failed", response, self.__inputCmd,
|
||||
|
|
|
@ -204,7 +204,7 @@ class Actions(JailThread, Mapping):
|
|||
def getBanTime(self):
|
||||
return self.__banManager.getBanTime()
|
||||
|
||||
def getBanList(self):
|
||||
def getBanList(self, withTime=False):
|
||||
"""Returns the list of banned IP addresses.
|
||||
|
||||
Returns
|
||||
|
@ -212,7 +212,7 @@ class Actions(JailThread, Mapping):
|
|||
list
|
||||
The list of banned IP addresses.
|
||||
"""
|
||||
return self.__banManager.getBanList()
|
||||
return self.__banManager.getBanList(ordered=True, withTime=withTime)
|
||||
|
||||
def removeBannedIP(self, ip=None, db=True, ifexists=False):
|
||||
"""Removes banned IP calling actions' unban method
|
||||
|
|
|
@ -102,9 +102,22 @@ class BanManager:
|
|||
#
|
||||
# @return IP list
|
||||
|
||||
def getBanList(self):
|
||||
def getBanList(self, ordered=False, withTime=False):
|
||||
with self.__lock:
|
||||
return self.__banList.keys()
|
||||
if not ordered:
|
||||
return self.__banList.keys()
|
||||
lst = []
|
||||
for ticket in self.__banList.itervalues():
|
||||
eob = ticket.getEndOfBanTime(self.__banTime)
|
||||
lst.append((ticket,eob))
|
||||
lst.sort(key=lambda t: t[1])
|
||||
t2s = MyTime.time2str
|
||||
if withTime:
|
||||
return ['%s \t%s + %d = %s' % (
|
||||
t[0].getID(),
|
||||
t2s(t[0].getTime()), t[0].getBanTime(self.__banTime), t2s(t[1])
|
||||
) for t in lst]
|
||||
return [t[0].getID() for t in lst]
|
||||
|
||||
##
|
||||
# Returns a iterator to ban list (used in reload, so idle).
|
||||
|
|
|
@ -113,6 +113,16 @@ class MyTime:
|
|||
return time.localtime(x)
|
||||
else:
|
||||
return time.localtime(MyTime.myTime)
|
||||
|
||||
@staticmethod
|
||||
def time2str(unixTime):
|
||||
"""Convert time to a string representing as date and time in ISO 8601
|
||||
format, YYYY-MM-DD HH:MM:SS without microseconds.
|
||||
|
||||
@return ISO-capable string representation of given unixTime
|
||||
"""
|
||||
return datetime.datetime.fromtimestamp(
|
||||
unixTime).replace(microsecond=0).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
## precreate/precompile primitives used in str2seconds:
|
||||
|
||||
|
|
|
@ -510,7 +510,7 @@ class Server:
|
|||
def getBanTime(self, name):
|
||||
return self.__jails[name].actions.getBanTime()
|
||||
|
||||
def getBanList(self, name):
|
||||
def getBanList(self, name, withTime=False):
|
||||
"""Returns the list of banned IP addresses for a jail.
|
||||
|
||||
Parameters
|
||||
|
@ -523,7 +523,7 @@ class Server:
|
|||
list
|
||||
The list of banned IP addresses.
|
||||
"""
|
||||
return self.__jails[name].actions.getBanList()
|
||||
return self.__jails[name].actions.getBanList(withTime)
|
||||
|
||||
def setBanTimeExtra(self, name, opt, value):
|
||||
self.__jails[name].setBanTimeExtra(opt, value)
|
||||
|
|
|
@ -391,7 +391,8 @@ class Transmitter:
|
|||
elif command[1] == "bantime":
|
||||
return self.__server.getBanTime(name)
|
||||
elif command[1] == "banip":
|
||||
return self.__server.getBanList(name)
|
||||
return self.__server.getBanList(name,
|
||||
withTime=len(command) > 2 and command[2] == "--with-time")
|
||||
elif command[1].startswith("bantime."):
|
||||
opt = command[1][len("bantime."):]
|
||||
return self.__server.getBanTimeExtra(name, opt)
|
||||
|
|
|
@ -261,10 +261,3 @@ class BeautifierTest(unittest.TestCase):
|
|||
|
||||
output = "Sorry but the command is invalid"
|
||||
self.assertEqual(self.b.beautifyError(IndexError()), output)
|
||||
|
||||
def testJailBanList(self):
|
||||
self.b.setInputCmd(["get", "ssh", "banip"])
|
||||
response = ["192.168.0.1", "192.168.1.10"]
|
||||
output = "192.168.0.1 192.168.1.10"
|
||||
self.assertEqual(self.b.beautify(response), output)
|
||||
self.assertEqual(self.b.beautify([]), "")
|
||||
|
|
|
@ -1064,6 +1064,17 @@ class Fail2banServerTest(Fail2banClientServerBase):
|
|||
"stdout: '[test-jail2] test-action3: ++ ban 192.0.2.22",
|
||||
"stdout: '[test-jail2] test-action3: ++ ban 192.0.2.22 ", all=True, wait=MID_WAITTIME)
|
||||
|
||||
# get banned ips:
|
||||
_observer_wait_idle()
|
||||
self.pruneLog("[test-phase 2d.1]")
|
||||
self.execCmd(SUCCESS, startparams, "get", "test-jail2", "banip", "\n")
|
||||
self.assertLogged(
|
||||
"192.0.2.4", "192.0.2.8", "192.0.2.21", "192.0.2.22", all=True, wait=MID_WAITTIME)
|
||||
self.pruneLog("[test-phase 2d.2]")
|
||||
self.execCmd(SUCCESS, startparams, "get", "test-jail1", "banip")
|
||||
self.assertLogged(
|
||||
"192.0.2.1", "192.0.2.2", "192.0.2.3", "192.0.2.4", "192.0.2.8", all=True, wait=MID_WAITTIME)
|
||||
|
||||
# restart jail with unban all:
|
||||
self.pruneLog("[test-phase 2e]")
|
||||
self.execCmd(SUCCESS, startparams,
|
||||
|
@ -1227,36 +1238,6 @@ class Fail2banServerTest(Fail2banClientServerBase):
|
|||
"Jail 'test-jail1' stopped",
|
||||
"Jail 'test-jail1' started", all=True, wait=MID_WAITTIME)
|
||||
|
||||
# test the list of banned IP addresses, step 0: prepare
|
||||
self.pruneLog("[test-phase 9a]")
|
||||
self.execCmd(SUCCESS, startparams, "reload", "--unban", "test-jail1")
|
||||
self.assertLogged(
|
||||
"Jail 'test-jail1' reloaded", wait=MID_WAITTIME)
|
||||
# test the list of banned IP addresses, step 1: ban IP addresses
|
||||
self.pruneLog("[test-phase 9b]")
|
||||
self.execCmd(SUCCESS, startparams,
|
||||
"set", "test-jail1", "banip", "192.168.0.1")
|
||||
self.assertLogged("[test-jail1] Ban 192.168.0.1", wait=MID_WAITTIME)
|
||||
self.execCmd(SUCCESS, startparams,
|
||||
"set", "test-jail1", "banip", "192.168.1.10")
|
||||
self.assertLogged("[test-jail1] Ban 192.168.1.10", wait=MID_WAITTIME)
|
||||
self.execCmd(SUCCESS, startparams, "get", "test-jail1", "banip")
|
||||
self.assertLogged(
|
||||
"192.168.1.10 192.168.0.1",
|
||||
"192.168.0.1 192.168.1.10", wait=MID_WAITTIME)
|
||||
# test the list of banned IP addresses, step 2: unban IP addresses
|
||||
self.pruneLog("[test-phase 9c]")
|
||||
self.execCmd(SUCCESS, startparams,
|
||||
"set", "test-jail1", "unbanip", "192.168.0.1")
|
||||
self.assertLogged("[test-jail1] Unban 192.168.0.1", wait=MID_WAITTIME)
|
||||
self.execCmd(SUCCESS, startparams,
|
||||
"set", "test-jail1", "unbanip", "192.168.1.10")
|
||||
self.assertLogged("[test-jail1] Unban 192.168.1.10", wait=MID_WAITTIME)
|
||||
self.execCmd(SUCCESS, startparams, "get", "test-jail1", "banip")
|
||||
self.assertNotLogged(
|
||||
"192.168.1.10 192.168.0.1",
|
||||
"192.168.0.1 192.168.1.10", wait=MID_WAITTIME)
|
||||
|
||||
# test action.d/nginx-block-map.conf --
|
||||
@unittest.F2B.skip_if_cfg_missing(action="nginx-block-map")
|
||||
@with_foreground_server_thread(startextra={
|
||||
|
@ -1427,6 +1408,11 @@ class Fail2banServerTest(Fail2banClientServerBase):
|
|||
"stdout: '[test-jail1] test-action1: ++ ban 192.0.2.11 -c 2 -t 300 : ",
|
||||
"stdout: '[test-jail1] test-action2: ++ ban 192.0.2.11 -c 2 -t 300 : ",
|
||||
all=True, wait=MID_WAITTIME)
|
||||
# get banned ips with time:
|
||||
self.pruneLog("[test-phase 2) time+10m - get-ips]")
|
||||
self.execCmd(SUCCESS, startparams, "get", "test-jail1", "banip", "--with-time")
|
||||
self.assertLogged(
|
||||
"192.0.2.11", "+ 300 =", all=True, wait=MID_WAITTIME)
|
||||
# unblock observer here and wait it is done:
|
||||
wakeObs = True
|
||||
_observer_wait_idle()
|
||||
|
@ -1441,6 +1427,13 @@ class Fail2banServerTest(Fail2banClientServerBase):
|
|||
"stdout: '[test-jail1] test-action2: ++ prolong 192.0.2.11 -c 2 -t 600 : ",
|
||||
all=True, wait=MID_WAITTIME)
|
||||
|
||||
# get banned ips with time:
|
||||
_observer_wait_idle()
|
||||
self.pruneLog("[test-phase 2) time+11m - get-ips]")
|
||||
self.execCmd(SUCCESS, startparams, "get", "test-jail1", "banip", "--with-time")
|
||||
self.assertLogged(
|
||||
"192.0.2.11", "+ 600 =", all=True, wait=MID_WAITTIME)
|
||||
|
||||
# test multiple start/stop of the server (threaded in foreground) --
|
||||
if False: # pragma: no cover
|
||||
@with_foreground_server_thread()
|
||||
|
|
|
@ -379,10 +379,6 @@ will look back for failures for
|
|||
gets the time a host is banned for
|
||||
<JAIL>
|
||||
.TP
|
||||
\fBget <JAIL> banip\fR
|
||||
gets the list of banned IP
|
||||
addresses for <JAIL>
|
||||
.TP
|
||||
\fBget <JAIL> datepattern\fR
|
||||
gets the patern used to match
|
||||
date/times for <JAIL>
|
||||
|
|
Loading…
Reference in New Issue