Files
Domcheck/check
Dominique Fournier 2c07be09ff Les erreurs de lanceurs sont maintenant envoyées au gestionnaire d'alerte plutot qu'à l'écran (ras le bol des mails en boucle)
Le passage des processus n'est possible qu'en Bash4 et +. Pour les Bash3, on retourne à la gestion avec les liens symboliques


git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@428 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
2012-05-14 09:42:27 +00:00

301 lines
8.9 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 asynchronisé 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[mysqld]="mysql"
lanceur[ntpd]="ntp"
lanceur[rsyslogd]="rsyslog"
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