Tag - nagios

Entries feed

Tuesday 27 September 2011

Nagios plugin to check SSL certificates

Here a Nagios plugin I wrote for checking SSL certificates for expiry. You can set it up for emitting a WARNING or a CRITICAL state N days before expiry.

/root/bin/nagios-check-crt.sh :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash
 
# Written by Alexis Bezverkhyy <alexis@grapsus.net> in september 2011
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>
 
function PRINT_USAGE(){
  echo "This Nagios plugin checks SSL certificates for expiration :
  -c HOST:PORT host and port to connect
  -d DAYS  minimum days before expiry, otherwise a WARNING is issued
  -D DAYS  minimum days before expiry, otherwise a CRITICAL is issued
  -h    prints out this help"
  exit 0
}
 
CONNECT='';WDAYS=0;CDAYS=0;
declare -i CDAYS 
declare -i WDAYS
while true ; do
  getopts 'c:d:D:h' OPT 
  if [ "$OPT" = '?' ] ; then break; fi; 
  case "$OPT" in
    "c") CONNECT="$OPTARG";;
    "d") WDAYS="$OPTARG";;
    "D") CDAYS="$OPTARG";;
    "h") PRINT_USAGE;;
  esac
done
 
if [ -z "$CONNECT" -o '(' "$WDAYS" = '0' -a "$CDAYS" = '0' ')' ] ; then
  PRINT_USAGE
fi
 
function get_crt_expiry
{
        # connect to host with OpenSSL client, filter CRT, parse CRT,
        # get expiry time, convert to traditionnal y-m-d h:s
        echo -n '' | openssl s_client -connect "$1" 2>/dev/null \
                | awk 'BEGIN { p = 0 }
                                         /BEGIN CERT/ { p = 1 }
                                         { if (p) print $0 }
                                         /END CERT/ { p = 0 }' \
                | openssl asn1parse 2>/dev/null \
                | grep 'UTCTIME' \
                | awk '{ print $7 }' \
                | tr -d 'Z:' \
                | tail -n 1 \
                | sed -r 's/^(..)(..)(..)(..)(..).*$/\1-\2-\3 \4:\5/'
}
 
EXPIRY=$(get_crt_expiry "$CONNECT")
if [ -z "$EXPIRY" ] ; then
        echo "WARNING - cannot get expiry date for $CONNECT"
        exit 1
fi
EPOCH_EXPIRY=$(date -d "$EXPIRY" +%s)
EPOCH_NOW=$(date +%s)
let "REM_DAYS = (EPOCH_EXPIRY - EPOCH_NOW)/(24*3600)"
 
if [ "$CDAYS" -gt 0 -a "$REM_DAYS" -lt "$CDAYS" ] ; then
  echo "CRITICAL - $CONNECT crt expries on $EXPIRY ($REM_DAYS days left)" 
        exit 2
fi
 
if [ "$WDAYS" -gt 0 -a "$REM_DAYS" -lt "$WDAYS" ] ; then
  echo "WARNING - $CONNECT crt expries on $EXPIRY ($REM_DAYS days left)" 
        exit 1
fi
  
echo "OK - $CONNECT crt expries on $EXPIRY ($REM_DAYS days left)"

Here's the configuration to check a simple HTTPS service.

commands.cfg :

1
2
3
4
define command {
  command_name check_crt
  command_line /root/bin/nagios-check-crt.sh -c $ARG1$ -d $ARG2$ -D $ARG3$
}

myhost.cfg :

1
2
3
4
5
6
define service {
        use             generic-service
        host_name  myhost
        service_description HTTPS-CRT
        check_command check_crt!myhost.com:443!60!30
}

Thursday 5 August 2010

Nagios plugin to check backup folders

Here's a plugin I wrote for Nagios to check directories where some scripts regularly store backup files. You may specify a directory to scan, an optional pattern for the filename and the minimal age and size you expect for the latest file found in that directory and matching the pattern. The script can output warnings and critical alerts with different thresholds.

/root/bin//nagios-check-backup.sh :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/bin/bash
 
# Written by Alexis Bezverkhyy <alexis@grapsus.net> in july 2010
# This is free and unencumbered software released into the public domain.
# For more information, please refer to <http://unlicense.org/>
 
 
function PRINT_USAGE(){
  echo "This Nagios plugin checks backup folders :
  -d DIRECTORY  the directory to search for backup files
  -p PATTERN  an optionnal pattern for backup files
  -t HOURS  maximal age in hours for the latest backup before a warning is issued
  -T HOURS  maximal age in hours for the latest backup before a critical alert is issued
  -s KBYTES maximal size in kilo bytes for the latest backup before a warning is issued
  -S KBYTES maximal size in kilo bytes for the latest backup before a critical alert is issued
  -h    prints out this help
You must at least specify a directory and a minimal size or a minimal age."
  exit 0
}
 
WTIME=0;CTIME=0;WSIZE=0;CSIZE=0;DIR='';PATTERN=''
declare -i CTIME 
declare -i WTIME
declare -i CSIZE
declare -i WSIZE
while true ; do
  getopts 't:T:s:S:d:p:h' OPT 
  if [ "$OPT" = '?' ] ; then break; fi; 
  case "$OPT" in
    "t") WTIME="$OPTARG";;
    "T") CTIME="$OPTARG";;
    "s") WSIZE="$OPTARG";;
    "S") CSIZE="$OPTARG";;
    "d") DIR="$OPTARG";;
    "p") PATTERN="$OPTARG";;
    "h") PRINT_USAGE;;
  esac
done
 
if [ -z "$DIR" -o '(' "$WTIME" = '0' -a "$CTIME" = '0'\
 -a "$WSIZE" = '0' -a "$CSIZE" = '0' ')' ] ; then
  PRINT_USAGE
fi
 
LASTFILE=$(ls -lt --time-style=+%s "$DIR" | grep -v "^total " | grep "$PATTERN"\
 | head -n 1 | sed 's/\s\+/ /g')
if [ -z "$LASTFILE" ] ; then
  echo "CRITICAL - no backup found in $DIR" 
  exit 2
fi
 
TIMESTAMP=$(cut -d ' ' -f 6 <<< "$LASTFILE")
BYTES=$(cut -d ' ' -f 5 <<< "$LASTFILE")
let "SIZE = $BYTES / 1024"
FILENAME=$(cut -d ' ' -f 7 <<< "$LASTFILE")
let "AGE = ( $(date +%s) - $TIMESTAMP ) / 3600"
 
if [ "$CTIME" -gt 0 -a "$AGE" -gt "$CTIME" ] ; then
  echo "CRITICAL - $FILENAME is out of date ($AGE hours old)" 
  exit 2
fi
 
if [ "$WTIME" -gt 0 -a "$AGE" -gt "$WTIME" ] ; then
  echo "WARNING - $FILENAME is out of date ($AGE hours old)"  
  exit 1
fi
 
if [ "$CSIZE" -gt 0 -a "$SIZE" -lt "$CSIZE" ] ; then
  echo "CRITICAL - $FILENAME is too small ($SIZE kb)" 
  exit 2
fi
 
if [ "$WSIZE" -gt 0 -a "$SIZE" -lt "$WSIZE" ] ; then
  echo "WARNING - $FILENAME is too small ($SIZE kb)"  
  exit 1
fi
 
echo "OK - $FILENAME ($AGE hours old, $SIZE kb)"
exit 0

Here is a sample configuration for Nagios to use my script. check_backup checks a regular folder with compressed backups and check_sync checks a directory that is ought to be synchronized, therefore only age is checked and not the size.

commands.cfg :

1
2
3
4
5
6
7
8
9
10
define command {
  command_name check_backup
  command_line /root/bin/nagios-check-backup.sh -d $ARG1$ -p $ARG2$ -t $ARG3$ \
   -T $ARG4$ -s $ARG5$ -S $ARG6$
}
 
define command {
  command_name check_sync
  command_line /root/bin/nagios-check-backup.sh -d $ARG1$ -t $ARG3$ -T $ARG4$
}

foo.cfg :

1
2
3
4
5
6
7
8
9
10
11
12
13
define service{
        use                             generic-service
        host_name                       bar
        service_description             BAK-FOO-CONF
        check_command                   check_backup!/media/backup/foo/conf/!conf!30!60!2000!1000
}
 
define service{
        use                             generic-service
        host_name                       bar
        service_description             BAK-FOO-WWW
        check_command                   check_sync!/media/backup/foo/www/!30!60
}

Friday 1 January 2010

Nagios et les locales des plugins

Nagios a plein de fonctionnalités intéressantes, mais du côté de la localisation et des encodages de caractères c'est très mal géré. Par exemple on ne peut pas choisir l'encodage des pages web de l'interface (à moins de faire des bidouilles du côté du serveur HTTP), les caractères accentués sont supposés être en ISO-8859 et sont automatiquement convertis en codes HTML ce qui rend impossible leur affichage correct sur un système fonctionnant en UTF-8. Encore, ces problèmes n'affectent pas les fonctionnalités du logiciel. Par contre les plugins s'amusent à exécuter des commandes sans se soucier de la locale utilisée, si bien que la sortie dépend de la langue du système ! À partir de là, les pages de résumé ne ressemblent à rien, Nagiosgrapher marche une fois sur deux etc. Je n'ai pas trouvé comment remédier à ce problème sur le net; dans les rapports de bugs Debian correspondants, on va jusqu'à dire que c'est normal. J'ai essayé de changer la locale de Nagios dans son script init, mais celui-ci se fork et certains résultats sont en anglais alors que d'autres restent en français de manière complètement aléatoire.

Voici ma solution définitive à ce problème : recompiler Nagios avec la modification suivante dans le fichier base/checks.c :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
350,352d349
<       
<       char *current_locale;
<       char previous_locale[40];
762,768d758 
<                       /* Grapsus : run plugins with no locale */
<                       if(current_locale = getenv("LC_ALL"))
<                       {
<                               strncpy(previous_locale, current_locale, 40);
<                               previous_locale[39] = 0;
<                       }
<                       setenv("LC_ALL", "C", 1);
770,774d759 
<                       if(current_locale)
<                               setenv("LC_ALL", previous_locale, 1);
<                       else
<                               unsetenv("LC_ALL");
<                       /* End grapsus run plugins with no locale */

Avec ce patch, Nagios va se mettre en locale par défaut avant d'exécuter un plugin, de sorte que les résultats seront homogènes et facilement lisibles avec Nagiosgrapher.

Voici comment obtenir le code source sous Debian :

apt-get source nagios3
apt-get build-dep nagios3

Une fois le patch appliqué, on reconstruit le paquet avec :

dpkg-buildpackage -uc -us