title: Supervision: Initiation
description: Bases de la supervision: découverte de SNMP, et de Zabbix
published: true
date: 2024-02-07T20:45:33.434Z
tags:
editor: markdown
dateCreated: 2024-02-07T20:41:24.937Z
Définitions et concepts
Introduction
La supervision d'une infrastructure a pour but de garantir la disponibilité et les niveaux de service de cette infrastructure. Pour cela, elle doit pouvoir surveiller l'infrastructure en collectant des /métriques/ pertinentes, tant matérielles qu'applicatives, et aussi être en mesure d'informer et d'alerter en cas de situation anormale, et ce, afin de garantir la remontée de l'alerte et un temps d'intervention (ou pire, d'indisponibilité du service) minimal.
Les alertes de supervision sont basées sur des mesures effectuées à intervalle réguliers qui seront effectuées par un ou plusieurs outil(s) de /métrologie/ et qui seront comparées avec des seuils prédéfinis.
De même, certaines solutions de supervision peuvent intégrer des outils automatisés de résolution d'incidents mineurs (par exemple, relancer un service automatiquement. On peut faire une analogie avec le fonctionnement d'orchestrateurs comme Docker Swarm ou Kubernetes qui relançeront automatiquement un container s'étant mis "en carafe"), ce qu'on nomme /Supervision 2.0/ ou /hypervision/.
On peut distinguer - hors supervision industrielle - trois grands types de supervision:
- La supervision Système, qui va surveiller les ressources systèmes (cpu, mémoire, stockage, Entrées/Sorties (disques, réseau, etc))
- La supervision Réseau, qui va contrôler la disponibilité des services en ligne, les débits, la QoS, etc
- La supervision Applicative, qui va vérifier le bon fonctionnement des applicatifs. En effet, on peut avoir un serveur de BDD avec les indicateurs Système "au vert" (CPU qui ne fait rien, RAM peu utilisée, etc), alors que le service de bases de données (MariaDB, postgreSQL, MongoDB (euh, non, lui, à fuir comme la peste en prod')) ne s'exécute plus.
Avantages de la Supervision
La supervision possède de nombreux avantages et est indispensable à tout système d'information sérieux:
En effet, un système efficace de supervision va permettre:
- D'être réactif, c'est à dire averti en temps réel. Aucun système d'information n'est fiable à 100%. Il y aura toujours un élément faillible. Un disque dur qui rend l'âme, un câble réseau qui se débranche, un CPU qui chauffe trop ou une alimentation défaillante. Hors, il est préférable d'être alerté du problème /avant/ que les utilisateurs s'en rendent compte - à fortiori lorsqu'il s'agit de leur outil de travail. La supervision doit nous permettre de pouvoir remonter à la source d'un problème, ou à minima de pouvoir cerner les causes potentielles du problème.
- D'être proactif: La supervision va nous permettre d'anticiper les problèmes, en nous donnant une visibilité sur les signes annonciateurs de futurs problèmes: disques à 80% pleins, bande passante commençant à être "limite", charge de plus en plus importante nécessitant un redimensionnement de l'infrastructure, etc… On ne peut être proactif
qu'en étant bien informé.
Par là, on va pouvoir:
- Améliorer la disponibilité du système d'information en anticipant de possibles pannes
- Anticiper l'évolution de l'infrastructure en observant sa montée en charge dans le temps
- Surveiller l'infrastructure au quotidien.
Métrologie
Un outil de métrologie a pour fonction de mesurer les ressources du système d'information. Il est en général intégré à la solution de supervision.
Lorsque l'on met en place nos outils de métrologie, il est nécessaire de définir quelles métriques sont pertinentes ainsi que les méthodes de mesure permettant de collecter ces métriques.
On utilise deux types de mesures:
- Les mesures dites passives: SNMP, WMI, agents de collecte (telegraf, collectd, etc) qui remontent les informations aux collecteurs de métriques depuis les machines surveillées vers la solution de supervision. Typiquement, ce qu'une solution comme collectd/influxDB/grafana effectue.
- Les mesures dites actives: ping, traceroute, curl, connexion à distance et exécution de commandes depuis le système de supervision vers les machines monitorées. Typiquement, ce qu'une solution comme HP SiteScope effectue.
Métrique
Une métrique, c'est une caractéristique mesurable de l'infrastructure, définie de façon rigoureuse et précise. Elle permet de déterminer si une situation est normale ou anormale, et d'effectuer des comparaisons:
- Dans le temps: est-ce que le serveur de bases de données avait le même load hier? la semaine dernière? Sa variation dans le temps
est-elle normale? - entre deux liens ou chemins: est-ce plus rentable de router par ce sous-réseau ou un autre?
Exemples de logiciels de supervision
Il existe de nombreux logiciels de supervision, libres et propriétaires, certains monolithiques, d'autres modulaires, d'autres n'étant que des "briques" que l'on peut ajouter les uns aux autres pour former notre système de supervision (exemple: collecteur de données (collectd, telegraf, statsd, cadvisor)-> agrégateur de données (Carbon, InfluxDB) -> affichage (Grafana)).
Parmi les plus connus:
- Bien évidemment, NAGIOS


- Zabbix

-
Centreon
-
Shinken

-
CACTI
-
MUNIN
-
collectd/statsd (applicatif)/telegraf/cadvisor/InfluxDB ou Graphite (Carbon)/Grafana


On peut aussi collecter des informations autres que purement "informatiques", afin de voir l'évolution d'une plateforme. Bon évidemment, c'est le moment où mon "check" du temps de réponse est out (il faut donc que je le mette à jour )
SNMP: Simple Network Management Protocol
Concepts et Définitions
Définition
SNMP, Simple Network Management Protocol, soit "protocole simple de gestion du réseau" (je me demande souvent si le "simple" n'est pas ironique ici:)) est un protocole de communication, en UDP, qui utilise, pour les clients, le port 161, et pour le(s) serveur(s) de management, le port 162. Il permet de superviser et diagnostiquer à distance différents équipements, du routeur au serveur en passant par les commutateurs.
SNMP est basé sur trois éléments principaux:
- Un NMS (Network Management Station - le serveur) qui va exécuter des requêtes de management sur les...
- agents qui permettent de récupérer différents objets contenant des valeurs (uptime, load, bande passante, éléments de configuration, statistiques diverses, etc). Ces agents sont exécutés sur les ... - noeuds, qui sont, typiquement, les machines que nous voulons superviser (routeurs, serveur, commutateurs, etc)
Typiquement, on utilisera SNMP pour administrer les équipements (on peut exécuter des scripts à distance via SNMP) et pour surveiller le comportement du matériel.
Versions du protocole SNMP
Il existe trois versions du protocole SNMP (on utilisera de préférence la v3 pour des raisons évidentes, mais il reste la possibilité de devoir superviser des matériels plus anciens utilisant des versions antérieures du protocole):
- SNMPv1: non sécurisé (pas d'authentification autre que la communauté SNMP définie dans la configuration. Les premières RFCs (Request For Comments - Documents de l'IETF définissant les standards et protocoles utilisés dans les communications. Si toutes les RFCs ne sont pas des standards, tous les standards de communication informatique sont des RFCs) de SNMPv1 remontent à 1988, il s'agit des RFCs 1065 à 1067, remplacées par les RFCs 1155 à 1157. la RFC1156 a été rapidement remplacée par la RFC 1213. Il s'agit d'un protocole obsolète, du fait de son âge et de ses (grosses) lacunes de sécurité. Il a été remplacé par…
- SNMPv2 (RFCs 1441 et 1452), qui améliore SNMPv1 en termes de performances, sécurité et confidentialité. Les premières versions du protocole proposaient un système d'authentification jugé trop complexe et ont été remplacées par SNMPv2c qui réintroduit la notion de communautés (publiques et privées, public et private) de SNMPv1, avec les problèmes de sécurité que cela comporte (RFC 1901 et 1908). À noter, il existe SNMPv2u qui réintroduit la notion d'utilisateurs SNMP (RFC 1909 et 1910) tout en restant moins complexe
que SNMPv2. Ces versions ont depuis été remplacées par… - SNMPv3 (RFCs 3411 et 3418, 2004), qui ne modifie pas le protocole SNMP lui même (bien qu'il change certaines conventions), mais ajoute à l'authentification des utilisateurs le chiffrement tant au niveau identification que transmission des données: les paquets sont chiffrés entre le superviseur et les agents, l'intégrité des données transmises est vérifiée par un algorithme de /hashage/, et l'authentification des utilisateurs par login/mot de passe est elle aussi chiffrée. À l'origine les algorithmes utilisés étaient DES pour le chiffrement et MD5 pour l'authentification et le hashage, il est cependant (pour des raisons évidentes de sécurité) d'utiliser AES (CFB-AES-128 pour être précis) et SHA (malheureusement, uniquement SHA1) en lieu et place des précédents qui restent utilisables notamment pour des raisons de
compatibilité.
SNMPv3 permet 3 modes de communication:
- NoAuthNoPriv: pas d'authentification, pas de chiffrement. Oups.
- AuthNoPriv: authentification mais pas de chiffrement. Oups bis.
- AuthPriv: authentification ET chiffrement, ça y est, on tient le bon bout!
MIB

SNMP utilise ce qu'on appelle des MIBs (Management Information Base, qui constituent une base de données rassemblant les objets de gestion et supervision (OID, on y revient plus bas) des nœuds de notre réseau de communication. Les objets en question sont définis selon un ensemble de la syntaxe Abstrace Syntax Notation One, ASN.1, appelé Structure de Gestion de l'Information, dans sa version 2 (RFC 2578).
Cette base de données est hiérarchique (structure en forme d'arbre) et chaque entrée (Managed Object) de cette base de données est associée à un Object IDentifier, OID.
Un Managed Object peut être de deux types:
- Scalaire: objet correspondant à une valeur et une seule. Cette valeur peut être
un entier, une chaîne de caractères, etc - Tabulaire: correspond à un ensemble d'objets pouvant être organisés sous forme de tableau. Par exemple, la liste des ports ouverts sur une machine et l'adresse IP de l'interface réseau (ou des interfaces réseau) associée(s).
Ce qui nous amène à la définition de ce qu'est un Object IDentifier. Attention, ça picote.
OID
Un OID, identificateur d'objet, est tout d'abord un standard de l'ITU (International Telecommunications Union) et de l'ISO/IEC pour nommer tout objet, concept ou "truc" (si si) avec un "nom" persistant qui ne soit pas ambigu. Ces OID sont organisés de façons hiérarchiques et identifiés par une suite de numéros uniques.
Un OID commence toujours par soit:
- 0: ITU-T
- 1: ISO
- 2: joint-iso-itu-t
En règle générale, on utilisera rarement des objets commençant par 0 et 2. (je n'en ai jamais rencontré).
Par exemple, l'OID de tout matériel Cisco (le "top-level" de Cisco dans l'arbre des OIDs) commence par:
1.3.6.1.4.1.9 - atchoum! Qu'est ce que ça veut dire?
-
- : ISO OID
- 1.3: ISO Identified Organization
- 1.3.6: Département de la Défense des USA (DOD)
- 1.3.6.1: OID Internet (d'où le DOD précédent, référence à ARPANET)
- 1.3.6.1.4: Internet Private
- 1.3.6.1.4.1: Entreprise privée enregistrée à l'IANA
- 1.3.6.1.4.1.9: Cisco top-level tree
le site http://www.oid-info.com (eh oui, http sans S… shrug) permet de
parcourir l'arbre complet des OIDs.
Mise en place de SNMP
Pour cela, nous allons avoir besoin de deux VMs - Debian Trixie SVP . La première sera notre VM superviseur (aka NMS), et la seconde constituera notre premier nœud.
Installation sur le NMS et sur le node
Sur notre VM "superviseur" (NMS), nous allons installer snmp ainsi que snmp-mibs-downloader, qui contient des informations propriétaires (sigh) permettant l'accès à la plupart de l'arbre des OIDs:
Note: il est fort possible que vous deviez activer les dépôts non-free sur Debian. Si vous ne savez pas comment faire... demandez moi
NMS $ sudo apt update && sudo apt install snmp snmp-mibs-downloader
Sur notre VM "node1", nous allons juste installer snmpd:
node1 $ sudo apt update && sudo apt install snmpd
Configuration du NMS
La configuration est ici très simple. On va simplement éditer le fichier de configuration de snmp pour qu'il prenne en compte nos MIBs propriétaires (sigh):
NMS $ sudo vim /etc/snmp/snmp.conf
# commenter la ligne "mibs :":
# mibs :
Et... c'est tout! Je vous rassure, ça va être un peu plus touffu pour la configuration du node.
Configuration de snmpd sur notre node /node1/
node1 $ sudo vim /etc/snmp/snmpd.conf
La première chose à faire va être de configurer l'adresse (et donc l'interface réseau) sur laquelle /snmpd/ écoute. En effet, par défaut (et par sécurité) il écoute uniquement sur localhost (127.0.0.1), sur le port 161.
Petite note sur la sécurité et SNMP
Dans le cas d'une machine (par exemple un serveur dédié (OVH, Online, ou serveurs dans une colo/datacenter)) possédant plusieurs interfaces réseau (virtuelles (VPN) ou physiques (eth0, eth1, enp0s1, eno1, etc) il est plus sûr de ne pas exposer snmpd sur l'interface WAN (ie connectée à Internet directement) mais d'utiliser un réseau privé isolé (RPNG Online, vRack OVH) pour la communication entre le manager et les nodes.
Si la topologie physique du réseau ne le permet pas, on peut aussi utiliser un VPN (man openvpn(8)) pour ajouter une couche de sécurité (et d'authentification) supplémentaire.
Comme on se trouve sur un réseau privé dont on a (normalement) le contrôle, on va donc renseigner l'adresse IP de l'interface réseau de notre VM /node1/ (ici, je prends comme exemple une adresse 172.30.0.2/24 pour notre interface réseau principale):
# on commente d'abord la ligne:
agentAddress udp:127.0.0.1:161
# Puis:
agentAddress udp:172.30.0.2:161
# Si on a une adresse IPv6, par exemple 2001:abcd::2/64, notre ligne deviendra (notez les crochets):
agentAddress udp:172.30.0.2:161,udp6:[2001:abcd::2]:161
# Si on veut ecouter sur toutes les interfaces reseau, en udp et en udp6:
agentAddress udp:161,udp6:[::1]:161
Tant que nous y sommes, nous allons créer un utilisateur configurator que nous utiliserons uniquement pour la configuration - nous l'effacerons ensuite, lorsque nous aurons créé notre utilisateur supervisor (note: vous pouvez bien sûr leur donner les noms que vous voulez) sur le nœud ET sur le NMS.
Toujours dans /etc/snmp/snmpd.conf:
# on ajoute les lignes suivantes en fin de fichier:
createUser test SHA super_mot_de_passe AES
#rwuser, utilisateur read/write (il peut snmpset), rouser pour un readonly
rwuser configurator priv
rwuser test priv
rwuser supervisor priv
# on quitte notre editeur de texte et on relance le service snmpd:
$ sudo systemctl restart snmpd
Notre config est prête, on va pouvoir se connecter à notre daemon SNMP depuis notre VM de supervision! Mais avant, un petit récapitulatif de la syntaxe générale des commandes SNMP!
Structure type des commandes SNMP
La plupart des outils SNMP vont utiliser les mêmes options de bases, qui sont:
- -v VERSION: la version du protocole à utiliser (on utilisera v3 - il s'agit normalement de l'option par défaut donc nous ne devrions pas avoir besoin de spécifier la version du protocole)
- -c COMMUNITY: la communauté (private ou public) SNMP (si on utilise SNMPv1 ou v2) que nous interrogeons. Comme on utilisera SNMPv3 ici, on ne devrait pas non plus en avoir besoin
- -u USERNAME: l'utilisateur avec lequel nous nous connectons - par exemple, l'utilisateur configurator défini précédemment dans la configuration de l'agent snmp sur notre node1
- -l LEVEL: Le type d'authentification utilisé (noAuthNoPriv, authNoPriv, ou authPriv - dans notre cas, authPriv
)
- -a PROTOCOL: le protocole d'authentification utilisé (MD5 ou SHA, dans notre cas: SHA)
- -x PROTOCOL: le protocole de chiffrement utilisé (DES ou AES, dans notre cas AES).
- -A PASSPHRASE: le mot de passe précisé pour l'authentification (ici: super_mot_de_passe)
- -X PASSPHRASE: la passphrase de chiffrement - nous n'avons pas spécifié de passphrase de chiffrement, aussi le mot de passe d'authentification est utilisé pour le chiffrement des communications.
Notre première commande SNMP 
Dès lors, la structure de base d'une commande SNMP envoyée depuis notre superviseur vers notre agent SNMP sur notre nœud node1 aura pour forme:
$ snmpcommande -u configurator -l authPriv -a SHA -x AES -A \
super_mot_de_passe -X super_mot_de_passe 172.30.0.2 OID
On peut même le tester tout de suite et vérifier que notre configuration est correcte dans la foulée:
$ snmpwalk -u configurator -l authPriv -a SHA -x AES -A \
super_mot_de_passe -X super_mot_de_passe 172.30.0.2 | less
# qui va nous renvoyer la liste des OIDs disponibles, ici sur une VM chez moi:
SNMPv2-MIB::sysDescr.0 = STRING: Linux daoloth 4.9.0-3-amd64 #1 SMP \
# Debian 4.9.30-2+deb9u2 (2017-06-26) x86_64
SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (29638) 0:04:56.38
SNMPv2-MIB::sysContact.0 = STRING: Me <me@example.org>
SNMPv2-MIB::sysName.0 = STRING: daoloth
SNMPv2-MIB::sysLocation.0 = STRING: Sitting on the Dock of the Bay
SNMPv2-MIB::sysServices.0 = INTEGER: 72
SNMPv2-MIB::sysORLastChange.0 = Timeticks: (1) 0:00:00.01
SNMPv2-MIB::sysORID.1 = OID: SNMP-MPD-MIB::snmpMPDCompliance
SNMPv2-MIB::sysORID.2 = OID: SNMP-USER-BASED-SM-MIB::usmMIBCompliance
SNMPv2-MIB::sysORID.3 = OID: SNMP-FRAMEWORK-MIB::snmpFrameworkMIBCompliance
SNMPv2-MIB::sysORID.4 = OID: SNMPv2-MIB::snmpMIB
SNMPv2-MIB::sysORID.5 = OID: SNMP-VIEW-BASED-ACM-MIB::vacmBasicGroup
# ... etc, etc, etc
HOST-RESOURCES-MIB::hrSWInstalledDate.871 = STRING: 0-1-1,0:0:0.0
HOST-RESOURCES-MIB::hrSWInstalledDate.872 = STRING: 0-1-1,0
Comme vous voyez, il y en a… un énorme paquet!
Par exemple, si on veut uniquement le nom ou l'uptime de la machine node1:
$ snmpget -v 3 -u configurator -a SHA -A super_mot_de_passe -x AES -X \
super_mot_de_passe -l authPriv 172.30.0.2 SNMPv2-MIB::sysDescr.0
# note, on peut aussi utiliser uniquement sysDescr.0
# qui nous renverra:
SNMPv2-MIB::sysDescr.0 = STRING: Linux daoloth 4.9.0-3-amd64 #1 SMP \
Debian 4.9.30-2+deb9u2 (2017-06-26) x86_64
# Pour l'uptime:
$ snmpget -v 3 -u configurator -a SHA -A super_mot_de_passe -x AES -X \
super_mot_de_passe -l authPriv 172.30.0.2
HOST-RESOURCES-MIB::hrSystemUptime.0
#qui nous renverra (dans le cas de cette VM chez moi - qu'il faut que
#je reboote d'ailleurs)
HOST-RESOURCES-MIB::hrSystemUptime.0 = Timeticks: (1944097103) 225 days, 0:16:11.03
etc.
Ça peut sembler très verbeux, mais ça peut être extrêmement puissant - sachant qu'en prime SNMP est très léger.
On peut aussi interroger notre agent SNMP en utilisant les OID numériques, par exemple on peut remplacer SNMPv2-MIB::sysDescr.0 par 1.3.6.1.2.1.1.1.0
Création et suppression d'utilisateurs SNMPv3
Pour la gestion des utilisateurs en SNMP, nous allons utiliser l'outil snmpusm dont la syntaxe est similaire aux autres outils snmp, et qui utilisera comme template celui d'un utilisateur existant:
$ snmpusm -v... hote_distant create utilisateur utilisateur_existant
Et donc, dans notre cas:
$ snmpusm -v 3 -u configurator -a SHA -A super_mot_de_passe -x AES -X \
super_mot_de_passe -l authPriv 172.30.0.2 create supervisor \
configurator
Maintenant, nous allons changer le mot de passe de l'utilisateur supervisor. En effet, il a le même mot de passe que notre utilisateur configurator, ce qui n'est pas très "propre":
$ snmpusm -v 3 -u supervisor -a SHA -A super_mot_de_passe -x AES -X \
super_mot_de_passe -l authPriv 172.30.0.2 passwd super_mot_de_passe \
mot_de_passe_encore_mieux
Note: un mot de passe SNMPv3 doit faire 8 caractères minimum.
Bon, on va aussi en profiter pour se simplifier la vie. En effet, taper à chaque fois ses identifiants, le protocole utilisé par défaut, etc… c'est pénible, non? On va donc soit modifier notre fichier /etc/snmp/snmp.conf (si on veut que nos paramètres d'identification soient accessibles à tous les utilisateurs de notre manager), soit créer un fichier ~/.snmp/snmp.conf pour que seul notre utilisateur dispose de ces informations - vous avez bien créé un utilisateur?
# on cree notre repertoire
$ mkdir .snmp
$ vim .snmp/snmp.conf
# on va pouvoir ajouter nos informations d'authentification
defSecurityName supervisor
defSecurityLevel authPriv
defAuthType SHA
defPrivType AES
defAuthPassphrase mot_de_passe_encore_mieux
defPrivPassphrase mot_de_passe_encore_mieux
# on sauvegarde et on quitte
Esc:wq ;) (ou Ctrl-C:wq - pratique si Esc n'est pas pris en compte)
Maintenant, on peut simplement faire:
$ snmpget 172.30.0.2 sysUpTime.0
au lieu de se "coltiner" toute les options de chiffrement et d'authentification à la main
Maintenant, on va supprimer notre utilisateur configurator:
Sur notre node1, nous allons commenter les lignes correspondantes à cet utilisateur dans /etc/snmp/snmpd.conf:
# on edite notre fichier avec notre editeur prefere (ViM bien entendu)
#createUser configurator etc
#rwuser configurator priv
Sur notre NMS on supprime l'utilisateur en question:
$ snmpusm 172.30.0.2 delete configurator
Commandes SNMP utiles
Nous avons déjà vu la commande snmpwalk ainsi que snmpusm et snmpget.
Comme nous l'avons vu, par défaut, snmpwalk nous renvoie tout l'arbre… pas très pratique quand on ne cherche que les OIDs "sous-section" d'une OID plus générique. Par exemple, l'OID system:
$ snmpwalk 172.30.0.2 system
Une autre commande très sympathique, c'est snmptranslate qui va nous permettre de:
- traduire une OID numérique en OID "textuelle" et inversement
- obtenir la description complète d'une OID (oui, c'est très bien documenté
)
Exemples:
$ snmptranslate 1.3.6.1.2.1.1.1.0
SNMPv2-MIB::sysDescr.0
# avec le flag -On pour l'operation inverse - lisez la manpage:
$ snmptranslate -On SNMPv2-MIB::sysDescr.0
.1.3.6.1.2.1.1.1.0
# ah oui, le "." au debut, c'est la racine des OID :)
# et le meilleur pour la fin, ici avec l'OID numerique correspondant a l'uptime:
~$ snmptranslate -Td .1.3.6.1.2.1.25.1.1.0
HOST-RESOURCES-MIB::hrSystemUptime.0
hrSystemUptime OBJECT-TYPE
-- FROM HOST-RESOURCES-MIB
SYNTAX TimeTicks
MAX-ACCESS read-only
STATUS current
DESCRIPTION "The amount of time since this host was last
initialized. Note that this is different from
sysUpTime in the SNMPv2-MIB [RFC1907] because
sysUpTime is the uptime of the network management
portion of the system."
::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) host(25) \
hrSystem(1) hrSystemUptime(1) 0 }
On a plusieurs "flags" utilisables avec l'opérateur -O:
- -Oa pour avoir uniquement la chaîne de caractères de notre OID
- -On pour obtenir la valeur numérique de notre OID
- -Of pour obtenir le chemin complet (.iso.org.dod.internet.etc etc etc) de notre OID
- -Os pour ne sortir que le nom de l'OID (par exemple: hrSystemUptime.0)
Maintenant, on va aussi voir comment on peut obtenir un formatage de la sortie plus lisible que celui de snmpwalk avec la commande snmptable, par exemple ici sur l'OID tcpConn. Testez:
$ snmpwalk 172.30.0.2 tcpConn
# bon courage :)
C'est certes détaillé mais pas réellement lisible humainement parlant. Par contre, avec /snmptable/, on va pouvoir présenter ces données tabulaires sous forme de… tableau (oui oui…)
# par exemple, sur une de mes VMs perso:
$ snmptable 192.168.42.215 tcpConn
SNMP table: TCP-MIB::tcpConnTable
tcpConnState tcpConnLocalAddress tcpConnLocalPort tcpConnRemAddress tcpConnRemPort
listen 0.0.0.0 13 0.0.0.0 0
listen 0.0.0.0 22 0.0.0.0 0
listen 0.0.0.0 37 0.0.0.0 0
listen 0.0.0.0 80 0.0.0.0 0
listen 0.0.0.0 111 0.0.0.0 0
listen 0.0.0.0 2049 0.0.0.0 0
listen 0.0.0.0 37011 0.0.0.0 0
listen 0.0.0.0 38595 0.0.0.0 0
listen 0.0.0.0 45737 0.0.0.0 0
listen 0.0.0.0 55333 0.0.0.0 0
listen 127.0.0.1 25 0.0.0.0 0
listen 127.0.0.1 4005 0.0.0.0 0
established 127.0.0.1 4005 127.0.0.1 38228
established 127.0.0.1 38228 127.0.0.1 4005
established 192.168.42.215 22 192.168.42.10 48706
Qui est ensuite facilement transformable en tableau, csv ou, ici,
org-mode:
| tcpConnState | tcpConnLocAddr | tcpConnLocPort | tcpConnRemAddr |
|---|---|---|---|
| listen | 0.0.0.0 | 13 | 0.0.0.0 |
| listen | 0.0.0.0 | 22 | 0.0.0.0 |
| listen | 0.0.0.0 | 37 | 0.0.0.0 |
| listen | 0.0.0.0 | 80 | 0.0.0.0 |
| listen | 0.0.0.0 | 111 | 0.0.0.0 |
| listen | 0.0.0.0 | 2049 | 0.0.0.0 |
| listen | 0.0.0.0 | 37011 | 0.0.0.0 |
| listen | 0.0.0.0 | 38595 | 0.0.0.0 |
| listen | 0.0.0.0 | 45737 | 0.0.0.0 |
| listen | 0.0.0.0 | 55333 | 0.0.0.0 |
| listen | 127.0.0.1 | 25 | 0.0.0.0 |
| listen | 127.0.0.1 | 4005 | 0.0.0.0 |
| established | 127.0.0.1 | 4005 | 127.0.0.1 |
| established | 127.0.0.1 | 38228 | 127.0.0.1 |
| established | 192.168.42.215 | 22 | 192.168.42.10 |
C'est tout de suite plus lisible, non?
On a vu que snmpwalk nous permet de parcourir tout l'arbre, ou juste un /subset/ (branche) de cet arbre. On peut aussi utiliser la commande snmpgetnext pour passer d'OID en OID, par exemple:
$ snmpbulkget 172.30.0.2 hrSystem
HOST-RESOURCES-MIB::hrSystemUptime.0 = Timeticks: (1949936967) 225 days, 16:29:29.67
# etc etc etc
et par exemple avec snmpbulkwalk:
$ snmpbulkwalk 192.168.42.215 vacmAccess
SNMP-VIEW-BASED-ACM-MIB::vacmAccessContextMatch."grpcomm1"."".0.noAuthNoPriv = INTEGER: prefix(2)
SNMP-VIEW-BASED-ACM-MIB::vacmAccessContextMatch."grpcomm2"."".0.noAuthNoPriv = INTEGER: prefix(2)
SNMP-VIEW-BASED-ACM-MIB::vacmAccessContextMatch."grpsupervisor"."".3.authPriv = INTEGER: prefix(2)
SNMP-VIEW-BASED-ACM-MIB::vacmAccessContextMatch."grpauthOnlyUser"."".3.authNoPriv = INTEGER: prefix(2)
#... etc etc etc
En fait, au lieu d'envoyer un paquet par ligne, les commandes bulk vont envoyer plusieurs lignes par paquet.
Bon, toutes ces commandes, c'est certes sympa, mais c'est quand même mieux d'avoir une solution de supervision qui va nous générer de beaux graphes et tableaux à partir des données que nous pouvons extraire via SNMP, non?
Traps SNMP, INFORM SNMPv3
Les Traps (et INFORM pour SNMPv3) snmp permettent aux agents d'envoyer directement au NMS SNMP des informations pertinentes (up/down d'une interface réseau par exemple).
Elles sont documentées dans la RFC 1157 pour SNMPv1 (mais qui utilise encore SNMPv1?), 1907 pour SNMPv2 et 3413 à 3415 pour SNMPv3. Le NMS doit disposer des MIBs contenant les OIDs correspondant aux Traps SNMP envoyées par les agents (i.e. si l'agent est utilisé sur du matériel Cisco, Juniper ou autre, le NMS doit disposer des MIBs correspondantes pour pouvoir comprendre la signification de la trap ou du message INFORM envoyés).
Comme nos agents envoient directement les informations au NMS sans répondre à une requête de ce dernier, elles ont plusieurs avantages:
- Transmission de potentiels dysfonctionnements sans interrogation de la part du manager
- économie de ressources (réseau et CPU) tant sur le NMS que sur les agents et nœuds
Une des différences majeures entre une Trap SNMP et un INFORM SNMP (introduit dans SNMPv2) est que l'agent, dans le premier cas, ne sait pas si le NMS a bien reçu le message (il n'y a pas de ACK transmis par le NMS).
De même, il y a plusieurs différences dans l'implémentation des Traps (et INFORM) entre SNMPv1/2 et SNMPv3. En effet, SNMPv3 impose que le message soit rejeté si:
- Les informations de l'utilisateur ne sont pas dans la base de données des utilisateurs
- Aucun EngineID (correspondant à l'utilisateur) n'est spécifié.
Cela signifie que contrairement à SNMPv1/2, où le message sera pris en compte tant qu'il appartient à la même communauté, SNMPv3 impose d'avoir un couple utilisateur/engineID pour chaque agent de votre infrastructure. C'est à dire que si vous avez 100 agents SNMP, il vous faudra… 100 directives createUser dans votre configuration de snmptrapd (conseil: sortez les scripts ).
Configuration de snmptrapd sur un NMS UNIX/UNIX-like
La première chose à faire est d'installer - via le gestionnaire de paquets de la distribution utilisée - le paquet correspondant à snmptrapd, ici pour Debian et dérivés:
$ sudo apt install snmptrapd
On va ensuite configurer snmptrapd, on coupe d'abord le service (et on le lancera "à la main" ensuite pour envoyer notre premier message INFORM et vérifier qu'il est bien arrivé):
$ sudo systemctl stop snmptrapd
$ sudo vim /etc/snmp/snmptrapd.conf
# on ajoute en fin de fichier:
createUser supervisor SHA supermotdepasse AES supermotdepasse
# on autorise l'utilisateur a envoyer des infos de log
# on peut l'autoriser a envoyer d'autres choses (execute (envoyer les
# details de l'inform ou trap a un programme ou script), net (envoyer
# les notifs a un autre NMS))
authUser log supervisor
# ou par ex: authUser log,execute supervisor
Pour le moment, on ne va pas relancer snmptrapd via systemctl start snmptrapd mais on va le lancer "à la mano":
$ sudo snmptrapd -f -C -c /etc/snmp/snmptrapd.conf -Le
Maintenant, si on se place sur notre node1, et qu'on envoie un INFORM avec nos informations d'authentification:
$ sudo snmpinform -v 3 -a SHA -A supermotdepasse -x AES -X \
supermotdepasse -l authPriv -u supervisor 172.30.0.1 1 \
SNMPv2-MIB::coldStart
On devrait obtenir, dans le /log/ de notre snmptrapd sur notre NMS:
2018-03-13 15:21:45 daoloth.lidless.lan [UDP: \
[192.168.42.215]:39420->[192.168.42.213]:162]: \
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (1) 0:00:00.01 \
SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-MIB::coldStart
"Indiquant" que notre machine node1 vient de redémarrer "brutalement".
Maintenant, la question, c'est "comment automatiser l'envoi de messages INFORM (ou de TRAPs)" depuis notre machine /node1/, ce qui nous amène au chapitre suivant
Configuration des agents SNMPv3 sur matériel Cisco
Il faut tout d'abord créer notre utilisateur SNMP (et le groupe auquel il appartient) sur notre routeur (ou commutateur):
Router- enable
Router- conf t
Router(config)- snmp-server user supervisor group nom_de_groupe v3 \
auth SHA mot_de_passe priv AES passphrase [access {accesslist}]
Tester ensuite depuis notre NMS que nous:
- Disposons bien des MIBs Cisco
- Pouvons par exemple exécuter snmpbulkwalk sur notre matériel Cisco
De même, on peut tester la configuration SNMP de notre matériel via
différentes commandes show
Router- ena
Router- show snmp user utilisateur
Router- show snmp group
Auto-Discovery via SNMP
Il est possible de découvrir quasi-automatiquement - et avec un peu de scripting - l'ensemble d'un réseau de machines "discutant" en SNMP (i.e dans la même communauté pour SNMPv1, v2c, et disposant des mêmes informations d'identification pour SNMPv3). Il suffit, en partant d'une machine dont nous pouvons interroger l'état des interfaces réseau via /snmpget/ par exemple, de chercher les OIDs correspondant à ses interfaces réseau, qui vont nous indiquer… avec quelles machines elle est interconnectée. De là, on peut ensuite, depuis notre NMS,
interroger successivement les machines découvertes selon le même
principe pour pouvoir "mapper" tout le réseau rapidement.
On sort un peu du programme de ce cours, mais je vous laisse explorer la piste
Zabbix
Installation sur notre VM de supervision
Alors, pour ce TP, nous allons nous simplifier la vie et utiliser Docker pour installer Zabbix.
Tout d'abord, on installe sur notre VM les paquets suivants:
- docker.io
- docker-compose
sudo apt install docker.io docker-compose
# on ajoute notre utilisateur au groupe docker
sudo usermod -aG docker votre-utilisateur
# déloggez-vous/déconnectez-vous de SSH/etc
# et reconnectez vous pour prendre en compte
# votre nouveau groupe
ensuite, nous allons créer un fichier docker-compose.yml
version: '3'
services:
zabbixdb:
image: postgres:13-alpine
environment:
- POSTGRES_DB=zabbix
- POSTGRES_USER=zabbix
- POSTGRES_PASSWORD=epsiepsi
volumes:
- zabbixpg-data:/var/lib/postgresql/data
zabbixserver:
image: zabbix/zabbix-server-pgsql:alpine-latest
environment:
- DB_SERVER_HOST=zabbixdb
- POSTGRES_USER=zabbix
- POSTGRES_PASSWORD=epsiepsi
links:
- zabbixdb
depends_on:
- zabbixdb
ports:
- 10050:10050
- 10051:10051/udp
zabbixweb:
image: zabbix/zabbix-web-nginx-pgsql:alpine-latest
environment:
- DB_SERVER_HOST=zabbixdb
- POSTGRES_USER=zabbix
- POSTGRES_PASSWORD=epsiepsi
- PHP_TZ=Europe/Paris
- ZBX_SERVER_HOST=zabbixserver
links:
- zabbixdb
- zabbixserver
depends_on:
- zabbixdb
- zabbixserver
ports:
- 9080:8080
volumes:
zabbixpg-data:
driver: local
Configuration utilisateurs
On se connecte à notre Zabbix: http://IP_VM_Zabbix
Les login et mot de passe de base sont: Admin/zabbix, à changer
rapidement bien sûr
Note: évidemment, en production, on utiliserait un IDP (LDAP/AD/OIDC/etc) pour identifier nos utilisateurs, les groupes auxquels ils appartiennent et les permissions à leur accorder
Ajout de notre node à monitorer
Ça tombe bien, on a nos VMs qui n'attendent que ça
Direction le menu Configuration/Hosts, puis on clique sur Create Host. Dans notre cas, on choisit le groupe Linux Server.
On renseigne un nom d'hôte "parlant" pour notre machine /node1/, puis on renseigne le champ Agent Interfaces. Remarquez qu'on a aussi notre copain SNMP dans la liste des interfaces disponibles…
Quelles métriques pertinentes pour notre node?
Pour le moment, si notre hôte est bien configuré, il ne nous remonte aucune information. Il faut en effet configurer les Items que notre NMS va suivre et stocker en base de données concernant cet hôte.
Dans la terminologie Zabbix, un item correspond à une métrique récupérée sur un hôte précis.
Ici, on se place donc sur l'hôte que nous venons de créer, et on clique sur le lien items, puis sur Create item.
ici, on va par exemple créer un item nous permettant de récupérer la valeur du Load CPU à un instant t: system.cpu.load
On procède de la même façon pour collecter d'autres métriques que l'on jugera pertinentes (ex: bande passante, I/Os disque, RAM, etc).
Par contre, dans le cas oú on aurait une centaine d'hôtes similaires à monitorer, ça risque de devenir rapidement barbant de les faire un par un (et juste un peu contre-productif). On va voir qu'on peut en fait facilement générer des modèles d'hôtes via les templates. Mais d'abord, comment déclencher une alerte au cas oú un paramètre de nos hôtes dépasse un seuil établi?
Triggers
Il s'agit des limites acceptables en deça desquelles aucune alerte n'est envoyée/affichée dans le dashboard. Là encore c'est "self-explanatory": menu Configuration/Hosts, on sélectionne notre hôte, puis enfin on clique sur triggers et enfin sur Create trigger.
la syntaxe d'un trigger est de la forme:
{Hostname:type.sous-type.valeur.calcul(intervalle de temps)}>valeur
# ou =, ou <, etc
Par exemple, sur une machine 12 coeurs, 24 threads dont le nom est
Front1:
{Front1:system.cpu.load.avg(120)}>24
Signifie: alerter d'un problème si le load moyen de Front1 est supérieur à 24 pendant deux minutes.
Templates
Pour créer un /template/ on va se placer dans le menu Configuration/Templates (original, non?)
On peut définir des templates contenant plusieurs items, triggers, etc pour des hôtes possédant des rôles similaires. De même on peut lier un hôte a plusieurs templates.
Par exemple, imaginons qu'on ait un hôte:
- sous GNU/Linux Debian
- ayant un service de base de données en cours d'exécution
On pourra par exemple lui appliquer un template "Linux Générique" nous permettant de collecter les données de base de l'OS: CPU, RAM, I/Os, espace disque.
Puis un template "BDD SQL", nous remontant les valeurs types d'une BDD: Nombre de QPS, buffers, deadlocks, etc.
Bien évidemment, ces templates pourront aussi posséder des triggers spécifiques, par exemple:
- Le template Linux genérique nous alertera si la RAM commence à être limite, si le load dépasse un certain seuil, si l'espace disque disponible est <20%
- Le template BDD SQL pourra lui nous avertir si le nombre de deadlocks dépasse un certain seuil, ou tout simplement si le service de BDD ne "tourne" pas - cequ'on aurait pas nécessairrement remarqué si nous avions uniquement utilisé le template Linux générique.
Services
Un service est un ensemble d'hôtes participant à l'exécution d'une tâche plus complexe.
Par exemple, on peut imaginer qu'un service Web va se composer:
- D'une ou plusieurs machines frontales. Typiquement leur rôle sera d'acheminer et distribuer les requêtes utilisateurs vers plusieurs serveurs en backend, de gérer la négociation TLS avec les utilisateurs, etc - typiquement tout ce qu'un reverse-proxy/load-balancer comme HAproxy peut faire.
- Serveurs de cache (Varnish, etc)
- Serveurs Web à proprement parler et le langage supportant l'applicatif: nginx, apache2, caddy, lighttpd, php-fpm, python-uwsgi, etc
- Serveurs de cache de base de données (Redis, Couchbase, etc)
- Serveurs de base de données à proprement parler: MySQL, PostgreSQL, MariaDB, etc
- Serveurs de stockage de données: NFS, GlusterFS, Ceph, Riak, baies de disques iSCSI...
L'ensemble de ces machines et des logiciels qu'ils exécutent formant ce qu'on appelle un service du point de vue Business. il est donc important de déterminer l'impact du mauvais fonctionnement d'une de ces machines ou d'un de ces logiciels. Par exemple, sur un gros cluster Riak composé d'une trentaine de machines, le fait qu'une ou deux machines soient DOWN n'est pas impactant pour le Service et donc pour le business. Pas besoin de réveiller un adminsys pour ça en pleine nuit .
À l'inverse, si la BDD Master est tombée, et que donc, par exemple dans le cas d'un site de e-commerce, les utilisateurs ne peuvent plus enregistrer leurs actions (achats, etc) l'impact business n'est plus le même - et là on réveillera le sysadmin
Autres solutions de supervision
WMI: Windows Monitoring Instrumentation
WMI est un peu le SNMP "sauce Windows" (on peut aussi utiliser SNMP sous Windows). Il dérive du standard WBEM (Web-Based Enterprise Management) et CIM (Common Information Model) du DMTF (Distributed Management Task Force). Il permet d'obtenir de nombreuses informations sur l'état de Windows ainsi que d'exécuter des scripts (powershell, etc) en fonction de l'état du système.
Collectd/statsd, Prometheus, InfluxDB, Grafana, etc
Il existe de nombreux systèmes de collecte (au moins autant que de logiciels de supervision) permettant de collecter des informations de supervision depuis des machines sous UNIX ou GNU/Linux. Certaines sont dites /agentless/ dans le sens où - typiquement - c'est le système de supervision qui va se connecter (par exemple en SSH) aux machines supervisées pour collecter les données en exécutant des commandes spécifiques (c'est le cas de MicroFocus (ex HP) SiteScope). D'autres requièrent l'installation d'un agent spécifique (exemple libre: collectd, exemple propriétaire: NewRelic) sur chaque machine supervisée.
Ces agents permettent de collecter des données à la fois système (load, entrées/sorties, etc) et applicatives (par exemple le nombre de requêtes exécutées par un serveur Web ou un reverse-proxy) voire plus détaillées (temps de réponse de PHP-FPM ou WSGI par exemple, mais aussi temps d'exécution d'une fonction précise de l'applicatif (statsd), très pertinent pour pouvoir /remonter/ des informations aux développeurs de l'applicatif afin de pouvoir améliorer le code et donc la qualité de service.
l'agrégateur de données consiste en général en une base de données (InfluxDB par exemple, mais on peut aussi utiliser PostGreSQL, MariaDB ou même SQL Server pour les masochistes, voire MongoDB si vous n'avez pas peur qu'il oublie des données - véridique ) qui va stocker les données collectées dans différentes tables, et y appliquer des règles de rétention (par exemple, conserver les données stockées sur un mois, puis ensuite passer à une métrique par heure, puis par jour, etc en fonction de l'éloignement temporel de cette métrique).
Enfin, on va afficher ces données via un logiciel de supervision (Shinken, Nagios, etc), voire avec un logiciel qui ne fait qu'afficher ces données (Grafana) qui va interroger l'agrégateur à chaque requête de l'utilisateur pour générer les graphiques représentant l'évolution des métriques collectées dans le temps.
De même, il existe aussi des outils de monitoring (et d'alerte) de logs (les plus connus étant basés sur la /stack/ ELK (ElasticSearch, Logstash, Kibana), par exemple OSSEC, Whazu (assez excellent), qui vérifient aussi la conformité PCI-DSS de l'infrastructure au fil du temps et peuvent pointer de potentielles failles dans votre infrastructure.