Sommaire

Nagios : Notification via Telegram

Prérequis

Avant de suivre le tutoriel

Dans cette version du tutoriel, je ne présente pas comment créer un bot Telegram. Je montre tout de même comment récupérer l’ID du groupe de chat. Pour suivre ce tutoriel, il vous faut donc :

  • Un bot Telegram
  • La clé de l’API
  • Un groupe Telegram avec votre bot

Récupération de l’ID du groupe Telegram

La méthode la plus simple et d’aller sur l’interface web de Telegram. Cliquez ensuite sur votre groupe est copier le lien de votre navigateur.

Le mien est la forme :

https://web.telegram.org/#/im?p=g123456789

L’ID de mon groupe est donc le : 123456789. Vous l’aurez compris, j’ai remplacé mon ID de groupe afin qu’il reste confidentiel.

Maintenant qu’on a toutes les informations nécessaires pour la configuration, on va d’abord valider à la main le système de notification avant de le passer en production.

Installation et tests

Script de notification

Pim van den Berg a écris un script en Python pour cela et l’a publié sur Github. C’est donc son script que nous allons utiliser.

On télécharge donc ce script et on le rend exécutable :

1
2
wget https://raw.githubusercontent.com/pommi/telegram_nagios/master/telegram_nagios.py
chmod u+x telegram_nagios.py

On test donc le lancement du script à la main de la manière suivante :

1
./telegram_nagios.py --token 999999999:AAaaAaAaaaaAaaAAa-Z_9Tg7KO-92z14iOK --object_type service --contact "-123456789" --servicestate "OK" --hostname "Martin_Routeur_King" --servicedesc "PING" --output "PING OK - Packet loss = 0%, RTA = 0.45 ms"

Remplacer donc la chaine 999999999:AAaaAaAaaaaAaaAAa-Z_9Tg7KO-92z14iOK par votre clé d’API Telegram et 123456789 par votre ID de groupe (conservez bien le tiret avant l’identifiant).

Le premier lancement me une erreur comme quoi ne n’ai pas le module “twx.botapi” d’installé. On corrige donc cela par l’installation du module. Après plusieurs essaie, la seul commande qui me donne le moins d’erreur est la suivante :

1
sudo -H python -m pip install twx.botapi

J’ai tous de même les erreurs suivantes :

Building wheels for collected packages: twx.botapi
Running setup.py bdist_wheel for twx.botapi … error
[…]
error: [Errno 2] No such file or directory: ‘LICENSE.txt’

Failed building wheel for twx.botapi
Running setup.py clean for twx.botapi
Failed to build twx.botapi
Installing collected packages: twx.botapi
Running setup.py install for twx.botapi … done

Je relance quand même le script et cela fonctionne !

Edit : La commande d’installation qui n’apporte pas d’erreur est sudo -H python -m pip install twx.botapi --no-cache-dir. De cette manière, PIP utilise le “setup.py” en lieu et place du systeme de package wheel.

On tests donc les différents états Nagios :

1
2
3
4
5
6
7
./telegram_nagios.py --token 999999999:AAaaAaAaaaaAaaAAa-Z_9Tg7KO-92z14iOK --object_type service --contact "-123456789" --servicestate "WARNING" --hostname "Orc Chasseur" --servicedesc "petstate" --output "WARNING - Mon pet est mort"

./telegram_nagios.py --token 999999999:AAaaAaAaaaaAaaAAa-Z_9Tg7KO-92z14iOK --object_type service --contact "-123456789" --servicestate "CRITICAL" --hostname "Toilette" --servicedesc "toiletpaper" --output "CRITICAL - Il n'y a plus de papier !"

./telegram_nagios.py --token 999999999:AAaaAaAaaaaAaaAAa-Z_9Tg7KO-92z14iOK --object_type host --contact "-123456789" --hoststate "DOWN" --hostname "localhost" --hostaddress "127.0.0.1" --output "PING CRITICAL - Packet loss = 100%"
  
./telegram_nagios.py --token 999999999:AAaaAaAaaaaAaaAAa-Z_9Tg7KO-92z14iOK --object_type host --contact "-123456789" --hoststate "UP" --hostname "localhost" --hostaddress "::1" --output "PING OK - Packet loss = 0%, RTA = 0.16 ms"
/nagios-notification-via-telegram/img/image-37.webp
Message Telegram de mon bot “Jarvis” sur mon groupe

Je vous conseille de tester cela avec l’utilisateur Nagios. Pour ma part, je n’ai pas eu de problème.

On va donc maintenant faire le nécessaire afin le passer en production.

Configuration

Enregistrement des secrets

On va d’abord enregistrer la clé d’API dans le fichiers de ressources (/usr/local/nagios/etc/resource.cfg). J’y ajoute donc la ligne suivante :

1
2
3
# Telegram
## API
$USER10$=999999999:AAaaAaAaaaaAaaAAa-Z_9Tg7KO-92z14iOK

J’utilise le “USER” 10 et car les précédant sont déjà utilisés dans ma configuration. Libre à vous de prendre un autre numéros.

Au début, j’avais aussi stocké l’identifiant du groupe, mais au final cela n’a pas fonctionné. Cela est surement dû au fait que cette macro est traduite en une autre macro ("$CONTACTPAGER$") dans le processus de notification. Les macros ne doivent fonctionner qu’en traduction directe.

Commandes

Au préalable, on copie le script et on rend notre utilisateur Nagios propriétaire du fichier :

1
2
sudo cp telegram_nagios.py /usr/local/nagios/libexec/
sudo chown nagios:nagios /usr/local/nagios/libexec/telegram_nagios.py

On édite donc le fichier de commandes (/usr/local/nagios/etc/objects/commands.cfg) pour lui ajouter les lignes suivantes :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
###########################################
#
# TELEGRAM NOTIFICATION COMMANDS
#
###########################################

define command {
    command_name     notify-host-by-telegram
    command_line     $USER1$/telegram_nagios.py --token $USER10$ --object_type host --contact "$CONTACTPAGER$" --notificationtype "$NOTIFICATIONTYPE$" --hoststate "$HOSTSTATE$" --hostname "$HOSTNAME$" --hostaddress "$HOSTADDRESS$" --output "$HOSTOUTPUT$"
}
define command {
    command_name     notify-service-by-telegram
    command_line     $USER1$/telegram_nagios.py --token $USER10$ --object_type service --contact "$CONTACTPAGER$" --notificationt
ype "$NOTIFICATIONTYPE$" --servicestate "$SERVICESTATE$" --hostname "$HOSTNAME$" --servicedesc "$SERVICEDESC$" --output "$SERVICEOUTPUT$"
}

N’oubliez pas de modifier le numéro de la macro “USER” si vous n’utilisez pas le même que moi.

Contact

On créer donc notre contact pour le groupe Telegram en éditant le fichier /usr/local/nagios/etc/objects/contacts.cfg. On y ajoute les lignes suivantes :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
define contact {
    contact_name                    telegram_group
    pager                           -123456789
    service_notification_commands   notify-service-by-telegram
    host_notification_commands      notify-host-by-telegram
    host_notifications_enabled      1
    service_notifications_enabled   1
    service_notification_period     24x7
    host_notification_period        24x7
    service_notification_options    w,u,c,r
    host_notification_options       d,u,r
}

N’oubliez pas de modifier la valeur de pager par votre identifiant de groupe avec un tiret au début.

Les services notifie pas défaut le groupe de contact “admins”. J’ai donc ajouté “telegram_group” en tant que membre du groupe :

1
2
3
4
5
define contactgroup {
    contactgroup_name       admins
    alias                   Nagios Administrators
    members                 telegram_group
}

Si votre groupe “admin” doit contenir plusieurs membres, séparez les éléments pas des virgules.

Validation de la configuration

On valide donc notre configuration avant de relancer Nagios :

1
2
sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
sudo systemctl restart nagios.service

Résultats

Notre service de notification via Telegram est maintenant actif. Je vais maintenant attendre les problèmes ou les provoquer.

Création de fausses alertes

Pour tester simplement, on va utiliser le plugin check_dummy. Comme son nom l’indique, ce check est stupide ! Si on lui envoie “0”, il répond “OK”. Voici quelques exemples :

Usage:
check_dummy [optional text]

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ ./check_dummy 0
OK

$ ./check_dummy 2
CRITICAL

$ ./check_dummy 4 salut
UNKNOWN: Status 4 is not a supported error state

$ ./check_dummy 3 salut
UNKNOWN: salut

$ ./check_dummy 1 azerty
WARNING: azerty
$ echo $?
1

Le problème d’implémenté simplement cela dans Nagios, c’est qu’à chaque fois qu’on veut changer de valeur de retour il faut modifier la configuration, le vérifier et relancer le service.

J’ai trouvé une astuce en envoyant en paramètre le contenu d’un fichier. Si j’écris “0” dans un fichier, le service passe en “OK”. Si je modifie le contenu du fichier par “1”, le service passe en “WARNING”.

J’ai donc créer le fichier dummy.txt avec le contenue “0” que j’ai mis avec les scripts (sa m’évite d’avoir à gérer les problèmes de droits).

1
2
echo 0 | sudo tee /usr/local/nagios/libexec/dummy.txt
sudo chown nagios:nagios /usr/local/nagios/libexec/dummy.txt

On créer donc la commande ainsi que le service :

1
2
3
4
5
# Dummy check (notifications tests)
define command {
    command_name    my_check_dummy
    command_line    $USER1$/check_dummy $(cat /usr/local/nagios/libexec/dummy.txt)
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
define service {
    use                             generic-service
    host_name                       localhost
    service_description             Dummy check
    check_period                    24x7
    check_interval                  1
    max_check_attempts              1
    retry_interval                  1
    notifications_enabled           1
    notification_options            w,u,c,r
    notification_interval           0
    notification_period             24x7
    check_command                   my_check_dummy
}

J’ai donc ajouté le service à mon serveur Nagios (“localhost”). Il est testé toutes les minutes et envoie immédiatement la notification. Une seule notification est envoyée par changement d’état.

Après avoir refait les étapes de changement de configuration et vu sur Nagios que mon service est bien “OK”, je teste les états avec les commandes suivantes :

1
2
3
echo "2 Oups" | sudo tee /usr/local/nagios/libexec/dummy.txt
echo "1 AHHHH" | sudo tee /usr/local/nagios/libexec/dummy.txt
echo "0 Parfait !" | sudo tee /usr/local/nagios/libexec/dummy.txt
/nagios-notification-via-telegram/img/image-42.webp
Notifications sur l’application Telegram

Je n’ai pas testé les changements d’états des hôtes (la flemme…). Si vous voulez les tester il vous suffit d’appliquer le même principe pour un hôte en remplaçant votre “check-host-alive” par “my_check_dummy”.