mirror of https://github.com/fail2ban/fail2ban
Merge pull request #2315 from psvi/ban_list
New command `fail2ban-client get <JAIL> banip`pull/2319/merge
commit
53684af0e3
|
@ -56,6 +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
|
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.
|
(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 setup-option `--without-tests` to skip building and installing of tests files (gh-2287).
|
||||||
|
* added new command `fail2ban-client get <JAIL> banip ?sep-char|--with-time?` to get the banned ip addresses (gh-1916).
|
||||||
|
|
||||||
|
|
||||||
ver. 0.10.4-dev-1 (20??/??/??) - development edition
|
ver. 0.10.4-dev-1 (20??/??/??) - development edition
|
||||||
|
|
|
@ -180,6 +180,12 @@ class Beautifier:
|
||||||
msg = "The jail %s action %s has the following " \
|
msg = "The jail %s action %s has the following " \
|
||||||
"methods:\n" % (inC[1], inC[3])
|
"methods:\n" % (inC[1], inC[3])
|
||||||
msg += ", ".join(response)
|
msg += ", ".join(response)
|
||||||
|
elif inC[2] == "banip" and inC[0] == "get":
|
||||||
|
if isinstance(response, list):
|
||||||
|
sep = " " if len(inC) <= 3 else inC[3]
|
||||||
|
if sep == "--with-time":
|
||||||
|
sep = "\n"
|
||||||
|
msg = sep.join(response)
|
||||||
except Exception:
|
except Exception:
|
||||||
logSys.warning("Beautifier error. Please report the error")
|
logSys.warning("Beautifier error. Please report the error")
|
||||||
logSys.error("Beautify %r with %r failed", response, self.__inputCmd,
|
logSys.error("Beautify %r with %r failed", response, self.__inputCmd,
|
||||||
|
|
|
@ -128,6 +128,7 @@ protocol = [
|
||||||
["get <JAIL> bantime", "gets the time a host is banned for <JAIL>"],
|
["get <JAIL> bantime", "gets the time a host is banned for <JAIL>"],
|
||||||
["get <JAIL> datepattern", "gets the patern used to match date/times for <JAIL>"],
|
["get <JAIL> datepattern", "gets the patern used to match date/times for <JAIL>"],
|
||||||
["get <JAIL> usedns", "gets the usedns setting for <JAIL>"],
|
["get <JAIL> usedns", "gets the usedns setting for <JAIL>"],
|
||||||
|
["get <JAIL> banip [<SEP>|--with-time]", "gets the list of of banned IP addresses for <JAIL>. Optionally the separator character ('<SEP>', default is space) or the option '--with-time' (printing the times of ban) may be specified. The IPs are ordered by end of ban."],
|
||||||
["get <JAIL> maxretry", "gets the number of failures allowed for <JAIL>"],
|
["get <JAIL> maxretry", "gets the number of failures allowed for <JAIL>"],
|
||||||
["get <JAIL> maxlines", "gets the number of lines to buffer for <JAIL>"],
|
["get <JAIL> maxlines", "gets the number of lines to buffer for <JAIL>"],
|
||||||
["get <JAIL> actions", "gets a list of actions for <JAIL>"],
|
["get <JAIL> actions", "gets a list of actions for <JAIL>"],
|
||||||
|
|
|
@ -204,6 +204,16 @@ class Actions(JailThread, Mapping):
|
||||||
def getBanTime(self):
|
def getBanTime(self):
|
||||||
return self.__banManager.getBanTime()
|
return self.__banManager.getBanTime()
|
||||||
|
|
||||||
|
def getBanList(self, withTime=False):
|
||||||
|
"""Returns the list of banned IP addresses.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
list
|
||||||
|
The list of banned IP addresses.
|
||||||
|
"""
|
||||||
|
return self.__banManager.getBanList(ordered=True, withTime=withTime)
|
||||||
|
|
||||||
def removeBannedIP(self, ip=None, db=True, ifexists=False):
|
def removeBannedIP(self, ip=None, db=True, ifexists=False):
|
||||||
"""Removes banned IP calling actions' unban method
|
"""Removes banned IP calling actions' unban method
|
||||||
|
|
||||||
|
|
|
@ -102,9 +102,22 @@ class BanManager:
|
||||||
#
|
#
|
||||||
# @return IP list
|
# @return IP list
|
||||||
|
|
||||||
def getBanList(self):
|
def getBanList(self, ordered=False, withTime=False):
|
||||||
with self.__lock:
|
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).
|
# Returns a iterator to ban list (used in reload, so idle).
|
||||||
|
|
|
@ -602,7 +602,7 @@ class Filter(JailThread):
|
||||||
if self._inIgnoreIPList(ip, tick):
|
if self._inIgnoreIPList(ip, tick):
|
||||||
continue
|
continue
|
||||||
logSys.info(
|
logSys.info(
|
||||||
"[%s] Found %s - %s", self.jailName, ip, datetime.datetime.fromtimestamp(unixTime).strftime("%Y-%m-%d %H:%M:%S")
|
"[%s] Found %s - %s", self.jailName, ip, MyTime.time2str(unixTime)
|
||||||
)
|
)
|
||||||
self.failManager.addFailure(tick)
|
self.failManager.addFailure(tick)
|
||||||
# report to observer - failure was found, for possibly increasing of it retry counter (asynchronous)
|
# report to observer - failure was found, for possibly increasing of it retry counter (asynchronous)
|
||||||
|
@ -1092,7 +1092,7 @@ class FileFilter(Filter):
|
||||||
fs = container.getFileSize()
|
fs = container.getFileSize()
|
||||||
if logSys.getEffectiveLevel() <= logging.DEBUG:
|
if logSys.getEffectiveLevel() <= logging.DEBUG:
|
||||||
logSys.debug("Seek to find time %s (%s), file size %s", date,
|
logSys.debug("Seek to find time %s (%s), file size %s", date,
|
||||||
datetime.datetime.fromtimestamp(date).strftime("%Y-%m-%d %H:%M:%S"), fs)
|
MyTime.time2str(date), fs)
|
||||||
minp = container.getPos()
|
minp = container.getPos()
|
||||||
maxp = fs
|
maxp = fs
|
||||||
tryPos = minp
|
tryPos = minp
|
||||||
|
@ -1171,7 +1171,7 @@ class FileFilter(Filter):
|
||||||
container.setPos(foundPos)
|
container.setPos(foundPos)
|
||||||
if logSys.getEffectiveLevel() <= logging.DEBUG:
|
if logSys.getEffectiveLevel() <= logging.DEBUG:
|
||||||
logSys.debug("Position %s from %s, found time %s (%s) within %s seeks", lastPos, fs, foundTime,
|
logSys.debug("Position %s from %s, found time %s (%s) within %s seeks", lastPos, fs, foundTime,
|
||||||
(datetime.datetime.fromtimestamp(foundTime).strftime("%Y-%m-%d %H:%M:%S") if foundTime is not None else ''), cntr)
|
(MyTime.time2str(foundTime) if foundTime is not None else ''), cntr)
|
||||||
|
|
||||||
def status(self, flavor="basic"):
|
def status(self, flavor="basic"):
|
||||||
"""Status of Filter plus files being monitored.
|
"""Status of Filter plus files being monitored.
|
||||||
|
|
|
@ -114,6 +114,16 @@ class MyTime:
|
||||||
else:
|
else:
|
||||||
return time.localtime(MyTime.myTime)
|
return time.localtime(MyTime.myTime)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def time2str(unixTime, format="%Y-%m-%d %H:%M:%S"):
|
||||||
|
"""Convert time to a string representing as date and time using given format.
|
||||||
|
Default format is ISO 8601, 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(format)
|
||||||
|
|
||||||
## precreate/precompile primitives used in str2seconds:
|
## precreate/precompile primitives used in str2seconds:
|
||||||
|
|
||||||
## preparing expression:
|
## preparing expression:
|
||||||
|
|
|
@ -393,7 +393,7 @@ class ObserverThread(JailThread):
|
||||||
return
|
return
|
||||||
# retry counter was increased - add it again:
|
# retry counter was increased - add it again:
|
||||||
logSys.info("[%s] Found %s, bad - %s, %s # -> %s%s", jail.name, ip,
|
logSys.info("[%s] Found %s, bad - %s, %s # -> %s%s", jail.name, ip,
|
||||||
datetime.datetime.fromtimestamp(unixTime).strftime("%Y-%m-%d %H:%M:%S"), banCount, retryCount,
|
MyTime.time2str(unixTime), banCount, retryCount,
|
||||||
(', Ban' if retryCount >= maxRetry else ''))
|
(', Ban' if retryCount >= maxRetry else ''))
|
||||||
# retryCount-1, because a ticket was already once incremented by filter self
|
# retryCount-1, because a ticket was already once incremented by filter self
|
||||||
retryCount = failManager.addFailure(ticket, retryCount - 1, True)
|
retryCount = failManager.addFailure(ticket, retryCount - 1, True)
|
||||||
|
@ -454,7 +454,7 @@ class ObserverThread(JailThread):
|
||||||
# check current ticket time to prevent increasing for twice read tickets (restored from log file besides database after restart)
|
# check current ticket time to prevent increasing for twice read tickets (restored from log file besides database after restart)
|
||||||
if ticket.getTime() > timeOfBan:
|
if ticket.getTime() > timeOfBan:
|
||||||
logSys.info('[%s] IP %s is bad: %s # last %s - incr %s to %s' % (jail.name, ip, banCount,
|
logSys.info('[%s] IP %s is bad: %s # last %s - incr %s to %s' % (jail.name, ip, banCount,
|
||||||
datetime.datetime.fromtimestamp(timeOfBan).strftime("%Y-%m-%d %H:%M:%S"),
|
MyTime.time2str(timeOfBan),
|
||||||
datetime.timedelta(seconds=int(orgBanTime)), datetime.timedelta(seconds=int(banTime))));
|
datetime.timedelta(seconds=int(orgBanTime)), datetime.timedelta(seconds=int(banTime))));
|
||||||
else:
|
else:
|
||||||
ticket.restored = True
|
ticket.restored = True
|
||||||
|
@ -485,7 +485,7 @@ class ObserverThread(JailThread):
|
||||||
if btime != -1:
|
if btime != -1:
|
||||||
bendtime = ticket.getTime() + btime
|
bendtime = ticket.getTime() + btime
|
||||||
logtime = (datetime.timedelta(seconds=int(btime)),
|
logtime = (datetime.timedelta(seconds=int(btime)),
|
||||||
datetime.datetime.fromtimestamp(bendtime).strftime("%Y-%m-%d %H:%M:%S"))
|
MyTime.time2str(bendtime))
|
||||||
# check ban is not too old :
|
# check ban is not too old :
|
||||||
if bendtime < MyTime.time():
|
if bendtime < MyTime.time():
|
||||||
logSys.debug('Ignore old bantime %s', logtime[1])
|
logSys.debug('Ignore old bantime %s', logtime[1])
|
||||||
|
|
|
@ -510,6 +510,21 @@ class Server:
|
||||||
def getBanTime(self, name):
|
def getBanTime(self, name):
|
||||||
return self.__jails[name].actions.getBanTime()
|
return self.__jails[name].actions.getBanTime()
|
||||||
|
|
||||||
|
def getBanList(self, name, withTime=False):
|
||||||
|
"""Returns the list of banned IP addresses for a jail.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
name : str
|
||||||
|
The name of a jail.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
list
|
||||||
|
The list of banned IP addresses.
|
||||||
|
"""
|
||||||
|
return self.__jails[name].actions.getBanList(withTime)
|
||||||
|
|
||||||
def setBanTimeExtra(self, name, opt, value):
|
def setBanTimeExtra(self, name, opt, value):
|
||||||
self.__jails[name].setBanTimeExtra(opt, value)
|
self.__jails[name].setBanTimeExtra(opt, value)
|
||||||
|
|
||||||
|
|
|
@ -390,6 +390,9 @@ class Transmitter:
|
||||||
# Action
|
# Action
|
||||||
elif command[1] == "bantime":
|
elif command[1] == "bantime":
|
||||||
return self.__server.getBanTime(name)
|
return self.__server.getBanTime(name)
|
||||||
|
elif command[1] == "banip":
|
||||||
|
return self.__server.getBanList(name,
|
||||||
|
withTime=len(command) > 2 and command[2] == "--with-time")
|
||||||
elif command[1].startswith("bantime."):
|
elif command[1].startswith("bantime."):
|
||||||
opt = command[1][len("bantime."):]
|
opt = command[1][len("bantime."):]
|
||||||
return self.__server.getBanTimeExtra(name, opt)
|
return self.__server.getBanTimeExtra(name, opt)
|
||||||
|
|
|
@ -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",
|
||||||
"stdout: '[test-jail2] test-action3: ++ ban 192.0.2.22 ", all=True, wait=MID_WAITTIME)
|
"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:
|
# restart jail with unban all:
|
||||||
self.pruneLog("[test-phase 2e]")
|
self.pruneLog("[test-phase 2e]")
|
||||||
self.execCmd(SUCCESS, startparams,
|
self.execCmd(SUCCESS, startparams,
|
||||||
|
@ -1397,6 +1408,11 @@ class Fail2banServerTest(Fail2banClientServerBase):
|
||||||
"stdout: '[test-jail1] test-action1: ++ ban 192.0.2.11 -c 2 -t 300 : ",
|
"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 : ",
|
"stdout: '[test-jail1] test-action2: ++ ban 192.0.2.11 -c 2 -t 300 : ",
|
||||||
all=True, wait=MID_WAITTIME)
|
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:
|
# unblock observer here and wait it is done:
|
||||||
wakeObs = True
|
wakeObs = True
|
||||||
_observer_wait_idle()
|
_observer_wait_idle()
|
||||||
|
@ -1411,6 +1427,13 @@ class Fail2banServerTest(Fail2banClientServerBase):
|
||||||
"stdout: '[test-jail1] test-action2: ++ prolong 192.0.2.11 -c 2 -t 600 : ",
|
"stdout: '[test-jail1] test-action2: ++ prolong 192.0.2.11 -c 2 -t 600 : ",
|
||||||
all=True, wait=MID_WAITTIME)
|
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) --
|
# test multiple start/stop of the server (threaded in foreground) --
|
||||||
if False: # pragma: no cover
|
if False: # pragma: no cover
|
||||||
@with_foreground_server_thread()
|
@with_foreground_server_thread()
|
||||||
|
|
|
@ -94,7 +94,7 @@ class _tmSerial():
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _tm(time):
|
def _tm(time):
|
||||||
# ## strftime it too slow for large time serializer :
|
# ## strftime it too slow for large time serializer :
|
||||||
# return datetime.datetime.fromtimestamp(time).strftime("%Y-%m-%d %H:%M:%S")
|
# return MyTime.time2str(time)
|
||||||
c = _tmSerial
|
c = _tmSerial
|
||||||
sec = (time % 60)
|
sec = (time % 60)
|
||||||
if c._last_s == time - sec:
|
if c._last_s == time - sec:
|
||||||
|
@ -306,7 +306,7 @@ class BasicFilter(unittest.TestCase):
|
||||||
unittest.F2B.SkipIfFast()
|
unittest.F2B.SkipIfFast()
|
||||||
## test function "_tm" works correct (returns the same as slow strftime):
|
## test function "_tm" works correct (returns the same as slow strftime):
|
||||||
for i in xrange(1417512352, (1417512352 // 3600 + 3) * 3600):
|
for i in xrange(1417512352, (1417512352 // 3600 + 3) * 3600):
|
||||||
tm = datetime.datetime.fromtimestamp(i).strftime("%Y-%m-%d %H:%M:%S")
|
tm = MyTime.time2str(i)
|
||||||
if _tm(i) != tm: # pragma: no cover - never reachable
|
if _tm(i) != tm: # pragma: no cover - never reachable
|
||||||
self.assertEqual((_tm(i), i), (tm, i))
|
self.assertEqual((_tm(i), i), (tm, i))
|
||||||
|
|
||||||
|
|
|
@ -347,6 +347,46 @@ class Transmitter(TransmitterBase):
|
||||||
self.transm.proceed(
|
self.transm.proceed(
|
||||||
["set", self.jailName, "unbanip", "192.168.1.1"])[0],1)
|
["set", self.jailName, "unbanip", "192.168.1.1"])[0],1)
|
||||||
|
|
||||||
|
def testJailBanList(self):
|
||||||
|
jail = "TestJailBanList"
|
||||||
|
self.server.addJail(jail, FAST_BACKEND)
|
||||||
|
self.server.startJail(jail)
|
||||||
|
|
||||||
|
# Helper to process set banip/set unbanip commands and compare the list of
|
||||||
|
# banned IP addresses with outList.
|
||||||
|
def _getBanListTest(jail, banip=None, unbanip=None, outList=[]):
|
||||||
|
# Ban IP address
|
||||||
|
if banip is not None:
|
||||||
|
self.assertEqual(
|
||||||
|
self.transm.proceed(["set", jail, "banip", banip]),
|
||||||
|
(0, banip))
|
||||||
|
self.assertLogged("Ban %s" % banip, wait=True) # Give chance to ban
|
||||||
|
# Unban IP address
|
||||||
|
if unbanip is not None:
|
||||||
|
self.assertEqual(
|
||||||
|
self.transm.proceed(["set", jail, "unbanip", unbanip]),
|
||||||
|
(0, unbanip))
|
||||||
|
self.assertLogged("Unban %s" % unbanip, wait=True) # Give chance to unban
|
||||||
|
# Compare the list of banned IP addresses with outList
|
||||||
|
self.assertSortedEqual(
|
||||||
|
self.transm.proceed(["get", jail, "banip"]),
|
||||||
|
(0, outList))
|
||||||
|
|
||||||
|
_getBanListTest(jail,
|
||||||
|
outList=[])
|
||||||
|
_getBanListTest(jail, banip="127.0.0.1",
|
||||||
|
outList=["127.0.0.1"])
|
||||||
|
_getBanListTest(jail, banip="192.168.0.1",
|
||||||
|
outList=["127.0.0.1", "192.168.0.1"])
|
||||||
|
_getBanListTest(jail, banip="192.168.1.10",
|
||||||
|
outList=["127.0.0.1", "192.168.0.1", "192.168.1.10"])
|
||||||
|
_getBanListTest(jail, unbanip="127.0.0.1",
|
||||||
|
outList=["192.168.0.1", "192.168.1.10"])
|
||||||
|
_getBanListTest(jail, unbanip="192.168.1.10",
|
||||||
|
outList=["192.168.0.1"])
|
||||||
|
_getBanListTest(jail, unbanip="192.168.0.1",
|
||||||
|
outList=[])
|
||||||
|
|
||||||
def testJailMaxRetry(self):
|
def testJailMaxRetry(self):
|
||||||
self.setGetTest("maxretry", "5", 5, jail=self.jailName)
|
self.setGetTest("maxretry", "5", 5, jail=self.jailName)
|
||||||
self.setGetTest("maxretry", "2", 2, jail=self.jailName)
|
self.setGetTest("maxretry", "2", 2, jail=self.jailName)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
|
||||||
.TH FAIL2BAN-CLIENT "1" "October 2018" "fail2ban-client v0.11.0.dev3" "User Commands"
|
.TH FAIL2BAN-CLIENT "1" "January 2019" "fail2ban-client v0.11.0.dev3" "User Commands"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
fail2ban-client \- configure and control the server
|
fail2ban-client \- configure and control the server
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
@ -386,6 +386,15 @@ date/times for <JAIL>
|
||||||
\fBget <JAIL> usedns\fR
|
\fBget <JAIL> usedns\fR
|
||||||
gets the usedns setting for <JAIL>
|
gets the usedns setting for <JAIL>
|
||||||
.TP
|
.TP
|
||||||
|
\fBget <JAIL> banip [<SEP>|\-\-with\-time]\fR
|
||||||
|
gets the list of of banned IP
|
||||||
|
addresses for <JAIL>. Optionally
|
||||||
|
the separator character ('<SEP>',
|
||||||
|
default is space) or the option
|
||||||
|
\&'\-\-with\-time' (printing the times
|
||||||
|
of ban) may be specified. The IPs
|
||||||
|
are ordered by end of ban.
|
||||||
|
.TP
|
||||||
\fBget <JAIL> maxretry\fR
|
\fBget <JAIL> maxretry\fR
|
||||||
gets the number of failures
|
gets the number of failures
|
||||||
allowed for <JAIL>
|
allowed for <JAIL>
|
||||||
|
|
Loading…
Reference in New Issue