1
0
Fork 0
scripts-admin-quickndirty-p.../nagios/check_netstat_connectioncount.sh

217 lines
5.2 KiB
Bash
Raw Permalink Normal View History

#!/bin/sh
# Petit script custom pour vérifier le nombre de connexions sur netstat
# GPL v3+ (copyright chl-dev@bugness.org)
# Default values
RANGE_WARNING="1:50"
RANGE_CRITICAL="1:100"
# Output
OUTPUT_EXIT_STATUS=0
OUTPUT_DETAIL_WARNING=""
OUTPUT_DETAIL_CRITICAL=""
OUTPUT_PERFDATA=""
PROGPATH=$( echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,' )
REVISION="0.1"
# Stop at the first non-catched error
set -e
# Include check_range()
. $PROGPATH/utils.sh
#
# Fonction d'aide
#
usage() {
cat <<EOF
Usage :
$0 [-w warning_range] [-c critical_range] -p port [[-w...] -p port] ...
Example :
./check_netstat_connectioncount.sh -w 50 -c 100 -p 80
Note: Since the port is checked against the lastest ranges given, order
of the arguments is important. Ex:
./check_netstat_connectioncount.sh -w 1:5 -c 1:10 -p 22 -p listen-unix:X11 -w 1:50 -c 1:100 -p 80 -p 443
Note 2: grep's return code can be different from 0 so remember to wrap it :
./check_netstat_connectioncount.sh -w 1:10 -c 1:20 -p cmd:weird_cpt:'ls /tmp | (grep -c "private" || true )'
Special values for 'port' :
all
all-ipv4
all-ipv6
listen
listen-ipv4
listen-ipv6
listen-unix
listen-unix:PATTERN
cmd:LABEL:SHELL COMMAND LINE
Default values:
warning_range: $RANGE_WARNING
critical_range: $RANGE_CRITICAL
EOF
}
check_range_syntax() {
check_range 0 "$1" >/dev/null 2>&1
if [ "$?" -eq "2" ]; then
return 1
fi
return 0
}
# Some early checks
for i in netstat ss; do
if which "$i" >/dev/null 2>&1 ; then
COMMAND_SYS="$i"
if [ "$COMMAND_SYS" = "ss" ]; then
OUTPUT_COLUMN=5
else
OUTPUT_COLUMN=4
fi
break
fi
done
if [ -z "$COMMAND_SYS" ]; then
echo "UNKNOWN 'netstat' and 'ss' not found."
exit 1
fi
#
# Gestion des paramètres
#
while getopts hw:c:p: f; do
case "$f" in
'h')
usage
exit
;;
'w')
if check_range_syntax "$OPTARG" >/dev/null; then
RANGE_WARNING="$OPTARG"
else
echo "UNKNOWN: invalid range."
exit 3
fi
;;
'c')
if check_range_syntax "$OPTARG" >/dev/null; then
RANGE_CRITICAL="$OPTARG"
else
echo "UNKNOWN: invalid range."
exit 3
fi
;;
'p')
# Ce n'est pas très propre, mais on gère tout ici plutôt que de remplir
# un buffer et de le traiter ensuite
# Note : grep renvoie un code d'erreur 1 s'il n'y a pas de résultat,
# d'où l'ajout d'un || true sur lui uniquement.
LABEL="$OPTARG"
case "$OPTARG" in
'all')
CPT="$( $COMMAND_SYS -taun | tail -n +2 | wc -l )"
PORT_NUMBER='all'
;;
'all-ipv4')
CPT="$( $COMMAND_SYS -taun4 | tail -n +2 | wc -l )"
PORT_NUMBER='all-ipv4'
;;
'all-ipv6')
CPT="$( $COMMAND_SYS -taun6 | tail -n +2 | wc -l )"
PORT_NUMBER='all-ipv6'
;;
'listen')
CPT="$( $COMMAND_SYS -tlun | tail -n +2 | wc -l )"
PORT_NUMBER='listen'
;;
'listen-ipv4')
CPT="$( $COMMAND_SYS -tlun4 | tail -n +2 | wc -l )"
PORT_NUMBER='listen-ipv4'
;;
'listen-ipv6')
CPT="$( $COMMAND_SYS -tlun6 | tail -n +2 | wc -l )"
PORT_NUMBER='listen-ipv6'
;;
'listen-unix')
CPT="$( $COMMAND_SYS -xl | tail -n +2 | wc -l )"
PORT_NUMBER='listen-unix'
;;
'listen-unix:'*)
CPT="$( $COMMAND_SYS -xl | tail -n +2 | grep "$( echo "$OPTARG" | sed 's/^listen-unix://' )" | wc -l )"
PORT_NUMBER=$OPTARG # risque de bug côté superviseur ?
;;
'cmd:'*)
# Free form. Should be 'cmd:<label>:<shell commands returning a number>'
LABEL="$( echo "$OPTARG" | sed -n 's/^cmd:\([^:]\+\):.*/\1/p' )"
PORT_NUMBER="$LABEL"
CUSTOM_CMD="$( echo "$OPTARG" | sed -n 's/^cmd:\([^:]\+\):\(.*\)/\2/p' )"
if [ -z "$LABEL" ] || [ -z "$CUSTOM_CMD" ]; then
echo "UNKNOWN: empty label or command in '$OPTARG' (should be cmd:LABEL:COMMAND LINE)"
exit 3
fi
# If the command fail, this script will stop and the output code will
# be different than 0 so it shouldn't pass unnoticed.
CPT="$( sh -c "$CUSTOM_CMD" )"
;;
*)
PORT_NUMBER=$( printf "%d" "$OPTARG" )
LABEL="port$PORT_NUMBER"
CPT="$( $COMMAND_SYS -taun | sed 's/[[:space:]]\+/\t/g' | cut -f "$OUTPUT_COLUMN" | ( grep -c ":$PORT_NUMBER$" || true ) )"
;;
esac
# mémo : 'label'=value[UOM];[warn];[crit];[min];[max]
2024-02-02 23:10:43 +01:00
OUTPUT_PERFDATA=$( printf "%s\n'%s'=%d;%s;%s;0;" \
"$OUTPUT_PERFDATA" \
"$LABEL" \
"$CPT" \
"$RANGE_WARNING" \
"$RANGE_CRITICAL" )
if check_range "$CPT" "$RANGE_CRITICAL"; then
OUTPUT_EXIT_STATUS=2
OUTPUT_DETAIL_CRITICAL="$OUTPUT_DETAIL_CRITICAL Port:$PORT_NUMBER($CPT conn.)"
elif check_range "$CPT" "$RANGE_WARNING"; then
if [ "$OUTPUT_EXIT_STATUS" -eq 0 ]; then
OUTPUT_EXIT_STATUS=1
fi
OUTPUT_DETAIL_WARNING="$OUTPUT_DETAIL_WARNING Port:$PORT_NUMBER($CPT conn.)"
fi
;;
\?)
usage
exit 1
;;
esac
done
case "$OUTPUT_EXIT_STATUS" in
'0')
printf "OK ($COMMAND_SYS)"
;;
'1')
printf "WARNING ($COMMAND_SYS) %s" "$OUTPUT_DETAIL_WARNING"
;;
'2')
printf "CRITICAL ($COMMAND_SYS) %s" "$OUTPUT_DETAIL_CRITICAL"
;;
*)
printf "UNKNOWN"
;;
esac
2024-02-02 23:10:43 +01:00
# We sort the entries to avoid mismatch with poor implementations of pnp4nagios
printf "|%s\n" "$( printf "%s" "$OUTPUT_PERFDATA" | grep -v "^$" | sort | tr "\n" " " )"
# on supprime les retours à la ligne
exit $OUTPUT_EXIT_STATUS