Création — Nicolas THOREZ 2020/02/12 15:06
Pour un projet j'ai dû mettre une supervision sur les sites web de mon entreprise. Lorsqu'il n'y a qu'un serveur web avec un seul site, c'est pas très compliqué. Mais quand l'entreprise gère plusieurs dizaines de serveurs hébergeant chacun plusieurs dizaines de sites, ça peut rapidement devenir compliquer.
Une automatisation de cette mise en supervision peut alors s'avérer utile :
curl est nécessaire sur le serveur Apache.
Les paquets curl, wget et nagios-plugins sont nécessaire sur le serveur Nagios.maintenance).L'ensemble des actions du script sont envoyé dans un fichier log.
Le script d'inventaire est placé dans /usr/local/batch/webcheck/ sous le nom check-websites-state.sh
#!/bin/bash
###########################################################################################
#
# Script de vérifications de l'état des sites web
#
# Par Nicolas THOREZ
#
###########################################################################################
##### Déclarations des variables #####
# nom du serveur
HOSTNAME=$(hostname)
# Dépôt externe
DRIVE="drive.shyrkasys.local"
# User dépôt externe
USER="webcheck"
# Mot de passe
PASS="P@ssw0rd"
# Dépôt local
LOCAL="/usr/local/batch/webcheck/repository"
# Date de la vérification
DATE=$(date '+%Y/%m/%d')
##### Traitement #####
# Vérification du dépôt local
if [ ! -d $LOCAL ]
then
# Création du dépôt
mkdir -p $LOCAL
fi
# Vérification de l'existence du fichier de status du serveur
if [ ! -e $LOCAL/$HOSTNAME-state ]
then
touch $LOCAL/$HOSTNAME-state
fi
# Vérification de l'existence de la liste des sites web
if [ ! -e $LOCAL/$HOSTNAME-list ]
then
touch $LOCAL/$HOSTNAME-list
fi
# Vérification de la différence entre les sites disponibles et les sites actifs (sauf les default et maintenance)
DIFF=$(diff /etc/apache2/sites-available/ /etc/apache2/sites-enabled/ | grep -vi 'default\|maintenance' | awk '{ print $3,$4 }' | cut -d/ -f4-9 | wc -l)
# Ajout des sites à checker
grep -Ri 'servername' /etc/apache2/sites-enabled/ | grep -vi 'default\|maintenance\|#' | awk '{print $3 }' > $LOCAL/$HOSTNAME-list
# Mise à jour des données
echo "DATE=$DATE" > $LOCAL/$HOSTNAME-state
echo "DIFF=$DIFF" >> $LOCAL/$HOSTNAME-state
# Mise à jour du dépôt externe
curl -X PUT -u $USER:$PASS --cookie "XDEBUG_SESSION=MROW4A;path=/;" --data-binary @"$LOCAL/$HOSTNAME-state" "https://$DRIVE/remote.php/webdav/$HOSTNAME-state"
curl -X PUT -u $USER:$PASS --cookie "XDEBUG_SESSION=MROW4A;path=/;" --data-binary @"$LOCAL/$HOSTNAME-list" "https://$DRIVE/remote.php/webdav/$HOSTNAME-list"
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0 5 * * 1-5 root /usr/local/batch/webcheck/check-websites-state.sh
Le script général est placé dans /usr/local/batch/webcheck/ sous le nom check-all-websites.sh
#!/bin/bash
####################################################################################################
#
# Script de vérification de tous les sites webs
#
# Par Nicolas THOREZ
#
####################################################################################################
##### Déclaration des fonctions #####
# Fonction d'affichage en mode verbeux et inscription des logs
add-log()
{
# Variables pour la coloration syntaxique du mode verbeux
GOOD="\e[92m"
CRIT="\e[91m"
WARN="\e[93m"
INFO="\e[96m"
UNKN="\e[95m"
OFF="\e[39m"
# Variable date et heure
DATE=$(date '+%Y/%m/%d %H:%M:%S')
# Gestion des arguments pour la fonction
while [[ $# -gt 0 ]]
do
LOG_PARAM="$1"
case $LOG_PARAM in
# fichier de logs
-f|--file)
LOG="$2"
shift
shift
;;
# Niveau de log
-l|--level)
LEVEL="$2"
shift
shift
;;
# Message
-m|--message)
MESSAGE="$2"
shift
shift
;;
# Autres
*)
echo -e "$DATE $CRIT[CRIT]$OFF Erreur d'arguments pour la fonction$CRIT add-log$OFF. Merci de vérifier votre code."
esac
done
# Enregistrement dans le fichier log
if [ -f $LOG ]
then
echo "$DATE [$LEVEL] $MESSAGE" >> $LOG
else
touch $LOG
echo "$DATE [$LEVEL] $MESSAGE" >> $LOG
fi
# Affichage console en cas de mode verbeux
if [ "$VERBOSE" == "TRUE" ]
then
case $LEVEL in
"GOOD")
echo -e "$DATE $GOOD[$LEVEL]$OFF $MESSAGE"
;;
"WARN")
echo -e "$DATE $WARN[$LEVEL]$OFF $MESSAGE"
;;
"CRIT")
echo -e "$DATE $CRIT[$LEVEL]$OFF $MESSAGE"
;;
"INFO")
echo -e "$DATE $INFO[$LEVEL]$OFF $MESSAGE"
;;
"UNKN")
echo -e "$DATE $UNKN[$LEVEL]$OFF $MESSAGE"
;;
esac
fi
}
# Fonction de création et d'envoi de rapport HTML
send-report()
{
# Gestion des arguments pour la fonction
while [[ $# -gt 0 ]]
do
LOG_PARAM="$1"
case $LOG_PARAM in
# Fichier HTML
-f|--file)
HTML="$2"
shift
shift
;;
# Raison du rapport
-m|--message)
MESSAGE="$2"
shift
shift
;;
# Destinataire
-a|--address-mail)
MAIL="$2"
shift
shift
;;
# Autres
*)
add-log -f $LOG_FILE -l "WARN" -m "[ GENERAL ] Erreur d'arguments pour la fonction send-report. Merci de vérifier votre code."
esac
done
# Headers
HEADERS='
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>WebCheck - Rapport de supervision des sites web</title>
</head>
<body>
<h1>Rapport de supervision des sites Web</h1>
<p>Date:'
# Date du rapport
HTMLDATE=$(date '+%d/%m/%Y')
# Début du rapport
echo $HEADERS > $HTML
echo $HTMLDATE >> $HTML
echo "</p>" >> $HTML
# Ajout de la raison du rapport
echo "<p>Raison : $MESSAGE</p>" >> $HTML
# Bloc des serveurs en erreur
TEST=$(cat $SERVER_ERROR | wc -l)
if [ "$TEST" != "0" ]
then
# Création d'un titre
echo "<h3>Liste des serveurs en erreur</h3>" >> $HTML
# Création d'une liste
echo "<ul>" >> $HTML
# Boucle d'ajout des serveurs
for SERVER in $(cat $SERVER_ERROR | uniq | sort)
do
# Ajout du serveur
echo "<li>$SERVER</li>" >> $HTML
done
# Fermeture de la liste
echo "</ul>" >> $HTML
fi
# Bloc des serveurs à ignorer
TEST=$(cat $SERVER_IGNORE | wc -l)
if [ "$TEST" != "0" ]
then
# Création d'un titre
echo "<h3>Liste des serveurs à ignorer</h3>" >> $HTML
# Création d'une liste
echo "<ul>" >> $HTML
# Boucle d'ajout des serveurs
for SERVER in $(cat $SERVER_IGNORE | uniq | sort)
do
# Ajout du serveur
echo "<li>$SERVER</li>" >> $HTML
done
# Fermeture de la liste
echo "</ul>" >> $HTML
fi
# Bloc des sites en erreur
TEST=$(cat $SITE_ERROR | wc -l)
if [ "$TEST" != "0" ]
then
# Création d'un titre
echo "<h3>Liste des sites en erreur</h3>" >> $HTML
# Création d'une liste
echo "<ul>" >> $HTML
# Boucle d'ajout des sites
for SITE in $(cat $SITE_ERROR | uniq | sort)
do
# Ajout du site
echo "<li>$SITE</li>" >> $HTML
done
# Fermeture de la liste
echo "</ul>" >> $HTML
fi
# Bloc des serveurs ayant des sites non activés
TEST=$(cat $SITE_DISABLE | wc -l)
if [ "$TEST" != "0" ]
then
# Création d'un titre
echo "<h3>Liste des serveurs ayant des sites non activés</h3>" >> $HTML
# Création d'une liste
echo "<ul>" >> $HTML
# Boucle d'ajout des serveurs
for SERVER in $(cat $SITE_DISABLE | uniq | sort)
do
# Ajout du serveur
echo "<li>$SERVER</li>" >> $HTML
done
# Fermeture de la liste
echo "</ul>" >> $HTML
fi
# Bloc des sites ignorés
TEST=$(cat $SITE_IGNORE | wc -l)
if [ "$TEST" != "0" ]
then
# Création d'un titre
echo "<h3>Liste des sites ignorés</h3>" >> $HTML
# Création d'une liste
echo "<ul>" >> $HTML
# Boucle d'ajout des sites
for SITE in $(cat $SITE_IGNORE | uniq | sort)
do
# Ajout du site
echo "<li>$SITE</li>" >> $HTML
done
# Fermeture de la liste
echo "</ul>" >> $HTML
fi
# Bloc des sites nouvellement ajoutés
TEST=$(cat $SITE_NEW | wc -l)
if [ "$TEST" != "0" ]
then
# Création d'un titre
echo "<h3>Liste des sites nouvellement ajoutés</h3>" >> $HTML
# Création d'une liste
echo "<ul>" >> $HTML
# Boucle d'ajout des sites
for SITE in $(cat $SITE_NEW | uniq | sort)
do
# Ajout du site
echo "<li>$SITE</li>" >> $HTML
done
# Fermeture de la liste
echo "</ul>" >> $HTML
fi
# Bloc des sites supervisés
TEST=$(cat $SITE_GOOD | wc -l)
if [ "$TEST" != "0" ]
then
# Création d'un titre
echo "<h3>Liste des sites supervisés</h3>" >> $HTML
# Création d'une liste
echo "<ul>" >> $HTML
# Boucle d'ajout des sites
for SITE in $(cat $SITE_GOOD | uniq | sort)
do
# Ajout du site
echo "<li>$SITE</li>" >> $HTML
done
# Fermeture de la liste
echo "</ul>" >> $HTML
fi
# Fin du document
echo "</body></html>" >> $HTML
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ GENERAL ] Création du rapport HTML."
# Envoi du mail
cat $HTML | mail -a "MIME-Version: 1.0" -a "Content-Type: text/html; charset=UTF-8" -s "Rapport de supervision des sites web" $MAIL
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ GENERAL ] Envoi du rapport HTML à $MAIL."
}
##### Déclaration des variables #####
# Mode verbeux pour debogage
VERBOSE="TRUE"
# Chemin du script
EXEC_PATH=/usr/local/batch/webcheck
# Fichier log
LOG_FILE=$EXEC_PATH/check-all-websites.log
# Fichier de rapport HTML
REPORT=$EXEC_PATH/rapport.html
# Adresse mail du restinataire du rapport
MAIL="nekan@shyrkasystem.com"
# Date d'exécution
EXEC_DATE=$(date '+%Y/%m/%d')
# Dépôt externe
DRIVE="drive.shyrkasys.local"
# Login drive
DRIVE_USER="webcheck"
# Mot de passe drive
DRIVE_PASS="P@ssw0rd"
# Dépôt git local
LOCAL=$EXEC_PATH/repository
# User Nagios SiteA & SiteB
USER="nagiosadmin"
# URL Nagios SiteA
NAGIOS_A="http://nagios.sitea.local/cgi-bin/nagios3/status.cgi?host=all&start=0&limit=0"
# Mot de passe Nagios SiteA
PASS_A="P@ssw0rd"
# Filtre de recherche SiteA
PATTERN_A="Webserver HTTP Stats"
# URL Nagios SiteB
NAGIOS_B="https://nagios.siteb.local/nagios/cgi-bin/status.cgi?host=all&start=0&limit=0"
# Mot de passe Nagios SiteB
PASS_B="P@ssw0rd"
# Filtre de recherche SiteB
PATTERN_B="Processus Apache"
# Filtre de recherche Nagios final
PATTERN_FINAL="Site"
# Fichier de réponse pour les serveurs en erreur
SERVER_ERROR=$EXEC_PATH/server-error.list
# Fichier de réponse pour les sites en erreur
SITE_ERROR=$EXEC_PATH/site-error.list
# Fichier de réponse pour les sites supervisés
SITE_GOOD=$EXEC_PATH/site-good.list
# Fichier de réponse pour les sites nouvellement supervisés
SITE_NEW=$EXEC_PATH/site-new.list
# Fichier de réponse pour les serveurs ayant des sites non activés
SITE_DISABLE=$EXEC_PATH/site-disable.list
# Fichier de définitions de services Nagios
SERVICE=/usr/local/nagios/etc/objects/services_webcheck.cfg
# Liste des serveurs à ignorer
SERVER_IGNORE=$EXEC_PATH/server-ignore.list
# Liste des sites à ignorer
SITE_IGNORE=$EXEC_PATH/site-ignore.list
##### Préparation #####
# Purge de l'ancien fichier log
rm -f $LOG_FILE
# Début du traitement
add-log -f $LOG_FILE -l "INFO" -m "[ GENERAL ] Début de l'exécution du script."
# Vérification de l'état de Nagios
PREFLIGHT=$(/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg | grep -i 'Things look okay' | wc -l)
if [[ $PREFLIGHT -eq 1 ]]
then
add-log -f $LOG_FILE -l "INFO" -m "[ NAGIOS ] Nagios correctement configuré."
else
add-log -f $LOG_FILE -l "CRIT" -m "[ NAGIOS ] Nagios en erreur."
send-report -f $REPORT -a $MAIL -m "Erreur critique de configuration de Nagios."
add-log -f $LOG_FILE -l "CRIT" -m "[ GENERAL ] Arrêt prématuré du script."
exit 2
fi
# Vérification du dépôt local
if [ -d $LOCAL ]
then
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ GENERAL ] Dépôt local présent."
# Nettoyage du dépôt
cd $LOCAL
rm -rf ./*
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ GENERAL ] Nettoyage du dépôt."
else
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ GENERAL ] Dépôt git local absent."
# Création du dépôt
mkdir -p $LOCAL
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ GENERAL ] Création du dépôt local."
fi
# Nettoyage du fichier d'erreur
rm -f $SERVER_ERROR $SITE_ERROR $SITE_NEW $SITE_GOOD $REPORT $SITE_DISABLE
touch $SERVER_ERROR $SITE_ERROR $SITE_NEW $SITE_GOOD $REPORT $SITE_DISABLE
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ GENERAL ] Initialisation des fichiers de réponse."
# Création de la liste des serveurs web
APACHE_A=$(curl -s -k -u $USER:$PASS_A $NAGIOS_A | grep -i "$PATTERN_A" | cut -d'&' -f 2 | grep host | cut -d= -f2 | uniq)
APACHE_B=$(curl -s -k -u $USER:$PASS_B $NAGIOS_B | grep -i "$PATTERN_B" | cut -d'&' -f 2 | grep host | cut -d= -f2 | uniq)
APACHE=$(echo $APACHE_A $APACHE_B)
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ GENERAL ] Création de la liste des serveurs Apache."
##### Boucle de traitement des serveurs #####
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ GENERAL ] Début du traitement global."
# Boucle
for SERVER in $(echo $APACHE)
do
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] Début de traitement."
# Vérification de la présence du site dans la liste des sites à ignorer
TEST_IGNORE=$(cat $SERVER_IGNORE | grep -i $SERVER | wc -l)
if [[ $TEST_IGNORE -eq 0 ]]
then
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ $SERVER ] Valide pour traitement."
else
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] Serveur à ignorer."
continue
fi
# Récupération des fichiers du dépôt externe
cd $LOCAL
wget --user=$DRIVE_USER --password=$DRIVE_PASS https://$DRIVE/remote.php/webdav/$SERVER-list -q
wget --user=$DRIVE_USER --password=$DRIVE_PASS https://$DRIVE/remote.php/webdav/$SERVER-state -q
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] Récupération des dernières informations."
# Vérification de la présence de la liste d'état dans le dépôt local
if [ ! -e $LOCAL/$SERVER-state ]
then
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] Pas de fichier d'état."
# Ajout du serveur à la liste des serveurs en erreurs
echo $SERVER >> $SERVER_ERROR
# Passage au serveur suivant
continue
else
# Vérification de la date du fichier d'état
STATE_DATE=$(cat $LOCAL/$SERVER-state | grep 'DATE' | cut -d= -f2)
if [ "$STATE_DATE" != "$EXEC_DATE" ]
then
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] Fichier d'état obsolète."
# Ajout du serveur à la liste des serveurs en erreurs
echo $SERVER >> $SERVER_ERROR
# Passage au serveur suivant
continue
fi
fi
# Vérification de la présence de la liste des sites dans le dépôt local
if [ ! -e $LOCAL/$SERVER-list ]
then
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] Pas de liste de sites."
# Ajout du serveur à la liste des serveurs en erreurs
echo $SERVER >> $SERVER_ERROR
# Passage au serveur suivant
continue
fi
# Vérification des différences enable-available
DIFF=$(cat $LOCAL/$SERVER-state | grep 'DIFF' | cut -d= -f2)
if [ "$DIFF" != "0" ]
then
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] Différences détectés entre les sites disponibles et les sites actifs."
# Ajout du serveur à la liste des serveurs en erreurs
echo $SERVER >> $SITE_DISABLE
fi
# A ce stade, les fichiers du dépôt sont présent et à jour. On attaque donc la boucle de vérification des sites.
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] Fichiers d'état et liste de sites valides."
##### Boucle de traitement des sites #####
for SITE in $(cat $LOCAL/$SERVER-list)
do
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] [ $SITE ] Début du traitement."
# Vérification de la présence du site dans la liste des sites à ignorer
TEST_IGNORE=$(cat $SITE_IGNORE | grep -i $SITE | wc -l)
if [[ $TEST_IGNORE -eq 0 ]]
then
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] [ $SITE ] Valide pour traitement."
else
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] [ $SITE ] Site à ignorer."
continue
fi
# Vérification du l'existence du check Nagios
IS_CHECKED=$(grep -i "$PATTERN_FINAL $SITE" $SERVICE | wc -l)
if [[ $IS_CHECKED -eq 0 ]]
then
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] [ $SITE ] Service Nagios absent."
# Test connectivité du site
HTTP=$(/usr/lib/nagios/plugins/check_http -H $SITE -p 80 -w 1 -c 3)
# Traitement selon le résultat du test
case "$?" in
0|1)
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ $SERVER ] [ $SITE ] Test réussi."
# Vérification du code de retour
CODE=$(echo $HTTP | awk '{print $4}')
case "$CODE" in
400)
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] [ $SITE ] Mauvaise requête, ignoré."
# Ajout à la liste des sites à ignorer
echo $SITE >> $SITE_IGNORE
# Fin de l'option
;;
404)
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] [ $SITE ] Site introuvable, ignoré."
# Ajout à la liste des sites à ignorer
echo $SITE >> $SITE_IGNORE
# Fin de l'option
;;
401)
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] [ $SITE ] Accès non autorisé, ignoré."
# Ajout à la liste des sites à ignorer
echo $SITE >> $SITE_IGNORE
# Fin de l'option
;;
403)
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] [ $SITE ] Accès interdit, ignoré."
# Ajout à la liste des sites à ignorer
echo $SITE >> $SITE_IGNORE
# Fin de l'option
;;
*)
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ $SERVER ] [ $SITE ] Accès autorisé."
# Ajout du check au fichier de configuration de Nagios
echo "" >> $SERVICE
echo "define service{" >> $SERVICE
echo " host_name localhost" >> $SERVICE
echo " use generic-service" >> $SERVICE
echo " service_description Site $SITE" >> $SERVICE
echo " check_command check_website" >> $SERVICE
echo " _URL $SITE" >> $SERVICE
echo "}" >> $SERVICE
# Vérification de la configuration Nagios
PREFLIGHT=$(/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg | grep -i 'Things look okay' | wc -l)
if [[ $PREFLIGHT -eq 1 ]]
then
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ $SERVER ] [ $SITE ] Service Nagios ajouté."
# Ajout du site dans le fichier des sites valides
echo $SITE >> $SITE_GOOD
echo $SITE >> $SITE_NEW
else
# Log
add-log -f $LOG_FILE -l "CRIT" -m "[ NAGIOS ] Erreur de configuration détecté."
# Désactivation du fichier de service
mv $SERVICE $SERVICE.lock
# Nouveau test
PREFLIGHT=$(/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg | grep -i 'Things look okay' | wc -l)
if [[ $PREFLIGHT -eq 1 ]]
then
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ NAGIOS ] Fichier de définition de services désactivé."
add-log -f $LOG_FILE -l "GOOD" -m "[ NAGIOS ] Configuration correcte rétablie."
add-log -f $LOG_FILE -l "CRIT" -m "[ $SERVER ] [ $SITE ] Echec de l'inscription du service."
send-report -f $REPORT -a $MAIL -m "[ WARN ] Arrêt suite à l'échec d'inscription d'un site dans Nagios. Nagios actif."
add-log -f $LOG_FILE -l "WARN" -m "[ GENERAL ] Arrêt prématuré du script."
exit 1
else
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ NAGIOS ] Fichier de définition de services désactivé."
add-log -f $LOG_FILE -l "CRIT" -m "[ NAGIOS ] Configuration correcte non rétablie."
add-log -f $LOG_FILE -l "CRIT" -m "[ $SERVER ] [ $SITE ] Echec de l'inscription du service."
send-report -f $REPORT -a $MAIL -m "[ CRIT ] Arrêt suite à l'échec d'inscription d'un site dans Nagios. Nagios inactif."
add-log -f $LOG_FILE -l "CRIT" -m "[ GENERAL ] Arrêt prématuré du script."
exit 2
fi
fi
# Fin de l'option
;;
# Fin du choix
esac
# Fin de l'option
;;
2)
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ $SERVER ] [ $SITE ] Test en erreur."
# Ajout du site dans le fichier d'erreur
echo $SITE >> $SITE_ERROR
# Fin de l'option
;;
*)
# Log
add-log -f $LOG_FILE -l "UNKN" -m "[ $SERVER ] [ $SITE ] Résultat inattendu lors du test."
# Ajout du site dans le fichier d'erreur
echo $SITE >> $SITE_ERROR
# Fin de l'option
;;
esac
else
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] [ $SITE ] Service Nagios présent."
# Ajout du site dans le fichier des sites valides
echo $SITE >> $SITE_GOOD
fi
# Fin du traitement pour le site
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] [ $SITE ] Fin de traitement."
done
# Fin du traitement pour le serveur
add-log -f $LOG_FILE -l "INFO" -m "[ $SERVER ] Fin de traitement."
done
# Fin de la boucle des serveur
add-log -f $LOG_FILE -l "INFO" -m "[ GENERAL ] Fin de traitement pour tous les serveurs."
##### Suppression des services Nagios obsolètes #####
add-log -f $LOG_FILE -l "INFO" -m "[ GENERAL ] Début du nettoyage des services Nagios obsolètes."
# Création de la liste des sites supervisés selon Nagios
NAGIOS_VISION=$(grep -i "service_description" $SERVICE | awk '{print $3}')
# Variable contenant les sites supervisés selon le script
SCRIPT_VISION=$(cat $SITE_GOOD)
# Liste des sites ne devant plus être supervisés
OUTDATED=$(echo "$SCRIPT_VISION $NAGIOS_VISION" | tr ' ' '\n' | sort | uniq -u | paste -sd"\n")
# Boucle de suppression
for SITE in $(echo $OUTDATED)
do
# Log
add-log -f $LOG_FILE -l "INFO" -m "[ NAGIOS ] [ $SITE ] Suppression du service..."
# Préparation à la suppression
DESCRIPTION_LINE=$(grep -n "service_description[[:space:]]*${PATTERN_FINAL}[[:space:]]${SITE}[[:space:]]*$" $SERVICE | sed 's/://g' | awk '{print $1}')
if [ "$( echo $DESCRIPTION_LINE | grep -v [^0-9])" ]
then
# Balise de début et de fin
START=$(($DESCRIPTION_LINE - 4))
STOP=$(($DESCRIPTION_LINE + 3))
# Suppression du service
sed -i "${START},${STOP}d" $SERVICE
# Vérification de la configuration de nagios
PREFLIGHT=$(/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg | grep -i 'Things look okay' | wc -l)
if [[ $PREFLIGHT -eq 1 ]]
then
# Log
add-log -f $LOG_FILE -l "GOOD" -m "[ NAGIOS ] [ $SITE ] Service supprimé."
else
# Log
add-log -f $LOG_FILE -l "CRIT" -m "[ NAGIOS ] Erreur de configuration détecté."
# Désactivation du fichier de service
mv $SERVICE $SERVICE.lock
# Nouveau test
PREFLIGHT=$(/usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg | grep -i 'Things look okay' | wc -l)
if [[ $PREFLIGHT -eq 1 ]]
then
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ NAGIOS ] Fichier de définition de services désactivé."
add-log -f $LOG_FILE -l "GOOD" -m "[ NAGIOS ] Configuration correcte rétablie."
add-log -f $LOG_FILE -l "CRIT" -m "[ NAGIOS ] [ $SITE ] Echec de la suppression du service."
send-report -f $REPORT -a $MAIL -m "[ WARN ] Arrêt suite à une erreur lors de la suppression d'un site sur Nagios. Nagios actif."
add-log -f $LOG_FILE -l "WARN" -m "[ GENERAL ] Arrêt prématuré du script."
exit 1
else
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ NAGIOS ] Fichier de définition de services désactivé."
add-log -f $LOG_FILE -l "CRIT" -m "[ NAGIOS ] Configuration correcte non rétablie."
add-log -f $LOG_FILE -l "CRIT" -m "[ NAGIOS ] [ $SITE ] Echec de la suppression du service."
send-report -f $REPORT -a $MAIL -m "[ CRIT ] Arrêt suite à une erreur lors de la suppression d'un site sur Nagios. Nagios inactf."
add-log -f $LOG_FILE -l "CRIT" -m "[ GENERAL ] Arrêt prématuré du script."
exit 2
fi
fi
else
# Log
add-log -f $LOG_FILE -l "WARN" -m "[ NAGIOS ] Impossible d'identifier le service."
fi
done
# Fin de suppression des services
add-log -f $LOG_FILE -l "INFO" -m "[ GENERAL ] Fin de suppression des services obsolètes."
# Redémarrage de Nagios
service nagios restart
# Vérification
if [ "$?" == "0" ]
then
# Log et sortie
add-log -f $LOG_FILE -l "GOOD" -m "[ GENERAL ] Redémarrage du service Nagios réussi."
send-report -f $REPORT -a $MAIL -m "[ GOOD ] Arrêt normal du script."
add-log -f $LOG_FILE -l "GOOD" -m "[ GENERAL ] Arrêt normal du script."
exit 0
else
# Log et sortie
add-log -f $LOG_FILE -l "CRIT" -m "[ GENERAL ] Échec du redémarrage du service Nagios."
send-report -f $REPORT -a $MAIL -m "[ CRIT ] Echec du redémarrage de Nagios à la fin du traitement."
add-log -f $LOG_FILE -l "CRIT" -m "[ GENERAL ] Arrêt prématuré du script."
exit 2
fi
# Si à ce stade, on est toujours pas sortie, on indique une erreur inconnue
send-report -f $REPORT -a $MAIL -m "[ UNKNOWN ] Sortie du script sur une erreur inconnue."
add-log -f $LOG_FILE -l "UNKN" -m "[ GENERAL ] Arrêt du script sur une erreur inconnue."
exit 3
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 30 9 * * 1-5 root /usr/local/batch/webcheck/check-all-websites.sh
Tous les services sont définie dans un fichier unique définie par la variable $SERVICE soit /usr/local/nagios/etc/objects/services_webcheck.cfg.
La commande Nagios check_website est définie ainsi :
define command {
command_name check_website
command_line /usr/lib/nagios/plugins/check_http -H $_SERVICEURL$ -p 80 -w 1 -c 3
}
Le programme check_http est fourni avec le package debian nagios-plugins.
J'ai rajouté des services Nagios afin de vérifier si des erreurs étaient signalées dans les fichiers de réponse pour les serveurs en erreur (server-error.list) et pour les sites en erreur (site-error.list). Celà permet d'avoir une alerte directement via Nagios.
define service{
use generic-service
host_name localhost
service_description WebCheck serveurs en erreur
check_command check_server_error
contact_groups sysadmins
}
define service{
use generic-service
host_name localhost
service_description WebCheck sites en erreur
check_command check_site_error
contact_groups sysadmins
}
define command {
command_name check_server_error
command_line /usr/local/batch/webcheck/check-server-error.sh
}
define command {
command_name check_site_error
command_line /usr/local/batch/webcheck/check-site-error.sh
}
#!/bin/bash # Fichier de réponse des sites en erreur FILE=/usr/local/batch/webcheck/server-error.list # Vérification de la présence du fichier de réponse if [ ! -e $FILE ] then # Erreur inconnue echo "UNKNOWN - Fichier de réponse introuvable" exit 3 else # Vérification du nombre le ligne COUNT=$(cat $FILE | wc -l) if [ "$COUNT" == "0" ] then # Tout va bien echo "GOOD - Aucun serveur en erreur" exit 0 else # Erreur echo "WARNING - Il y a $COUNT serveur(s) non supervisé(s)" exit 1 fi fi # Si on est toujours pas sortie alors erreur inconnue echo "UNKNOWN - Erreur inconnue" exit 3
#!/bin/bash # Fichier de réponse des sites en erreur FILE=/usr/local/batch/webcheck/site-error.list # Vérification de la présence du fichier de réponse if [ ! -e $FILE ] then # Erreur inconnue echo "UNKNOWN - Fichier de réponse introuvable" exit 3 else # Vérification du nombre le ligne COUNT=$(cat $FILE | wc -l) if [ "$COUNT" == "0" ] then # Tout va bien echo "GOOD - Aucun site en erreur" exit 0 else # Erreur echo "WARNING - Il y a $COUNT site(s) non supervisé(s)" exit 1 fi fi # Si on est toujours pas sortie alors erreur inconnue echo "UNKNOWN - Erreur inconnue" exit 3
A partir de maintenant, chaque fois qu'un serveur Apache sera sous surveillance, le script nous rappellera d'y déployer le script d'inventaire avec son cron (si c'est pas encore fait). De plus tous les nouveaux sites web seront automatiquement supervisés, tous les sites supprimés verront leur supervision supprimée de même et un rapport journalier nous permettra de suivre l'évolution de cette gestion automatique.