Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various improvements #12

Merged
merged 4 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ I followed [Writing you own check plug-ins](https://docs.checkmk.com/latest/en/d
## Parameter to configure

## TODO
* use parse functions?
* Add Agent Bakery support (I use core only)
* Decide if total banned/failed are something you want to graph and altering on
13 changes: 5 additions & 8 deletions agents/plugins/fail2ban
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@
# Boston, MA 02110-1301 USA.


if [ -x /usr/bin/fail2ban-client ]; then
echo "<<<fail2ban>>>"
jails="$(/usr/bin/fail2ban-client status | grep "Jail list" | sed -e 's/.*://' -e 's/,//g')"
echo "Detected jails: $jails"
for jail in $jails
do
/usr/bin/fail2ban-client status "$jail"
done
if command -v fail2ban-client > /dev/null 2>&1; then
echo "<<<fail2ban:sep(58)>>>"
fail2ban-client status |
awk -F: '$1 ~ /Jail list$/ { gsub(/,/, "", $2); print $2}' |
xargs -n1 fail2ban-client status
fi
161 changes: 80 additions & 81 deletions lib/check_mk/base/plugins/agent_based/fail2ban_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,96 +39,95 @@
# `- Actions
# |- Currently banned: 5
# |- Total banned: 50
# `- Banned IP list: 112.122.54.162 144.135.85.184 103.200.21.89 1.14.61.204
# `- Banned IP list: 192.0.2.162 198.51.100.184 203.0.113.89

from .agent_based_api.v1 import *
from .agent_based_api.v1 import register, check_levels, Service
from .agent_based_api.v1.type_defs import (
DiscoveryResult,
CheckResult,
StringTable,
)

from typing import Any, Mapping

def discovery_fail2ban(section):
firstline = section[0]
if firstline[:2] == ['Detected', 'jails:']:
for jail in firstline[2:]:
yield Service(item=jail)

Section = Mapping[str, Mapping[str, str]]

def check_fail2ban(item, params, section):
currentjail = ""
currentfailedcrit = params["failed"][1]
currentfailedwarn = params["failed"][0]
currentbannedcrit = params["banned"][1]
currentbannedwarn = params["banned"][0]

# set variable to check for jails that are not there anymore
currentfailed = None
currentbanned = None
totalfailed = None
totalbanned = None
def parse_fail2ban(string_table: StringTable) -> Section:
parsed = {}
currentjail = None
for line in string_table:
if ' ' not in line[0]:
# Re-split on : instead of space
line = " ".join(line).split(":")

for entry in section:
if (entry[:3]) == ['Status', 'for', 'the']:
currentjail = entry[4]
elif currentjail != item:
# skip lines when this item is requested at the moment
if len(line) != 2:
# Not a key-value pair
continue
elif (entry[:4]) == ['|', '|-', 'Currently', 'failed:', ]:
currentfailed = int(entry[4])
elif (entry[:4]) == ['|', '|-', 'Total', 'failed:', ]:
totalfailed = int(entry[4])
elif (entry[:3]) == ['|-', 'Currently', 'banned:', ]:
currentbanned = int(entry[3])
elif (entry[:3]) == ['|-', 'Total', 'banned:', ]:
totalbanned = int(entry[3])

# removed jails should not create a crash,
# so we dont yield anything and simply return without anything
if (currentfailed is None) or \
(totalfailed is None) or \
(currentbanned is None) or \
(totalbanned is None):

key = line[0].strip("|-` ")
value = line[1].strip()

if key == 'Status for the jail':
currentjail = value
parsed[currentjail] = dict()
elif currentjail is not None:
try:
parsed[currentjail][key] = int(value)
except ValueError:
# we are only interested in the numeric values
pass
return parsed


register.agent_section(
name="fail2ban",
parse_function=parse_fail2ban,
)


def discovery_fail2ban(section: Section) -> DiscoveryResult:
for jail in section:
yield Service(item=jail)


def check_fail2ban(
item: str,
params: Mapping[str, Any],
section: Section,
) -> CheckResult:
try:
data = section[item]
except KeyError:
# removed jails should not create a crash,
# so we dont yield anything and simply return without anything
return
elif currentfailedcrit <= currentfailed or \
currentbannedcrit <= currentbanned:
s = State.CRIT
status = "Crit"
elif currentfailedwarn <= currentfailed or \
currentbannedwarn <= currentbanned:
s = State.WARN
status = "Warn"
else:
s = State.OK
status = "OK"

yield Metric(
name="current_failed",
value=currentfailed,
levels=(currentfailedwarn, currentfailedcrit)
)
yield Metric(
name="total_failed",
value=totalfailed,
)
yield Metric(
name="current_banned",
value=currentbanned,
levels=(currentbannedwarn, currentbannedcrit)
)
yield Metric(
name="total_banned",
value=totalbanned,
)

yield Result(
state=s,
summary=f"{status} - {item} active - {currentfailed} failed ({totalfailed} total), {currentbanned} banned ({totalbanned} total)"
)
return

for what in ("failed", "banned"):
current_key = f"Currently {what}"
total_key = f"Total {what}"
yield from check_levels(
metric_name=f"current_{what}",
value=data[current_key],
levels_upper=params[what],
label=current_key,
render_func=int,
)
yield from check_levels(
metric_name=f"total_{what}",
value=data[total_key],
notice_only=True,
label=total_key,
render_func=int,
)


register.check_plugin(
name="fail2ban",
service_name="Jail %s",
discovery_function=discovery_fail2ban,
check_function=check_fail2ban,
check_default_parameters={'banned': (10, 20), 'failed': (30, 40)},
check_ruleset_name="fail2ban",
)
name="fail2ban",
service_name="Jail %s",
discovery_function=discovery_fail2ban,
check_function=check_fail2ban,
check_default_parameters={'banned': (10, 20), 'failed': (30, 40)},
check_ruleset_name="fail2ban",
)
1 change: 1 addition & 0 deletions web/plugins/wato/fail2ban_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
Dictionary,
Integer,
TextAscii,
Tuple,
)

from cmk.gui.plugins.wato import (
Expand Down