Browse Source

implemented `fail2ban-client status --all [flavor]`

closes #2975
pull/3641/merge
sebres 7 months ago
parent
commit
bdba42edd9
  1. 26
      fail2ban/client/beautifier.py
  2. 1
      fail2ban/protocol.py
  3. 16
      fail2ban/server/server.py
  4. 9
      fail2ban/server/transmitter.py
  5. 67
      fail2ban/tests/clientbeautifiertestcase.py
  6. 62
      fail2ban/tests/servertestcase.py

26
fail2ban/client/beautifier.py

@ -71,23 +71,37 @@ class Beautifier:
elif inC[0] == "echo":
msg = ' '.join(msg)
elif inC[0:1] == ['status']:
if len(inC) > 1:
# Display information
msg = ["Status for the jail: %s" % inC[1]]
def jail_stat(response, pref=""):
# Display jail information
for n, res1 in enumerate(response):
prefix1 = "`-" if n == len(response) - 1 else "|-"
prefix1 = pref + ("`-" if n == len(response) - 1 else "|-")
msg.append("%s %s" % (prefix1, res1[0]))
prefix1 = " " if n == len(response) - 1 else "| "
prefix1 = pref + (" " if n == len(response) - 1 else "| ")
for m, res2 in enumerate(res1[1]):
prefix2 = prefix1 + ("`-" if m == len(res1[1]) - 1 else "|-")
val = " ".join(map(str, res2[1])) if isinstance(res2[1], list) else res2[1]
msg.append("%s %s:\t%s" % (prefix2, res2[0], val))
if len(inC) > 1 and inC[1] != "--all":
msg = ["Status for the jail: %s" % inC[1]]
jail_stat(response)
else:
jstat = None
if len(inC) > 1: # --all
jstat = response[-1]
response = response[:-1]
msg = ["Status"]
for n, res1 in enumerate(response):
prefix1 = "`-" if n == len(response) - 1 else "|-"
prefix1 = "`-" if not jstat and n == len(response) - 1 else "|-"
val = " ".join(map(str, res1[1])) if isinstance(res1[1], list) else res1[1]
msg.append("%s %s:\t%s" % (prefix1, res1[0], val))
if jstat:
msg.append("`- Status for the jails:")
i = 0
for n, j in jstat.items():
i += 1
prefix1 = "`-" if i == len(jstat) else "|-"
msg.append(" %s Jail: %s" % (prefix1, n))
jail_stat(j, " " if i == len(jstat) else " | ")
msg = "\n".join(msg)
elif len(inC) < 2:
pass # to few cmd args for below

1
fail2ban/protocol.py

@ -58,6 +58,7 @@ protocol = [
["banned", "return jails with banned IPs as dictionary"],
["banned <IP> ... <IP>]", "return list(s) of jails where given IP(s) are banned"],
["status", "gets the current status of the server"],
["status --all [FLAVOR]", "gets the current status of all jails, with optional flavor or extended info"],
["ping", "tests if the server is alive"],
["echo", "for internal usage, returns back and outputs a given string"],
["help", "return this output"],

16
fail2ban/server/server.py

@ -604,14 +604,18 @@ class Server:
return 1
# Status
def status(self):
def status(self, name="", flavor="basic"):
try:
self.__lock.acquire()
jails = list(self.__jails)
jails.sort()
jailList = ", ".join(jails)
ret = [("Number of jail", len(self.__jails)),
("Jail list", jailList)]
jails = sorted(self.__jails.items())
jailList = [n for n, j in jails]
ret = [("Number of jail", len(jailList)),
("Jail list", ", ".join(jailList))]
if name == '--all':
jstat = dict(jails)
for n, j in jails:
jstat[n] = j.status(flavor=flavor)
ret.append(jstat)
return ret
finally:
self.__lock.release()

9
fail2ban/server/transmitter.py

@ -512,11 +512,10 @@ class Transmitter:
def status(self, command):
if len(command) == 0:
return self.__server.status()
elif len(command) == 1:
elif len(command) >= 1 and len(command) <= 2:
name = command[0]
return self.__server.statusJail(name)
elif len(command) == 2:
name = command[0]
flavor = command[1]
flavor = command[1] if len(command) == 2 else "basic"
if name == "--all":
return self.__server.status("--all", flavor)
return self.__server.statusJail(name, flavor=flavor)
raise Exception("Invalid command (no status)")

67
fail2ban/tests/clientbeautifiertestcase.py

@ -70,8 +70,8 @@ class BeautifierTest(unittest.TestCase):
def testStatus(self):
self.b.setInputCmd(["status"])
response = (("Number of jails", 0), ("Jail list", ["ssh", "exim4"]))
output = "Status\n|- Number of jails:\t0\n`- Jail list:\tssh exim4"
response = (("Number of jails", 2), ("Jail list", ", ".join(["ssh", "exim4"])))
output = "Status\n|- Number of jails:\t2\n`- Jail list:\tssh, exim4"
self.assertEqual(self.b.beautify(response), output)
self.b.setInputCmd(["status", "ssh"])
@ -105,6 +105,69 @@ class BeautifierTest(unittest.TestCase):
output += " `- Banned IP list: 192.168.0.1 10.2.2.1 2001:db8::1"
self.assertEqual(self.b.beautify(response), output)
self.b.setInputCmd(["status", "--all"])
response = (("Number of jails", 2), ("Jail list", ", ".join(["ssh", "exim4"])), {
"ssh": (
("Filter", [
("Currently failed", 0),
("Total failed", 0),
("File list", "/var/log/auth.log")
]
),
("Actions", [
("Currently banned", 3),
("Total banned", 3),
("Banned IP list", [
IPAddr("192.168.0.1"),
IPAddr("::ffff:10.2.2.1"),
IPAddr("2001:db8::1")
]
)
]
)
),
"exim4": (
("Filter", [
("Currently failed", 3),
("Total failed", 6),
("File list", "/var/log/exim4/mainlog")
]
),
("Actions", [
("Currently banned", 0),
("Total banned", 0),
("Banned IP list", []
)
]
)
)
})
output = (
"Status\n"
+ "|- Number of jails:\t2\n"
+ "|- Jail list:\tssh, exim4\n"
+ "`- Status for the jails:\n"
+ " |- Jail: ssh\n"
+ " | |- Filter\n"
+ " | | |- Currently failed: 0\n"
+ " | | |- Total failed: 0\n"
+ " | | `- File list: /var/log/auth.log\n"
+ " | `- Actions\n"
+ " | |- Currently banned: 3\n"
+ " | |- Total banned: 3\n"
+ " | `- Banned IP list: 192.168.0.1 10.2.2.1 2001:db8::1\n"
+ " `- Jail: exim4\n"
+ " |- Filter\n"
+ " | |- Currently failed: 3\n"
+ " | |- Total failed: 6\n"
+ " | `- File list: /var/log/exim4/mainlog\n"
+ " `- Actions\n"
+ " |- Currently banned: 0\n"
+ " |- Total banned: 0\n"
+ " `- Banned IP list: "
)
self.assertEqual(self.b.beautify(response), output)
def testFlushLogs(self):
self.b.setInputCmd(["flushlogs"])
self.assertEqual(self.b.beautify("rolled over"), "logs: rolled over")

62
fail2ban/tests/servertestcase.py

@ -620,6 +620,19 @@ class Transmitter(TransmitterBase):
["set", self.jailName, "addignoreregex", 50])[0],
1)
_JAIL_STATUS = [
('Filter', [
('Currently failed', 0),
('Total failed', 0),
('File list', [])]
),
('Actions', [
('Currently banned', 0),
('Total banned', 0),
('Banned IP list', [])]
)
]
def testStatus(self):
jails = [self.jailName]
self.assertEqual(self.transm.proceed(["status"]),
@ -628,59 +641,24 @@ class Transmitter(TransmitterBase):
jails.append("TestJail2")
self.assertEqual(self.transm.proceed(["status"]),
(0, [('Number of jail', len(jails)), ('Jail list', ", ".join(jails))]))
self.assertEqual(self.transm.proceed(["status", "--all"]),
(0, [('Number of jail', len(jails)), ('Jail list', ", ".join(jails)),
{"TestJail1": self._JAIL_STATUS, "TestJail2": self._JAIL_STATUS}
]))
def testJailStatus(self):
self.assertEqual(self.transm.proceed(["status", self.jailName]),
(0,
[
('Filter', [
('Currently failed', 0),
('Total failed', 0),
('File list', [])]
),
('Actions', [
('Currently banned', 0),
('Total banned', 0),
('Banned IP list', [])]
)
]
)
(0, self._JAIL_STATUS)
)
def testJailStatusBasic(self):
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', [])]
)
]
)
(0, self._JAIL_STATUS)
)
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', [])]
)
]
)
(0, self._JAIL_STATUS)
)
def testJailStatusCymru(self):

Loading…
Cancel
Save