isitdown

2022-02-09T14:11:37Z

Pour être automatiquement averti si mon site ou un des services que j'héberge est en panne, j'ai configuré un petit script que j'appelle périodiquement sur ma VM chez openbsd.amserdam : il s'appelle isitdown.

Vous pourrez le télécharger ici :

/code/isitdown.tgz

Voici la ligne ajouté à mon crontab afin de faire tourner ce script toutes les heures:

~ * * * * /home/prx/bin/isitdown /home/prx/isitdown.cfg

Comme vous le voyez, il prend en entrée un ficher "isitdown.cfg". On pourrait l'appeler comme on veut, il s'agit d'un bête fichier texte rempli de lignes ressemblant à :

# services persos
si3t.ch www prx@si3t.ch
si3t.ch smtp prx@si3t.ch
si3t.ch imaps prx@si3t.ch
si3t.ch domain prx@si3t.ch
si3t.ch xmpp-server prx@si3t.ch
# Les cop(ain|ine)s
unbon.cafe 1965 foo@bar
automario.eu 443 foo@bar
linuxmario.net 443 foo2@bar
vinishor.xyz 443 foo@bar
...

Le script va simplement lancer un netcat sur chacun de ces domaines au port correspondant. Le port peut être un nombre ou bien le nom du service défini dans /etc/services.

En cas d'échec, l'adresse mail de la ligne correspondante est notifiée.

Par la même occasion, on garde trace de l'heure à laquelle le service était inaccessible. Ça permettra d'éviter de spammer une adresse en vérifiant si un fichier contenant cette information existe déjà.

Voici à quoi ressemble le script avec des commentaires :

#!/bin/sh
# Author: prx <prx@si3t.ch>
# licence: MIT
# read $1 with lines like : 
# <domain> <port> <email>
# adresse mail de l'expéditeur
fromaddr="$(whoami)@$(hostname)"
# dossier où on gardera trace des échecs
db=$HOME/.isitdown
# on crée ce dossier s'il n'existe pas déjà
test -d "${db}" || mkdir -p "${db}" # create db directory if needed
# on envoie le fichier de configuration en supprimant les commentaires avec grep
# puis on met chaque champ dans les variables domain port et email
grep -v "^#" "$1" | while read domain port email
do
	# vérifications idiotes pour s'assurer qu'il ne manque pas un champ
	test -z "$domain" && continue
	test -z "$port" && continue
	test -z "$email" && continue
	# on enregistre à quoi ressemblera le fichier qui contiendra l'heure d'un éventuel échec
	r="${db}/${domain}-${port}"
	# hop, netcat tente une connexion
	/usr/bin/nc -zw1 "${domain}" "${port}" >/dev/null 2>&1
	# netcat a échoué
	if [ $? -ne 0 ]; then
		# on vérifie si un fichier attestant d'un échec précédent existe
		if [ ! -f "${r}" ]; then
			# ce fichier n'existe pas, on alerte la personne concernée
			printf "Connection to %s port %s failed 😨\nIs it down?"\
						"$domain" "$port" \
				| /usr/bin/mail -s "ISITDOWN: ${domain} down?" \
						-r "${fromaddr}" "${email}"
			# On enregistre la date dans ce fichier
			date "+%Y-%m-%d %H:%M" > "${db}/${domain}-${port}"
		fi
	else
		# la connexion a réussi
		if [ -f "${r}" ]; then
			# La connexion avait échoué auparavant, on prévient que tout est revenu à la normale
			printf "%s on port %s is back online 😃\nIt was down since %s."\
						"$domain" "$port" "$(cat ${r})" \
				| /usr/bin/mail -s "ISITDOWN: ${domain} up :)" \
							-r "${fromaddr}" "${email}"
			rm "${r}"
		fi
	fi
done

Si vous le souhaitez, je peux ajouter le nécessaire à ma liste pour vous notifier si votre serveur a un souci. Juste, envoyez moi un mail ;)

Une réaction?

Envoyez votre commentaire par mail.

Mode d'emploi de la liste de diffusion pour recevoir les réponses.