Logo IcingaDans notre précédent article, nous avons installé l’application de supervision Icinga – ainsi que l’interface graphique Icinga Web – sur un serveur dédié. Le moment est venu de passer aux choses sérieuses en utilisant notre installation flambant neuve pour surveiller l’état des hôtes et des services de notre réseau.

La supervision des machines distantes peut s’effectuer grosso modo de deux manières.

  1. à distance et sans rien installer sur la machine à distance, ce qui n’offre que des possibilités de contrôle très limitées (ping, ssh, http).
  2. en installant un agent Icinga sur les serveurs, ce qui permet beaucoup plus de flexibilité dans la supervision.

InfoMême si Icinga est fait pour tourner exclusivement sur les plateformes Linux et Unix, sachez que l’agent Icinga est compatible avec les différentes versions de Windows Server. Vous pouvez donc utiliser Icinga pour surveiller votre parc de serveurs Microsoft.

Configurer le pare-feu

L’agent Icinga communique avec le serveur de supervision via le port 5665. Avant toute chose, je vais donc songer à ouvrir ce port.

$ sudo firewall-cmd --permanent --add-port=5665/tcp
$ sudo firewall-cmd --reload

Préparer le serveur pour les clients

La prochaine étape consiste à préparer le serveur pour les clients. Icinga fournit un assistant de configuration en ligne de commande pour cette tâche, qui peut être invoqué par la commande node wizard.

$ sudo icinga2 node wizard
Welcome to the Icinga 2 Setup Wizard!
We will guide you through all required configuration details.
Please specify if this is an agent/satellite setup 
('n' installs a master setup) [Y/n]: n
Starting the Master setup routine...
Please specify the common name (CN) [sd-100246.dedibox.fr]: [Entrée]
Reconfiguring Icinga...
Checking for existing certificates for common name 'sd-100246.dedibox.fr'...
...
Generating master configuration for Icinga 2.
'api' feature already enabled.
Master zone name [master]: [Entrée]
Default global zones: global-templates director-global
Do you want to specify additional global zones? [y/N]: [Entrée]
Please specify the API bind host/port (optional):
Bind Host []: [Entrée]
Bind Port []: [Entrée]
Do you want to disable the inclusion of the conf.d directory [Y/n]: n
Done.
Now restart your Icinga 2 daemon to finish the installation!
$ sudo systemctl restart icinga2

Quelques remarques sur les différentes options utilisées.

  • Icinga permet la supervision distribuée dans des configurations relativement complexes et distingue entre master, satellite et agent. Dans l’exemple présenté ici, je me servirai uniquement des rôles master et agent. En répondant n (no) à la première question, je définis mon installation comme serveur de supervision « maitre ».
  • Pour la suite et jusqu’à l’avant-dernière question incluse, je confirme les paramètres proposés par défaut, comme le CN (sd-100246.dedibox.fr), le nom de la zone (master), etc.
  • La dernière question concerne l’exclusion du répertoire de configuration /etc/icinga2/conf.d. Ce répertoire contient déjà une configuration par défaut, que nous avons d’ailleurs vue à l’oeuvre lors de la première connexion au tableau de bord. Si nous répondons par l’affirmative à cette question, toute cette configuration initiale est rejetée, ce qui nous oblige à repartir de zéro. J’ai expérimenté avec les deux approches, et pour ma part, j’ai trouvé qu’il était plus simple de partir de la configuration existante en l’adaptant à mes besoins. Quoi qu’il en soit, répondez par n (no) pour ne pas exclure le contenu de conf.d.

Peaufiner la configuration initiale

Dans la configuration proposée par défaut, le serveur Icinga surveille son propre état, ce qui se manifeste sous forme d’une série de tests comme disk, icinga, swap, users, ping4, ping6, procs, load ou ssh qui s’affichent sur le tableau de bord.

Icinga Web 2 Setup

Avant d’aller plus loin et intégrer d’autres machines, je vais modifier cette configuration initiale pour corriger l’affichage d’une erreur, mais surtout pour rendre les tests plus lisibles.

Pour commencer, je vais sauvegarder cette configuration existante pour pouvoir expérimenter plus sereinement et revenir en arrière si je me tire dans le pied.

$ sudo cp -R /etc/icinga2/conf.d/ /etc/icinga2/conf.d.orig

Adapter la configuration à l’IPv4

Comme nous l’avons vu à la fin de notre précédent article sur Icinga, le test ping6 échoue pour la simple et bonne raison que nous n’utilisons que l’IPv4 sur cette machine.

Ouvrez le fichier /etc/icinga2/conf.d/hosts.conf et repérez la stance suivante.

/* Specify the address attributes for checks e.g. `ssh` or `http`. */
address = "127.0.0.1"
address6 = "::1"

Supprimez la ligne qui commence par address6 et enregistrez les modifications.

Testez la validité de la configuration et repérez l’avertissement relatif à ping6.

$ sudo icinga2 daemon -C
... information/cli: Icinga application loader (version: 2.12.0-1)
... information/cli: Loading configuration file(s).
... information/ConfigItem: Committing config item(s).
... information/ApiListener: My API identity: sd-100246.dedibox.fr
... warning/ApplyRule: Apply rule 'ping6' (in /etc/icinga2/conf.d/services.conf:
    34:1-34:21) for type 'Service' does not match anywhere!
... information/ConfigItem: Instantiated 1 NotificationComponent.

Ouvrez /etc/icinga2/conf.d/services.conf et repérez la stance qui définit le service ping6.

apply Service "ping6" {
  import "generic-service"

  check_command = "ping6"

  assign where host.address6
}

Supprimez cette stance, enregistrez les modifications, quittez le fichier et relancez un test de la configuration.

$ sudo icinga2 daemon -C

Tous les tests s’affichent en vert, je vais donc prendre en compte cette nouvelle configuration.

$ sudo systemctl reload icinga2

Le tableau de bord n’affiche plus la moindre erreur.

Icinga Monitoring

Activer le test pour Icinga Web

Le fichier hosts.conf fournit une stance commentée qui permet de superviser l’application Icinga Web elle-même.

/* Uncomment if you've sucessfully installed Icinga Web 2. */
//vars.http_vhosts["Icinga Web 2"] = {
// http_uri = "/icingaweb2"
//}

Je décommente cette stance en renommant le service Icinga Web.

/* Uncomment if you've sucessfully installed Icinga Web 2. */
vars.http_vhosts["Icinga Web"] = {
  http_uri = "/icingaweb2"
}

Là encore, je teste la validité de la syntaxe.

$ sudo icinga2 daemon -C

Je prends en compte la nouvelle configuration.

$ sudo systemctl reload icinga2

InfoVous aurez compris que d’une manière générale, c’est toujours une bonne idée de procéder par petites modifications incrémentales en testant à chaque fois la validité de la configuration.

Au bout de trente secondes, je vois apparaître le nouveau service Icinga Web dans la liste.

Icinga

Améliorer la lisibilité des services de base

Le fichier conf.d/services.conf contient toute une panoplie de services prédéfinis. Je vais éditer ces définitions pour arranger la lisibilité de l’affichage.

Dans la stance qui définit le test ping4, je remplace le nom du service par Ping.

apply Service "Ping" {
  import "generic-service"

  check_command = "ping4"

  assign where host.address
}

Cette modification devra également être renseignée dans le fichier groups.conf, qui regroupe un certain nombre de services.

object ServiceGroup "Ping" {
  display_name = "Ping Checks"

  assign where match("Ping*", service.name)
}

Je retourne dans le fichier services.conf et j’édite la stance qui définit le test relatif à la charge du système.

apply Service "System load" {
  import "generic-service"

  check_command = "load"

  /* Used by the ScheduledDowntime apply rule in `downtimes.conf`. */
  vars.backup_downtime = "02:00-03:00"

  assign where host.name == NodeName
}

Toujours dans cette même logique, je remplace procs par Running processes, swap par Swap usage et users par Logged users.

apply Service "Running processes" {
  import "generic-service"

  check_command = "procs"

  assign where host.name == NodeName
}

apply Service "Swap usage" {
  import "generic-service"

  check_command = "swap"

  assign where host.name == NodeName
}

apply Service "Logged users" {
  import "generic-service"

  check_command = "users"

  assign where host.name == NodeName
}

Un peu plus haut dans le fichier, ssh deviendra SSH.

apply Service "SSH" {
  import "generic-service"

  check_command = "ssh"

  assign where (host.address || host.address6) && host.vars.os == "Linux"
}

Quant au service icinga, on va le renommer en Icinga.

apply Service "Icinga" {
  import "generic-service"

  check_command = "icinga"

  assign where host.name == NodeName
}

J’enregistre les modifications apportées à services.conf et j’ouvre hosts.conf, où je vais également renommer quelques tests. Ainsi, http devient HTTP.

/* Define http vhost attributes for service apply rules in `services.conf`. */
  vars.http_vhosts["HTTP"] = {
    http_uri = "/"
  }

Dans la section qui définit les tests des disques durs, je remplace disk par Hard disk.

/* Define disks and attributes for service apply rules in `services.conf`. */
vars.disks["Hard disk"] = {
  /* No parameters. */
}

En passant, je simplifie l’affichage de ce service en supprimant la stance suivante.

vars.disks["disk /"] = {
  disk_partitions = "/"
}

Toutes ces petites améliorations peuvent vous paraître insignifiantes et simplement cosmétiques. Je vous laisse donc apprécier la lisibilité de l’ensemble après avoir pris en compte l’ensemble des modifications apportées.

Icinga

Connecter un serveur public

Je choisis une première machine publique que je souhaite surveiller. Je commence par générer un ticket pour cette machine.

$ sudo icinga2 pki ticket --cn sd-107066.dedibox.fr
d8b8485685edbfa29ecd9

Je garde cet affichage, j’ouvre un deuxième terminal et je me connecte à la machine sd-107066.dedibox.fr, qui tourne également sous CentOS 7. Pour installer l’agent Icinga – identique au moteur de l’application qui tourne sur notre serveur de supervision – je dois passer par les mêmes étapes que sur le serveur Icinga.

  1. Configurer le dépôt du projet Icinga.
  2. Installer les paquets de base Icinga.
  3. Installer une panoplie de plugins Nagios.
  4. Activer et lancer le démon correspondant.
  5. Ouvrir le port 5665 puisque l’agent et le serveur maître doivent pouvoir communiquer dans les deux sens.
$ sudo yum install -y \
  https://packages.icinga.com/epel/icinga-rpm-release-7-latest.noarch.rpm
$ sudo yum install -y icinga2 icinga2-selinux
$ sudo yum install -y \
  nagios-plugins-{ping,ssh,http,disk,load,procs,swap,users}
$ sudo systemctl enable icinga2 --now
$ sudo firewall-cmd --permanent --add-port=5665/tcp
$ sudo firewall-cmd --reload

Sur la machine client, j’utilise également la commande node wizard pour connecter l’agent au serveur de supervision.

$ sudo icinga2 node wizard
Welcome to the Icinga 2 Setup Wizard!
We will guide you through all required configuration details.
Please specify if this is an agent/satellite setup 
('n' installs a master setup) [Y/n]: [Entrée]
Starting the Agent/Satellite setup routine...
Please specify the common name (CN) [sd-107066.dedibox.fr]: [Entrée]
Please specify the parent endpoint(s) (master or satellite) where this node should connect to:
Master/Satellite Common Name (CN from your master/satellite node): sd-100246.dedibox.fr
Do you want to establish a connection to the parent node from this node? [Y/n]: [Entrée]
Please specify the master/satellite connection information:
Master/Satellite endpoint host (IP address or FQDN): sd-100246.dedibox.fr
Master/Satellite endpoint port [5665]: [Entrée]
Add more master/satellite endpoints? [y/N]: [Entrée]
Parent certificate information:
 Version:             3
 Subject:             CN = sd-100246.dedibox.fr
 Issuer:              CN = Icinga CA
 Valid From:          Sep 28 08:10:54 2020 GMT
 Valid Until:         Sep 25 08:10:54 2035 GMT
 Serial:              8d:93:d2:be:ea:33:32:08:eb:b3:b2:27:be:b4:46:94:fc:a7:4f:f7
 Signature Algorithm: sha256WithRSAEncryption
 Subject Alt Names:   sd-100246.dedibox.fr
 Fingerprint:         DE 17 A5 4D 5C 6D F8 8F 0C 70 E3 64 A4 4E 63 07 
                      73 66 F7 63 69 B0 5E 74 F7 04 F9 32 A4 47 77 65 
Is this information correct? [y/N]: y
Please specify the request ticket generated on your Icinga 2 master (optional).
 (Hint: # icinga2 pki ticket --cn 'sd-107066.dedibox.fr'): d8b8485685edbfa29ecd9
Please specify the API bind host/port (optional):
Bind Host []: [Entrée]
Bind Port []: [Entrée]
Accept config from parent node? [y/N]: y
Accept commands from parent node? [y/N]: y
Reconfiguring Icinga...
Disabling feature notification. 
Make sure to restart Icinga 2 for these changes to take effect.
Enabling feature api. Make sure to restart Icinga 2 for these changes to take effect.
Local zone name [sd-107066.dedibox.fr]: [Entrée]
Parent zone name [master]: [Entrée]
Default global zones: global-templates director-global
Do you want to specify additional global zones? [y/N]: [Entrée]
Do you want to disable the inclusion of the conf.d directory [Y/n]: [Entrée]
Disabling the inclusion of the conf.d directory...
Done.
Now restart your Icinga 2 daemon to finish the installation!
$ sudo systemctl restart icinga2

InfoNotez qu’ici nous avons choisi de désactiver l’inclusion du répertoire conf.d. C’est normal, puisque toute la configuration d’Icinga se trouve sur le serveur de supervision.

Je n’ai plus rien à faire sur le client. Je me reconnecte au serveur et je crée un nouveau répertoire dans l’arborescence d’Icinga.

$ sudo mkdir -v /etc/icinga2/zones.d/master
mkdir: created directory ‘/etc/icinga2/zones.d/master’

Dans ce répertoire, je crée un fichier que je nomme en fonction de mon hôte à surveiller.

// /etc/icinga2/zones.d/master/host-sd-107066.dedibox.fr.conf

object Endpoint "sd-107066.dedibox.fr" {
}

object Zone "sd-107066.dedibox.fr" {
  endpoints = [ "sd-107066.dedibox.fr" ]
  parent = "master"
}

object Host "sd-107066.dedibox.fr" {
  import "generic-host"
  address = "163.172.81.8"
  vars.os = "Linux"
  vars.client_endpoint = name
}

InfoNotez que vous pouvez nommer ce fichier comme vous voulez, du moment qu’il se termine par *.conf. Pour ma part, je lui ai simplement donné un nom parlant.

Là encore, je vérifie si je n’ai pas fait d’erreurs de syntaxe.

$ sudo icinga2 daemon -C
... information/cli: Icinga application loader (version: 2.12.0-1)
... information/cli: Loading configuration file(s).
... information/ConfigItem: Committing config item(s).
... information/ApiListener: My API identity: sd-100246.dedibox.fr
...
... information/cli: Finished validating the configuration file(s).

Icinga ne m’affiche aucune erreur. Je peux donc sereinement prendre en compte la nouvelle configuration.

$ sudo systemctl reload icinga2

Je me connecte à l’interface d’Icinga et je vois mon nouvel hôte en attente (PENDING) d’un premier test de connexion.

Icinga

Définir quelques tests de base

Je vais demander à mon agent de supervision d’effectuer quelques tests assez basiques relatifs à l’état de santé de mon serveur. Toujours dans le répertoire /etc/icinga2/zones.d/master, je vais créer un fichier service-load.conf que je vais éditer comme ceci.

// /etc/icinga2/zones.d/master/service-load.conf
//
// System load check executed on client node
apply Service "System load" {
  import "generic-service"
  check_command = "load"
  command_endpoint = host.vars.client_endpoint 
  assign where host.vars.client_endpoint
}

Je prends en charge la nouvelle configuration après avoir vérifié la syntaxe de mon fichier.

$ sudo icinga2 daemon -C
$ sudo systemctl reload icinga2

J’attends un peu, et je vois apparaître ce test de charge en état d’attente, puis tout en haut dans la colonne de droite.

Icinga

Partant de là, je vais ajouter quelques vérifications de base en suivant la même logique.

J’ajoute la supervision de l’état du disque dur du serveur.

// /etc/icinga2/zones.d/master/service-disk.conf
//
// System disk usage check executed on client node
apply Service "Hard disk" {
  import "generic-service"
  check_command = "disk"
  command_endpoint = host.vars.client_endpoint
  assign where host.vars.client_endpoint
}

Je souhaite en savoir un peu plus sur l’utilisation de la partition d’échange de la machine.

// /etc/icinga2/zones.d/master/service-swap.conf
//
// Swap memory usage check executed on client node
apply Service "Swap usage" {
  import "generic-service"
  check_command = "swap"
  command_endpoint = host.vars.client_endpoint
  assign where host.vars.client_endpoint
}

Voici une vue d’ensemble sur le nombre et l’état des processus du serveur.

// /etc/icinga2/zones.d/master/service-procs.conf
//
// Running system processes check executed on client node
apply Service "Running processes" {
  import "generic-service"
  check_command = "procs"
  command_endpoint = host.vars.client_endpoint
  assign where host.vars.client_endpoint
}

Je peux également être renseigné sur les utilisateurs actuellement connectés au système.

// /etc/icinga2/zones.d/master/service-users.conf
// 
// Logged users check executed on client node
apply Service "Logged users" {
  import "generic-service"
  check_command = "users"
  command_endpoint = host.vars.client_endpoint
  assign where host.vars.client_endpoint
}

InfoJ’aurais pu très bien écrire toutes ces stances dans un seul gros fichier services.conf. Plutôt que de faire cela, j’aime bien répartir ma configuration dans des petits bouts de fichier individuels. Différents chemins mènent à Saint-Bauzille-de-Putois.

À chaque fois que je définis un ou plusieurs nouveaux tests, l’interface d’Icinga met un certain temps – entre 30 secondes et une minute – à les prendre en compte.

Icinga

Connecter un serveur derrière un NAT

Nous venons de configurer une poignée de vérifications de base pour une machine avec une ouverture frontale sur Internet. À partir du moment où nous utilisons l’agent Icinga, nous pouvons également gérer la supervision d’une machine coincée derrière un routeur et normalement inaccessible depuis l’extérieur. Pour ce faire, il suffit qu’elle dispose d’une connexion à Internet pour contacter le serveur de supervision.

Dans l’exemple qui suit, je vais intégrer le routeur proxy.microlinux.lan installé dans mon bureau dans la liste des machines à surveiller depuis mon serveur Icinga.

  1. J’installe l’agent Icinga et les plugins Nagios sur le client.
  2. J’ouvre le port 5665 sur le client.
  3. Je crée un ticket pour proxy.microlinux.lan sur le serveur.
  4. Je connecte le client au serveur en transmettant le ticket au node wizard.

Une fois que la connexion entre l’agent et le serveur est établie, je crée un fichier host-proxy.microlinux.lan.conf sur le serveur.

// /etc/icinga2/zones.d/master/host-proxy.microlinux.lan.conf

object Endpoint "proxy.microlinux.lan" {
}

object Zone "proxy.microlinux.lan" {
  endpoints = [ "proxy.microlinux.lan" ]
  parent = "master"
}

object Host "proxy.microlinux.lan" {
  check_command = "dummy"
  vars.dummy_state = 0 // UP
  vars.dummy_text = "Everything OK."
  vars.os = "Linux"
  vars.client_endpoint = name
}

InfoÉtant donné que je ne peux pas envoyer de ping à mon routeur depuis l’extérieur, je passe par la configuration de ce que l’on appelle un dummy host (ou « hôte bidon »). J’ai trouvé cette astuce dans la documentation officielle d’Icinga, dans la section Host Check Alternatives.

Je vérifie la syntaxe, je recharge la configuration et j’affiche l’interface d’Icinga. Les vérifications en attente s’affichent sur le tableau de bord.

Icinga

Tester SSH sur les machines publiques

Certains tests – comme par exemple le bon fonctionnement du service SSH – ne peuvent être effectués par le serveur de supervision que sur les machines publiques, pour des raisons évidentes. Comment faire alors pour intégrer le service sous certaines conditions, sans que celui-ci ne nous affiche une série d’erreurs pour les machines injoignables depuis Internet ?

Éditez un fichier service-ssh.conf comme ceci.

// /etc/icinga2/zones.d/master/service-ssh.conf
//
// SSH service check executed on public clients
apply Service "SSH" {
  check_command = "ssh"
  command_endpoint = host.vars.client_endpoint
  assign where host.address
}

InfoNotez bien la ligne assign where host.address, qui signifie que le test ne sera exécuté que sur les hôtes dont l’adresse IP est définie dans la configuration. Les dummy hosts ne sont donc pas concernés.

J’ouvre conf.d/services.conf et je supprime la configuration initiale du service SSH.

apply Service "SSH" {
  import "generic-service"

  check_command = "ssh"

  assign where (host.address || host.address6) && host.vars.os == "Linux"
}

Une fois que j’ai pris en compte la nouvelle configuration, je m’aperçois effectivement que le service SSH est supervisé sur la machine publique sd-107066.dedibox.fr, mais pas sur le routeur local proxy.microlinux.lan.

Recevoir des notifications par mail

Vous n’allez probablement pas rester les yeux rivés sur le tableau de bord d’Icinga pour superviser votre parc de machines – à moins que vous ne soyez un grand opérateur avec votre propre datacenter et des gens payés pour faire ça à longueur de journée.

Si votre entreprise est de taille plus modeste, la solution la plus pragmatique consiste à mettre en place les notifications par mail en cas de problème. C’est relativement simple à mettre en oeuvre.

Ouvrez le fichier de configuration d’un de vos hôtes, repérez la stance object Host et ajoutez trois lignes comme ceci.

// /etc/icinga2/zones.d/master/host-sd-107066.dedibox.fr.conf

object Endpoint "sd-107066.dedibox.fr" {
}

object Zone "sd-107066.dedibox.fr" {
  endpoints = [ "sd-107066.dedibox.fr" ]
  parent = "master"
}

object Host "sd-107066.dedibox.fr" {
  import "generic-host"
  address = "163.172.81.8"
  vars.client_endpoint = name
  vars.notification["mail"] = {  
    groups = [ "icingaadmins" ]  
  }   
}

Enregistrez les modifications, ouvrez le fichier conf.d/users.conf et renseignez l’adresse mail vers laquelle vous souhaitez envoyer les notifications.

object User "icingaadmin" {
  import "generic-user"

  display_name = "Icinga 2 Admin"
  groups = [ "icingaadmins" ]

  email = "info@microlinux.fr"
}

object UserGroup "icingaadmins" {
  display_name = "Icinga 2 Admin Group"
}

Icinga

Une fois que vous avez pris en compte les modifications, il n’y a plus grand-chose à faire. À partir du moment où Icinga détecte un service dans un état critique – ou lorsqu’il n’arrive plus à joindre un hôte distant – il vous envoie une notification qui ressemble à ceci.

Icinga notificationSi jamais il ne s’agissait que d’une interruption de service momentanée, Icinga vous avertit également dès que les choses retournent à la normale.

Icinga notification

Pour aller plus loin

L’installation et la prise en main d’un serveur de supervision avec Icinga n’est pas une opération triviale, comme vous avez pu le voir. J’ai fait de mon mieux pour vous faciliter la tâche de manière à ce que vous soyez capable de franchir le pas et configurer « quelque chose qui marche ».

L’installation que nous avons effectuée est relativement basique, mais elle est tout à fait utilisable en production. Considérez-la comme un point de départ pour vos futures configurations. Réfléchissez aux différents services et processus que vous souhaitez garder à l’oeil, et faites une recherche dans la multitude de plugins Nagios disponible.

Enfin, n’hésitez pas à éplucher la documentation officielle d’Icinga, qui vous impressionnera un peu moins à présent.


La rédaction de cette documentation demande du temps et des quantités significatives de café espresso. Vous appréciez ce blog ? Offrez un café au rédacteur en cliquant sur la tasse.

 

Catégories : Serveur

0 commentaire

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *