Plugin Nagios pour les NAS Synology

Voici un plugin Nagios en Bourne shell qui peut s'exécuter directement sur les NAS Synology. Il s'appuit sur les scripts développés par Jur Groen et Nicolas Ordonez.

Il vérifiera les éléments suivants :

Environnement

Instructions

Activer SNMPv3

Synology NAS configuration SNMP

Le plugin peut être utilisé à distance (donc depuis le NAS Synology) ou localement (donc depuis le serveur Nagios).
À savoir que les informations sur le niveau d'utilisation des disques ne sera visible que depuis la méthode distante.

root@host:~# apt install sudo snmp

Méthode Locale

Ici, le plugin est exécuté depuis le serveur Nagios et des requètes SNMPv3 seront envoyées vers le NAS.

Synology NAS snmp Local graph
root@host:~# chmod +x ./check_syno.sh
root@host:~# sudo -u nagios ./check_syno.sh -u user -p PassW0RD -h 192.168.1.200
OK - The NAS DS218j - SN : 254262N214800 - DSM : DSM 6.2-25426 is fine
NAS temperature is 40°C - Fan Status : OK - CPU Fan Status : OK - Power Status : OK - System Status : OK 
The Hard Drive 2 model HD204UI is functioning normally
The Hard Drive 1 model WD20EARX-00PASB0 is functioning normally
The RAID Storage Pool 1 is fine The RAID Volume 2 is fine 

Méthode distante

Cette fois, le plugin est lancé depuis le serveur Nagios via ssh et s'exécutera sur le NAS Synology. Dans ce mode, les informations sur l'utilisation disques sera disponible.

Synology NAS snmp méthode distante

Création d'un nouvel utilisateur depuis l'interface Web

Synology NAS Interface Web creation Wizard

Activer l'authentification avec clé ssh

SAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
synoservicectl --restart sshd
chmod 0711 ~
chmod 0711 ~/.ssh
chmod 0600 ~/.ssh/authorized_keys
root@host:~# sudo -u nagios ssh-keygen -t rsa
root@host:~# sudo -u nagios cat /var/lib/nagios/.ssh/id_rsa.pub | ssh SSH_USER@192.168.1.200 'cat >> .ssh/authorized_keys' 
user@host:~$ scp check_syno.sh SSH_USER@192.168.1.200:/usr/syno/sbin/
root@host:~# sudo -u nagios ssh -l SSH_USER 192.168.1.200 /usr/syno/sbin/check_syno.sh -h 127.0.0.1 -u SNMP_USER -p SNMP_PASSWORD -w 80 -c 90
OK - The NAS DS218j - SN : 254262N214800 - DSM : DSM 6.2-25426 is fine
NAS temperature is 40°C - Fan Status : OK - CPU Fan Status : OK - Power Status : OK - System Status : OK 
The Hard Drive 2 model HD204UI is functioning normally
The Hard Drive 1 model WD20EARX-00PASB0 is functioning normally
The RAID Storage Pool 1 is fine The RAID Volume 2 is fine 
/volume2 is used at 49%, 947G remaining free space 
/tmp is used at 1%, 249M remaining free space 
/ is used at 42%, 1.3G remaining free space

check_syno.sh

#! /bin/bash
# check_snmp_synology for nagios version 1.4
# 30.04.2013  Nicolas Ordonez, Switzerland
# 03.10.2014  Jur Groen, Syso IT Services, The Netherlands
# 06.11.2014  shebangthedolphins.net
# 05.12.2014  shebangthedolphins.net add disk usage check
# 17.09.2020  shebangthedolphins.net bugs correction, DSM 6 compatibility, improve snmpv3 security (SHA and AES)
#---------------------------------------------------
# this plugin checks the health of your Synology NAS
# - System status (Power, Fans)
# - Disks status
# - RAID status
# - DSM update status
#
# this plugin now makes use of SNMP V3 for enhanced security
# Tested with DSM 6.0
#---------------------------------------------------
# Based on http://download.synology.com/download/ds/userguide/Synology_DiskStation_MIB_Guide_enu_20110725.pdf
#---------------------------------------------------

#Variables definition
## NAGIOS returns
CRITICAL=2
WARNING=1
OK=0
RETURN=0                #everything's fine, by default

## If arguments found
option_found=0

#get the number of partitions
NB_part=$(df -h | grep "/" | grep -v "\(\/tmpfs\|\/shm\|\/sys\|\/run\|\/dev$\|\/rootfs\)" | wc -l)

##OIDs
OID_syno="1.3.6.1.4.1.6574"
OID_model="1.3.6.1.4.1.6574.1.5.1.0"
OID_serialNumber="1.3.6.1.4.1.6574.1.5.2.0"
OID_DSMVersion="1.3.6.1.4.1.6574.1.5.3.0"
OID_upgradeAvailable="1.3.6.1.4.1.6574.1.5.4.0"
OID_systemStatus="1.3.6.1.4.1.6574.1.1.0"
OID_powerStatus="1.3.6.1.4.1.6574.1.3.0"
OID_systemFanStatus="1.3.6.1.4.1.6574.1.4.1.0"
OID_CPUFanStatus="1.3.6.1.4.1.6574.1.4.2.0"
OID_temp="1.3.6.1.4.1.6574.1.2.0"

OID_disk=""
OID_diskID="1.3.6.1.4.1.6574.2.1.1.2"
OID_diskModel="1.3.6.1.4.1.6574.2.1.1.3"
OID_diskStatus="1.3.6.1.4.1.6574.2.1.1.5"
OID_diskTemp="1.3.6.1.4.1.6574.2.1.1.6"

OID_RAID=""
OID_RAIDName="1.3.6.1.4.1.6574.3.1.1.2"
OID_RAIDStatus="1.3.6.1.4.1.6574.3.1.1.3"

#Functions
FunctionDiskSpace()
{
	if [ "$HOSTNAME" == "127.0.0.1" ]; then #check disk usage only if executed on the synology nas
	    for i in $(seq 1 "$NB_part"); do
		PARTITION=$(df -h | grep "/" | tr -s " " | grep -v "\(\/tmpfs\|\/shm\|\/sys\|\/run\|\/dev$\|\/rootfs\)" | head -n "$i" | tail -n 1 | grep "/" | cut -d " " -f 6)
		UTI=$(df -h | grep "/" | tr -s " " | grep -v "\(\/tmpfs\|\/shm\|\/sys\|\/run\|\/dev$\|\/rootfs\)" | head -n "$i" | tail -n 1 | grep "/" | cut -d " " -f 5)
		DISPO=$(df -h | grep "/" | tr -s " " | grep -v "\(\/tmpfs\|\/shm\|\/sys\|\/run\|\/dev$\|\/rootfs\)" | head -n "$i" | tail -n 1 | grep "/" | cut -d " " -f 4)
		SORTIE="$(echo ""$PARTITION" is used at "$UTI", "$DISPO" remaining free space") \n"$SORTIE""
		TEST=$(echo "$UTI" | sed 's/%//')
		if [ $TEST -gt "$WARNING_SPACE" ]; then
		    RETURN="$WARNING"
		    if [ "$TEST" -gt "$CRITICAL_SPACE" ]; then
			RETURN="$CRITICAL"
		    fi
		fi
	    done
	    if [ "$1" == "Output" ]; then
		echo -e "$SORTIE"
	    fi
	    SORTIE=""
	fi
}

usage()
{
        echo "usage: ./check_snmp_synology -u [snmp username] -p [snmp password] -h [hostname] -w [warning occuped space in %] -c [max occuped space in %]"
        echo ""
        exit 3
}

while getopts u:p:h:c:w: OPTNAME; do
        case "$OPTNAME" in
        u)
                SNMPUSERNAME="$OPTARG"
                option_found=1
                ;;
        p)
                SNMPPASSWORD="$OPTARG"
                option_found=1
                ;;

        h)
                HOSTNAME="$OPTARG"
                option_found=1
                ;;
        w)
                WARNING_SPACE="$OPTARG"
                option_found=1
                ;;
        c)
                CRITICAL_SPACE="$OPTARG"
                option_found=1
                ;;
        *)
                usage
                ;;
        esac
done

# Script beginning :
if [ "$option_found" -eq "0" ] || [ "$HOSTNAME" == "" ] ; then
        usage
else
        # DiskSpace function usage but without print anything
        FunctionDiskSpace NoOutput

	nbDISK=$(snmpwalk -OQne -v 3 -t 10 -l authNoPriv -u $SNMPUSERNAME -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" $HOSTNAME .1.3.6.1.4.1.6574.2.1.1.3 2>/dev/null|wc -l)
        #if SNMP failed, exit with error
        if [ "$?" != "0" ] ; then
                echo "CRITICAL - Problem with SNMP request"
                exit "$CRITICAL"
        fi

	nbRAID=$(snmpwalk -OQne -v 3 -t 10 -l authNoPriv -u $SNMPUSERNAME -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" $HOSTNAME .1.3.6.1.4.1.6574.3.1.1.2 2>/dev/null|wc -l)

        for i in $(seq 1 $nbDISK);
        do
                OID_DISK="$OID_disk $OID_diskID.$(($i-1)) $OID_diskModel.$(($i-1)) $OID_diskStatus.$(($i-1)) $OID_diskTemp.$(($i-1)) "
        done
        for i in $(seq 1 $nbRAID);
        do
                OID_RAID="$OID_RAID $OID_RAIDName.$(($i-1)) $OID_RAIDStatus.$(($i-1))"
        done

        #MODEL
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_model" 2>/dev/null)
        model=$(echo $temp | grep $OID_model | cut -d " " -f3 | sed "s/\"//g")
        #echo $model

        #serialNumber
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_serialNumber" 2>/dev/null)
        serialNumber=$(echo $temp | grep $OID_serialNumber | cut -d " " -f3 | sed "s/\"//g")
        #echo $serialNumber

        #OID_upgradeAvailable
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_upgradeAvailable" 2>/dev/null)

        #OID_DSMVersion
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_DSMVersion" 2>/dev/null)
        DSMVersion=$(echo $temp | grep $OID_DSMVersion | cut -d "\"" -f2)
        #echo "$DSMVersion"

        #OID_systemStatus
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_systemStatus" 2>/dev/null)
        systemStatus=$(echo $temp | grep $OID_systemStatus | cut -d " " -f3 | sed "s/\"//g")
        #echo $systemStatus

        #OID_powerStatus
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_powerStatus" 2>/dev/null)
        powerStatus=$(echo $temp | grep $OID_powerStatus | cut -d " " -f3 | sed "s/\"//g")
        #echo $powerStatus

        #OID_systemFanStatus
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_systemFanStatus" 2>/dev/null)
        systemFanStatus=$(echo $temp | grep $OID_systemFanStatus | cut -d " " -f3 | sed "s/\"//g")
        #echo $systemFanStatus

        #OID_CPUFanStatus
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_CPUFanStatus" 2>/dev/null)
        CPUFanStatus=$(echo $temp | grep $OID_CPUFanStatus | cut -d " " -f3 | sed "s/\"//g")
        #echo $CPUFanStatus

        #OID_temp
        temp=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_temp" 2>/dev/null)
        TEMP=$(echo "$temp" | grep "$OID_temp" | cut -d " " -f3 | sed "s/\"//g")
        #echo "$TEMP"

        #Disks state
        for i in $(seq 1 "$nbDISK")
        do
                temp01=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_diskStatus.$(($i-1))" 2>/dev/null)
                temp02=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_diskModel.$(($i-1))" 2>/dev/null)
                temp03=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_diskID.$(($i-1))" 2>/dev/null)
                temp04=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_diskTemp.$(($i-1))" 2>/dev/null)

                status=$(echo "$temp01" | grep "$OID_disk" | cut -d " " -f3)
                diskmodel=$(echo "$temp02" | grep "$OID_disk" | cut -d "\"" -f2 | sed 's/\s//g')
                ID=$(echo "$temp03" | grep "$OID_disk" | cut -d "\"" -f2)
                temp=$(echo "$temp04" | grep "$OID_disk" | cut -d " " -f3)
                if [ "$status" -eq "5" ]; then
                        disques="$(echo "The Hard "$ID" model "$diskmodel" is damaged")\\n"$disques""
                        RETURN="$CRITICAL"
                elif [ "$status" -eq "4" ]; then
                        disques="$(echo "The Hard "$ID" model "$diskmodel" has partitions damaged")\\n"$disques""
                        RETURN="$CRITICAL"
                elif [ "$status" -eq "3" ]; then
                        disques="$(echo "The Hard "$ID" model "$diskmodel" is not partitioned")\\n"$disques""
                        RETURN="$WARNING"
                elif [ "$status" -eq "2" ]; then
                        disques="$(echo "The Hard "$ID" model "$diskmodel" has system partitions but no data")\\n"$disques""
                        RETURN="$WARNING"
                elif [ "$status" -eq "1" ]; then
                        disques="$(echo "The Hard "$ID" model "$diskmodel" is functioning normally")\\n"$disques""
                        #RETURN=$(echo "$OK")
                else
                        disques="$(echo "The Hard "$ID" model "$diskmodel" is in an unknown state")\\n"$disques""
                        RETURN="$WARNING"
                fi
        done

        #RAID State
        for i in $(seq 1 "$nbRAID")
        do
                temp01=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_RAIDName.$(($i-1))" 2>/dev/null)
                temp02=$(snmpwalk -OQne -t 10 -v 3 -l authNoPriv -u "$SNMPUSERNAME" -a SHA -A "$SNMPPASSWORD" -x AES -X "$SNMPPASSWORD" "$HOSTNAME" "$OID_RAIDStatus.$(($i-1))" 2>/dev/null)
                Volume=$(echo "$temp01" | grep "$OID_disk" | cut -d "\"" -f2)
                Statut=$(echo "$temp02" | grep "$OID_disk" | cut -d " " -f3)
                if [ "$Statut" -eq "11" ]; then
                        raids="$(echo "The RAID "$Volume" is degraded") "$raids""
                        RETURN="$CRITICAL"
                elif [ "$Statut" -eq "12" ]; then
                        raids="$(echo "The RAID "$Volume" has crashed") "$raids""
                        RETURN="$CRITICAL"
                elif [ "$Statut" -eq "1" ]; then
                        raids="$(echo "The RAID "$Volume" is fine") "$raids""
                else
                        raids="$(echo "The RAID "$Volume" is in an unknown state") "$raids""
                        RETURN="$WARNING"
                fi
        done

        # Nagios States
        if [ "$RETURN" -eq "2" ] || [ "$systemFanStatus" -eq "2" ] || [ "$CPUFanStatus" -eq "2" ] || [ "$powerStatus" -eq "2" ] || [ "$systemStatus" -eq "2" ]; then
                echo -e "CRITICAL - The NAS "$model" - SN : "$serialNumber" - DSM : "$DSMVersion" has a problem"
                echo -e "NAS temperature is "$TEMP"°C - Fan Status : "$systemFanStatus" - CPU Fan Status : "$CPUFanStatus" - Power Status : "$powerStatus" - System Status : "$systemStatus" " | sed 's/ 1 / OK
                for i in "$disques"; do
                        echo -e "$i" | sed '/^$/d'
                done
                for i in "$raids"; do
                        echo -e "$i" | sed '/^$/d'
                done
                FunctionDiskSpace Output

                exit "$CRITICAL"
        fi
        if [ "$RETURN" -eq "1" ]; then
                echo -e "WARNING - The NAS "$model" - SN : "$serialNumber" - DSM : "$DSMVersion" is in Warning state"
                echo -e "NAS temperature is "$TEMP"°C - Fan Status : "$systemFanStatus" - CPU Fan Status : "$CPUFanStatus" - Power Status : "$powerStatus" - System Status : "$systemStatus" " | sed 's/ 1 / OK
                for i in "$disques"; do
                        echo -e "$i" | sed '/^$/d'
                done
                for i in "$raids"; do
                        echo -e "$i" | sed '/^$/d'
                done
                FunctionDiskSpace Output

                exit "$WARNING"
        fi
        if [ "$RETURN" -eq "0" ]; then
		echo -e "OK - The NAS "$model" - SN : "$serialNumber" - DSM : "$DSMVersion" is fine"
		echo -e "NAS temperature is "$TEMP"°C - Fan Status : "$systemFanStatus" - CPU Fan Status : "$CPUFanStatus" - Power Status : "$powerStatus" - System Status : "$systemStatus" " | sed 's/ 1 / OK /g' | sed 's/ 2 / FAILED /g'
		for i in "$disques"; do
			echo -e "$i" | sed '/^$/d'
		done
		for i in "$raids"; do
			echo -e "$i" | sed '/^$/d'
		done
		FunctionDiskSpace Output
		
		exit "$OK"
	fi 
	echo -e "CRITICAL - The NAS "$model" - SN : "$serialNumber" - DSM : "$DSMVersion" is in an indeterminate State"
	exit "$CRITICAL"
fi

Configuration Nagios

Je n'utilise plus Nagios mais la configuration doit ressembler à ça.

command.cfg

define command {
    command_name   check_syno_local
    command_line    /usr/local/sbin/check_syno.sh -u $ARG1$ -p $ARG2$ -h $ARG3$
}
define command {
    command_name   check_syno_remote
    command_line    ssh -l $ARG1$ $ARG2$ /usr/syno/sbin/check_syno.sh -h 127.0.0.1 -u $ARG3$ -p $ARG4$ -w 80 -c 90
}

service.cfg

define service{
    use                     nassynology-service
    host_name               NAS Synology
    servicegroups           nas-synology
    service_description     Backup Local NAS
    check_command           check_syno_local!SNMP_USER PassW0RD 192.168.1.200
}
define service{
    use                     nassynology-service
    host_name               NAS Synology
    servicegroups           nas-synology
    service_description     Backup Remote NAS
    check_command           check_syno_remote!SSH_USER 192.168.1.200 SNMP_USER PassW0RD
}

Output

Synology check_syno.sh plugin output
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Contact :