Modifier ou créer un service sur Icinga 2
De base, Icinga2 surveille pas mal de services. Mais ces services ne sont peut-être pas bien configurés pour votre serveur. Il va donc nous falloir les modifier. On va prendre comme exemple dans cet article la modification du port à utiliser pour tester le SSH. Mais avant de se lancer dans la modification des services, on va voir comment fonctionne Icinga2. L'explication qui suit est dans le cadre d'une installation multi-serveur maître/client.
Arborescence des fichiers de configuration
Les fichiers de configuration de Icinga2 se trouvent dans deux répertoires
/etc/icinga2/conf.d/
et
/etc/icinga2/zones.d/master/
Ce répertoire est uniquement présent sur le serveur maître.
Les fichiers que vous serez amené à modifier sont hosts.conf, services.conf, commands.conf et templates.conf. On va voir à quoi servent ces fichiers et comment ils interagissent les uns avec les autres.
- services.conf : liste tous les services. Pour chaque service il faut indiquer quel template, défini dans le fichier templates.conf, utiliser et quelle commande, définie dans commands.conf, lancer pour tester ce service. On indique également une condition (exemple : telle variable doit avoir telle valeur) qui devra être vraie pour que le service soit actif sur tel ou tel host. Comprendre par « host » les serveurs que vous souhaitez surveiller. La valeur de la variable utilisée pour cette condition sera définie dans le fichier hosts.conf. Le but de cette condition, qui est obligatoire, est de pouvoir limiter l’activation de certains services sur des hosts spécifiques uniquement. Par exemple, si on crée un service pour tester que le protocole smtp soit actif, ça n’a aucun sens de le tester sur les hosts n’ayant pas de serveur mail. Ce fichier se trouve dans le répertoire zones.d/master.
- hosts.conf : ce fichier liste votre ou vos hosts. A l’intérieur de chaque host est indiqué des services à tester spécifiques à ce host ou la valeur de variables de condition servant à activer certains services. Il sert également à pouvoir modifier des arguments de tests services. Par exemple, le service check_ssh va tester que le SSH est actif et va tester par défaut le port 22. Si vous utiliser un autre port, vous pouvez l’indiquer dans le fichier hosts.conf et ce pour chaque host. Ce fichier se trouve dans le répertoire zones.d/master.
- templates.conf : comme son nom l’indique, ce fichier regroupe les templates, c’est-à-dire les configurations par défaut (temps entre chaque test, nombre d’essais en cas d’échec, etc), pour chaque type : test sur le serveur (tester s’il est accessible ou non), test des services (http, test de charge serveur, espace libre disque, etc), notification mail, etc. Ce fichier est dans le répertoire conf.d.
- commandes.conf : permet de configurer les commandes à lancer pour réaliser les tests ou les notifications. Ce fichier est dans le répertoire conf.d.
Icinga2, pour faire ces tests, utilise des plugins qui s'installent avec le paquet monitoring-plugins. Ces plugins se trouvent dans le répertoire
/usr/lib/nagios/plugins
Ces plugins sont configurés via les fichiers
/usr/share/icinga2/include/command-plugins.conf
ainsi que les fichiers de configuration présents dans le répertoire
/etc/nagios-plugins/config/
Maintenant qu’on a la théorie, passons à la pratique.
Modifier un service : modifier le port SSH
Comme j’ai indiqué précédemment, il est possible de modifier les arguments de tests existant, comme le numéro de port, l’adresse IP, le répertoire à tester, etc. On va prendre comme exemple le port SSH à utiliser, une modification que la plupart des gens devront faire. Comme il est fortement déconseillé d’utiliser le port par défaut, il y a de forte chance que le port 22 ne corresponde pas à votre port SSH.
Tout d’abord, il nous faut vérifier que le test du SSH, activé par défaut sur Icinga2, permette de modifier le port. Pour ça, lancez la commande suivante :
icinga2 object list --name ssh --type checkcommand
.
La commande icinga2 object list affiche tous les objets actifs. Qu’est-ce qu’un objet ? C’est un service (le test du SSH par exemple) ou une commande (la commande à lancer pour tester le SSH par exemple). “–name” permet de filtrer par nom et “–type” permet de filtrer par type (service ou checkcommand). La ligne de commande que je vous ai fait entrer va donc nous afficher tous les détails de la commande de test du SSH. Ce qui nous intéresse est la partie argument
* arguments % = modified in '/usr/share/icinga2/include/command-plugins.conf', lines 1354:2-1376:2 * -4 * description = "Use IPv4 connection" * set_if = "$ssh_ipv4$" * -6 * description = "Use IPv6 connection" * set_if = "$ssh_ipv6$" * -p * description = "Port number (default: 22)" * value = "$ssh_port$" * -t * description = "Seconds before connection times out (default: 10)" * value = "$ssh_timeout$" * host * order = 1 * skip_key = true * value = "$ssh_address$"
On voit donc que l’argument indiquant le numéro du port à tester est “-p” est que la variable qui correspond à cet argument (on ne peut pas utiliser directement l’argument dans Icinga2) est “ssh_port”. Pour modifier le port à utiliser pour le test du SSH, il nous suffit donc de donner à cette variable pour valeur le numéro du port que l’on utilise pour le SSH. Il nous faut rentrer cette valeur dans le fichier hosts.conf (sur le serveur maître donc). Ouvrez-le.
Repérez la ligne
object Host NodeName {
Elle marque le début de la configuration de votre host. Dans une configuration multi-serveur, cette ligne est présente pour chaque serveur (deux dans mon cas).
Pour modifier la valeur de la variable “ssh_port”, et donc modifier le port du SSH, il suffit de rajouter dans la configuration du host la ligne
vars.ssh_port = numéroport
Si vous souhaitez modifier un argument d’un autre service existant, le principe sera le même :
- Trouvez le nom du service : il suffit d’aller sur l’interface web d’Icinga2
- Tapez la commande
icinga2 object list --name nomduservice --type checkcommand
- Voir dans la partie argument si un argument correspond à ce qu’on veut modifier.
- Récupérez le nom de la variable correspondant à cet argument
- Modifiez la valeur de la variable dans le fichier hosts.conf en ajoutant la ligne
vars.nom_variable = valeursouhaitée
dans le host, entre
object Host NodeName {
et la dernière accolade.
Voyons voir maintenant comment créer un nouveau service afin de tester un protocole ou un processus.
Créer un service
Tester un protocole
Quand on crée un service on doit ajouter une condition qui activera ce service si elle est vraie
Le premier truc à faire, c’est d’identifier quel plugin nous allons utiliser pour notre test. Pour l’exemple, on va choisir le protocole ftp. Parmi tous les plugins, le plugin check_ftp, sert à tester la connexion au serveur ftp.
Il va tout d’abord falloir apprendre comment fonctionne ce plugin et quels arguments il a besoin. Tapez la commande
/usr/lib/nagios/plugins/check_ftp -h
L’aide de ce plugin va s’afficher (tous les plugins fonctionnent de la même manière). C’est le début de l’une des premières lignes de l’aide qui nous intéresse :
check_ftp -H host -p port [-w <warning time>] [-c <critical time>]
Que nous dit cette aide :
- l’argument -H permet d’indiquer à quelle adresse IP se connecter.
- l’argument -p permet d’indiquer quel port utiliser. Il y a peu de chance que vous utilisiez un port différent de celui par défaut pour le serveur ftp. Nous n’aurons donc pas besoin de cet argument
- les arguments -w et -c permettent d’indiquer à partir de quel temps de réponse déclencher, respectivement, un avertissement et une alerte. Comme je souhaite juste un test binaire, le serveur ftp répond/ne répond pas, nous ne les utiliserons pas.
- les autres arguments ne nous seront pas utile.
Ces 4 arguments, qui sont communs à quasiment tous les plugins, sont ceux que vous utiliserez le plus.
Maintenant que nous connaissons les arguments à utiliser, nous allons pouvoir créer la commande qui servira à tester le protocole ftp. Ouvrez le fichier
/etc/icinga2/conf.d/commands.conf
.
A la fin du fichier, rajoutez les lignes suivantes
object CheckCommand "check_ftp" { command = [ PluginDir + "/check_ftp" ] arguments = { "-H" = "$ftp_host$" } }
Expliquons un peu ces lignes :
- object CheckCommand “check_ftp” { : indique que vous allez créer un objet de type commande de test qui s’appelle “check_ftp” (vous pouvez l’appeler comme vous voulez).
- arguments = { : début de la liste des arguments
- “-H” = “$ftp_host$” : création de la variable “ftp_host” (là aussi vous pouvez mettre le nom que vous voulez) qui correspond à l’argument -H.
- Si vous utilisez un port autre que celui par défaut, il aurait fallu créer également une variable pour l’argument “-p” avec la ligne “-p” = “$ftp_port$”.
Pour tous les tests de protocoles (smtp, pop, etc), la création de commande sera sur le même principe.
Dans le cas d'une installation multi-serveur, il faut que la commande créée soit présente dans le fichier commands.conf de tous les serveurs. Dans le cas inverse vous ne serez pas capable de lancer la commande sur le serveur client.
La commande étant créée, on va pouvoir créer le service. Il y a plusieurs manières de créer un service. En voici une. Ouvrez le fichier services.conf. Rajoutez les lignes suivantes à la fin du fichier
apply Service "protocole_ftp" { import "generic-service" check_command = "check_ftp" vars.ftp_host = host.address command_endpoint = host.vars.endpoint assign where host.address }
Expliquons de nouveau ces lignes :
- apply Service “protocole_ftp” { : indique que vous allez créer un service qui s’appelle “protocole_ftp” (vous pouvez modifier le nom).
- import “generic-service” : on importe le template des services, qui se trouve dans le fichier templates.conf. Pour rappel, ce template sert à avoir des valeurs par défaut pour le délai entre chaque test, le nombre d’essai en cas d’échec, etc.
- check_command = “check_ftp” : indique quelle commande on va utiliser pour tester ce service. Le nom de la commande doit être le même que dans le fichier commands.conf.
- vars.ftp_host = host.address : on attribue à la variable “ftp_host” la valeur host.adress qui correspond à l’adresse ip du host définie dans le fichier hosts.conf. Comme ftp_host est la valeur que prendra l’argument “-H”, on se retrouvera bien avec “-H adresseipduhost”.
- command_endpoint = host.vars.endpoint : indique que la commande devra être lancée sur le host (client ou maître) correspondant aux conditions du “assign” et non pas en local sur le serveur maître (utile uniquement en multiserveur).
- assign where host.address : indique la condition qui doit être présente sur le host pour que le service soit actif. Là on a indiqué que si une adresse ip est spécifiée dans le host, cela rendra le service actif. Comme les hosts ont forcément une adresse ip spécifiée, ce service s’appliquera bien à notre host. Cette ligne est obligatoire.
Petite parenthèse sur les conditions. Il est possible de mettre d’autres conditions que celle-là. On pourrait par exemple remplacer cette ligne par
assign where host.vars.serveurFTP == true
Dans ce cas, ce service ne sera actif que si la variable serveurFTP, qui sera déclarée dans le fichier hosts.conf, est vraie. Pour spécifier la valeur de la variable serveurFTP, ouvrez le fichier hosts.conf et ajoutez à la configuration du host la ligne suivante
vars.serveurFTP = true
Fin de la parenthèse.
Il existe également une autre méthode pour créer un service.
Dans le fichier services.conf, créez le service de cette façon :
apply Service for (ftp => config in host.vars.protocole_ftp){ import "generic-service" check_command = "check_ftp" vars += config }
On peut voir que 2 lignes ont été remplacées par rapport à la méthode précédente :
apply Service "protocole_ftp" {
a été remplacé par
apply Service for (ftp => config in host.vars.protocole_ftp){
vars.ftp_host = host.address
a été remplacé par
vars += config
La première ligne signifie que ce service sera activé dans le fichier hosts.conf grâce à la variable protocole_ftp. Elle remplace la ligne “assign where” qui a disparu.
La seconde signifie qu’au lieu de renseigner la valeur des variables, créées dans le fichier commands.conf, dans le fichier services.conf lors de la création du service, on va les renseigner directement dans le fichier hosts.conf. On va rajouter un cas pour expliquer l’utilité de renseigner les variables dans le fichier hosts.conf.
On va garder l’exemple du test du protocole ftp pour rester dans la continuité mais ça ne va pas être un cas très réaliste. Vous vous souvenez que les variables correspondent aux arguments du plugin. Imaginons maintenant que vous hébergiez 3 serveurs ftp et que vous avez modifiés le port du ftp de chaque serveur (cas assez improbable avec un serveur ftp mais c’est juste pour l’exemple). Dans le fichier commands.conf, vous allez créer la commande servant à tester le ftp, comme dans le chapitre 1, et ajouter la ligne
"-p" = "$ftp_port$"
La variable “ftp-port” correspondra donc à l’argument “-p” qui sert à indiquer quel port tester.
Avec la méthode vu précédemment, il vous faudrait créer 3 services dans le fichier services.conf, avec pour chacun une valeur différente pour la variable “ftp_port”. Avec cette nouvelle méthode, vous allez indiquer dans le fichier hosts.conf la valeur que prendra chaque variable déclarée dans la commande du test. Dans notre cas il nous faudra renseigner la valeur des variables “ftp_port” et “ftp_host”. Pour ce faire, il suffit de rajouter dans le fichier hosts.conf les ligne suivante dans la configuration de chaque host pour lesquels vous souhaitez activer ce service (note : il faut forcément que les valeurs des variables soient entre des guillemets)
vars.protocole_ftp["ftp1"] = { ftp_port="numéroport" ftp_host="ipduserveur" } vars.protocole_ftp["ftp2"] = { ftp_port="numéroport" ftp_host="ipduserveur" } vars.protocole_ftp["ftp3"] = { ftp_port="numéroport" ftp_host="ipduserveur" }
Pour info, il est tout à fait possible de déclarer les valeurs des variables à la fois dans services.conf et dans hosts.conf. Reprenons notre exemple avec deux variables, une pour le port et une autre pour l’adresse ip. L’adresse ip est déjà déclarée dans le fichier hosts.conf. Le mieux à faire dans ce cas est donc de déclarer la valeur de la variable “ftp_host” dans le fichier services.conf avec la ligne
vars.ftp_host = host.address
et de ne déclarer que la valeur de la variable “ftp_port” dans hosts.conf car elle sera propre à chaque serveur ftp.
Maintenant vous savez comment tester un protocole et comment remplir les différents fichiers de configuration. On va voir juste un dernier cas, comment vérifier qu’une application tourne sur le serveur.
Tester un processus
Comme vous devez vous en douter, le principe va rester globalement le même que pour tester un protocole. Commençons par le plugin à utiliser. On va utiliser le plugin “check_procs”. Affichez l'aide ce plugin
/usr/lib/nagios/plugins/check_procs -h
Utilisation: check_procs -w <range> -c <range> [-m metric] [-s state] [-p ppid] [-u user] [-r rss] [-z vsz] [-P %cpu] [-a argument-array] [-C command] [-k] [-t timeout] [-v]
Vous connaissez déjà les arguments “w” et “c”, qui servent à déterminer, respectivement, quand lever un avertissement et quand lever une alarme. L’autre argument qui nous intéresse est “C”, qui sert à indiquer quel processus on va tester. Ce plugin va chercher dans tous les processus en cours s’il y en a un ou plusieurs qui correspondent à la valeur de l’argument “-C”.
Le problème est que, comme c’est l’utilisateur “nagios” qui exécute les plugins, il ne pourra voir que les processus auxquels il a accès, ce qui limite considérablement le nombre de processus. On va donc remédier à ce problème.
On va permettre à l’utilisateur “nagios” d’exécuter le plugin “check_procs” avec sudo (donc en admin) sans mot de passe. Je sais que c’est pas très propre d’un point de vue sécurité, mais ça reste très limité vu que seul ce plugin pourra être exécuté en root.
Ouvrez le fichier
/etc/sudoers
Ajoutez la ligne suivante
nagios ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/check_procs
Comme expliqué plus tôt, cette ligne permettra donc à l’utilisateur “nagios” d’exécuter le plugin check_procs, et uniquement ce script, avec les droits root sans mot de passe.
Maintenant que c’est fait, passons à la configuration d’Icinga. Comme précédemment, on va devoir créer la commande servant à tester le processus ainsi que le service.
Ouvrez le fichier commands.conf et ajoutez les lignes suivantes
object CheckCommand "check_processus" { command = ["sudo", PluginDir + "/check_procs" ] arguments = { "-c" = "$critical_arg$" "-C" = "$name_processus$" } }
J’ai appelé la commande “check_processus”. Cette commande va exécuter le plugin “check_procs” avec “sudo” et on va utiliser 2 arguments :
- “-c” qui prendra la valeur de la variable “critical_arg”. Cette valeur indique combien de processus doivent être en cours d’exécution. Cette valeur doit être exprimée sous forme de limite “min:max”. Imaginons que vous vouliez vérifier l’application “toto” et que cette application est lancée 3 fois. Cette valeur devra donc plus tard être déclarée comme suit : “3:3”. Dès qu’Icinga2 trouvera moins ou plus de 3 processus nommés toto, il déclenchera une alarme. Si le nombre d’application lancé est variable, disons entre 3 et 6, vous pourrez déclarer comme valeur “3:6” quand vous créerez le service. La plupart des processus ne se lançant qu’une fois, la valeur que vous mettrez le plus souvent sera “1:1”.
- “-C” qui prendra la valeur de la variable “name_processus”. Cette valeur devra correspondre au nom du processus.
Je n’utilise pas l’argument “-w” car il n’y a pas d’intérêt à avoir des avertissements pour ce genre de test. A part cas très particulier.
Cette commande servira pour tous les tests de processus. Passons maintenant à la création du service.
On va devoir créer un service pour chaque processus que nous voulons tester. Ouvrez le fichier services.conf et ajoutez les lignes suivantes
apply Service "processus_toto" { import "generic-service" check_command = "check_processus" vars.critical_arg = "1:1" vars.name_processus = "toto" command_endpoint = host.vars.endpoint assign where host.address }
Si vous le souhaitez vous pouvez utiliser la méthode vue au chapitre précédent pour créer un seul service générique et renseigner la variable “name_processus et “critical_arg” dans hosts.conf en appelant plusieurs fois le service. Pour ma part j’ai préféré créer plusieurs services car je trouve que c’est plus clair d’avoir un service = une application.