Files
Domcheck/check
2013-03-06 09:18:35 +00:00

306 lines
9.0 KiB
Bash
Executable File

#!/bin/bash
## CHECK
## Verifie que les programmes fonctionnent et les relance si ils sont en panne
## Doit etre lance par cron. On peut par exemple mettre un /etc/cron.d/check
## qui contient :
## * * * * * root /usr/sbin/check
PATH="/sbin:/bin:/usr/sbin:/usr/bin"
## Configuration dans un fichier exterieur : /etc/check.conf
if [ "`whoami`" != "root" ]; then
echo "Check lance par un autre utilisateur que root : EXIT"
exit
fi
RUNLEVEL=`runlevel | cut -f 2 -d ' '`
if [ $RUNLEVEL -eq 0 ] || [ $RUNLEVEL -eq 6 ]; then
echo "Arret ou reboot en cours : on sort"
exit
fi
if [ $RUNLEVEL -eq 1 ]; then
echo "Démarrage en cours : on sort"
exit
fi
if [ -f "/tmp/check-bloque" ]; then
# Check est bloque par un programme externe : on sort
exit
fi
function checklog()
{
# Loggue dans /var/log/check.log tous les arguments passes a la fonction
# Ne doit pas se retrouver dans le fichier de configuration (sauf pour test
# de demarrage de l'application check)
echo "`date +"%b %d %T"` `hostname` check - $@" >> /var/log/check.log
if [ "$alerteAudio" == "TRUE" ]; then
rc=`/usr/bin/alerte.php "$@"`
if [ "$rc" != "OK" ]; then
echo $rc
fi
fi
if [ "$alerteNotify" == "TRUE" ]; then
rc=`/usr/bin/notify-send -u critical -t 2000 "$@"`
if [ "$rc" != "OK" ]; then
echo $rc
fi
fi
if [ "$alerteAudio" != "TRUE" ] && [ "$alerteNotify" != "TRUE" ]; then
# Si aucun moyen de communication n'est demandé, on écrit à l'écran
echo "$@"
fi
}
function chercheLanceur()
{
# Cette fonction renvoie le lanceur du programme passé en paramètre
# On peut définir un tableau supplémentaire dans le fichier de configuration
# Si le lanceur n'est pas défini dans le tableau, on renvoie le nom du
# processus
if [ $BASH_VERSINFO -ge 4 ]; then
processus=$1
if [ -z ${lanceur["$processus"]} ]; then
echo "$processus"
else
echo ${lanceur["$processus"]}
fi
else
# Le Bash 3 ne supporte pas les tableaux associatifs. On retourne aux liens
# symboliques
echo $1
fi
}
function testps()
{
lanceur=`chercheLanceur "$1"`
if [ ! -e "/etc/init.d/$lanceur" ]; then
checklog "ERREUR : /etc/init.d/$lanceur introuvable (testps)"
else
if [ `ps -edf | grep -v grep | grep "$*" | wc -l` -eq 0 ]; then
checklog "Relance de '$*' par /etc/init.d/$lanceur"
/etc/init.d/$lanceur stop
/etc/init.d/$lanceur start
fi
fi
}
function testpsStrict()
{
# On rend le test plus strict en mettant un slash devant le nom du demon
lanceur=`chercheLanceur "$1"`
if [ ! -e "/etc/init.d/$lanceur" ]; then
checklog "ERREUR : /etc/init.d/$lanceur introuvable (testpsStrict) "
else
if [ `ps -edf | grep -v grep | grep "/$*" | wc -l` -eq 0 ]; then
checklog "Relance de '$*' par /etc/init.d/$lanceur"
/etc/init.d/$lanceur stop
/etc/init.d/$lanceur start
fi
fi
}
function testiptables()
{
# Verifie que iptables est bien ferme
if [ ! -e "/etc/init.d/ipt4" ] && [ ! -e "/etc/init.d/ipt" ]; then
checklog "ERREUR : /etc/init.d/ipt4 ou /etc/init.d/ipt introuvable (testiptables) "
else
if [ `/sbin/iptables -L -n | wc -l` -lt 10 ]; then
checklog "Relance de IPTables IPv4"
if [ -e "/etc/init.d/ipt4" ]; then
/etc/init.d/ipt4 start
else
/etc/init.d/ipt start
fi
fi
fi
}
function testip6tables()
{
# Verifie que ip6tables est bien ferme
if [ ! -e "/etc/init.d/ipt6" ]; then
checklog "ERREUR : /etc/init.d/ipt6 introuvable (testip6tables) "
else
if [ `/sbin/ip6tables -L -n | wc -l` -lt 10 ]; then
checklog "Relance de IPTables IPv6"
/etc/init.d/ipt6 start
fi
fi
}
function testDNS()
{
# Verifie si le DNS a change pour l'adresse passe en argument
NEW="`host -t A $1 2>/dev/null`"
if [ "$?" != "0" ]; then return; fi
if [ "$NEW" != "`cat /var/lib/check 2>&1 /dev/null`" ]; then
checklog "Changement d'adresse pour $1 : `host -t A $1`"
echo "ALERTE : Nouvelle adresse DNS pour $1 :"
echo " Ancienne : `cat /var/lib/check 2>&1 /dev/null`"
echo " Nouvelle : $NEW"
host -t A $1 > /var/lib/check
fi
}
function testdf()
{
# Teste tous les disques et renvoie si le disque est plein a plus de 84%
# On peut aussi tester les disques unitairement :
# testdf /mnt
# On peut aussi tester unitairement avec une limite differente de 84%
# testdf /mnt 90
if [ -z "$2" ]; then
limite=84
else
limite=$2
fi
if [ ! -z "$1" ]; then
fs="$1"
fi
IFS="
"
for ligne in `df -P -l -x tmpfs -x devtmpfs $fs | sed '/Used Available/d'`; do
fs_space=`echo $ligne | awk '{print $5}'| sed 's/\%//'`
filesys=`echo $ligne | awk '{print $6}'`
if [ $fs_space -gt $limite ]; then
checklog "Systeme de fichier $filesys plein a $fs_space %"
fi
done
}
function testPort()
{
# Verifie si un port est actif
# Attend 3 parametres : l'adresse IP a tester, le port a tester et le
# fichier /etc/init.d/XX a relancer
if [ ! -e "/etc/init.d/$3" ]; then
checklog "ERREUR : /etc/init.d/$3 introuvable (testPort)"
else
RESULTAT=`echo "QUIT" | nc -w1 $1 $2 2>&1`
if [ "$?" != "0" ]; then
checklog "Relance de $3 car injoignable par reseau"
echo "ALERTE : La machine `hostname` ne peut plus se connecter a "
echo "$1 port $2 : $RESULTAT"
echo "Relance de $3"
/etc/init.d/$3 stop
/etc/init.d/$3 start
fi
fi
}
function testDDClient()
{
# Verifie si ddclient est toujours actif. Pour cela, le processus doit avoir
# une ligne 'ddclient - sleeping for'. Si ce n'est pas le cas (test en cours)
# on attend 15 s et on refait le test. Si le test est toujours negatif on
# relance.
if [ ! -e "/etc/init.d/ddclient" ]; then
checklog "ERREUR : /etc/init.d/ddclient introuvable (testDDClient)"
else
LIGNE1=`ps -edf | grep -v grep | egrep "ddclient "`
LIGNE2=`echo $LIGNE1 | egrep 'ddclient - sleeping for|ddclient - (connecting to|reading from) checkip.dyndns.com port 80'`
if [ $? -ne 0 ]; then
checklog " DDCLIENT ERREUR 1 (LIGNE1=$LIGNE1///LIGNE2=$LIGNE2)"
ps -edf >> /var/log/check.log
checklog "ddclient non lance ou pas en mode sleep : relance"
echo "Relance de ddclient"
/etc/init.d/ddclient stop
/etc/init.d/ddclient start
fi
fi
}
function testMount()
{
# Verifie si le point de montage passe en argument est bien monte et en RW
# Si pas monte, on le monte. Si en RO, on le passe en RW
PNT=$1
MNT=`egrep -v "^{none|rootfs|binfmt_misc|gvfs-fuse-daemon} " /proc/mounts | cut -d " " -f 2 | egrep "^$PNT$"`
if [ "$MNT" == "" ]; then
checklog "Disque $PNT non monte : remonte"
mount $PNT
fi
ST=`egrep -v "^{none|rootfs|binfmt_misc|gvfs-fuse-daemon} " /proc/mounts | cut -d " " -f 2,4| egrep "^$PNT " | cut -d " " -f 2 | cut -d "," -f 1`
if [ "$ST" == "ro" ]; then
checklog "Disque $PNT en RO : Passage en RW"
mount -o remount,rw $PNT
fi
}
function testRepertoireVide()
{
# Verifie que le repertoire passe en argument est bien vide
REP=$1
if [ "`ls -1 $REP`" != "" ]; then
checklog "Repertoire $1 non vide"
ls -1 $REP
fi
}
function testBatterie()
{
# Cette fonction teste la batterie de l'ordinateur si elle est dispo et envoie
# une erreur si le niveau tombe sous le seuil defini pour la batterie
# Recherche du seuil :
SEUIL=`grep "design capacity warning:" /proc/acpi/battery/BAT1/info 2>/dev/null | cut -d " " -f 4`
# Recherche de la capacite restante :
CAPA=`grep "remaining capacity:" /proc/acpi/battery/BAT1/state 2>/dev/null | cut -d " " -f 8`
if [ -n $SEUIL ] && [ -n $CAPA ] && [ $CAPA -lt $SEUIL ]; then
checklog "Batterie faible ($CAPA/$SEUIL)"
fi
}
function testNTP()
{
# Cette fonction teste si NTP est bien synchronisé avec un serveur de temps
/usr/bin/ntpq -n -c peers | egrep -q '^\*' || checklog "Serveur de temps désynchronisé ou injoignable"
}
if [ ! -f "/etc/check.conf" ]; then
echo "Le fichier /etc/check.conf n'existe pas : EXIT"
exit
fi
# Lanceur est le tableau associatif des lanceurs 'processus'=>'lanceur' dans
# /etc/init.d
# On peut définir des lanceurs dans la fonction chercheLanceur, ou dans le
# fichier de configuration /etc/check.conf. Si on redéfinit un lanceur dans
# /etc/check.conf, c'est lui qui est prioritaire par rapport à ceux codés en dur
if [ $BASH_VERSINFO -ge 4 ]; then
declare -A lanceur
lanceur[bind]="bind9"
lanceur[dhcpd]="isc-dhcp-server"
lanceur[master]="postfix"
lanceur[munin-nod]="munin-node"
lanceur[mysqld]="mysql"
lanceur[ntpd]="ntp"
lanceur[rpc.statd]="nfs-common"
lanceur[rpc.idmapd]="nfs-common"
lanceur[rsyslogd]="rsyslog"
lanceur[smartd]="smartmontools"
lanceur[spamd]="spamassassin"
lanceur[sshd]="ssh"
fi
. /etc/check.conf
if [ "$alerteNotify" == "TRUE" ] && [ ! -f "/usr/bin/notify-send" ]; then
echo "Check : alerteNotify demande mais /usr/bin/notify-send non disponible"
echo " apt-get install libnotify-bin"
exit
fi
if [ "$alerteAudio" == "TRUE" ] && [ ! -f "/usr/bin/alerte.php" ]; then
echo "Check : alerte audio demandée mais /usr/bin/alerte.php non disponible"
echo " apt-get install cric-alerte"
exit
fi