Illustration de l'article SNMP : comprendre le protocole et choisir entre v1, v2c et v3

SNMP : comprendre le protocole et choisir entre v1, v2c et v3

Un switch qui sature, un disque qui se remplit, une alimentation qui lâche dans un onduleur. Pour le savoir avant les utilisateurs, il faut que les équipements puissent dire comment ils vont. Depuis la fin des années 1980, c'est le travail de SNMP.

Le protocole est partout : switchs, routeurs, pare-feu, serveurs, imprimantes, onduleurs, climatiseurs de salle serveur. Il est aussi souvent mal configuré avec une communauté public qui traîne et une version qui envoie tout en clair.

Cet article reprend tout depuis le début : le fonctionnement, les données, les trois versions et leurs différences puis la configuration et la sécurité.

À quoi sert SNMP

SNMP signifie Simple Network Management Protocol. Il sert à deux choses.

  • Lire l'état d'un équipement : trafic d'une interface, charge du processeur, température, espace disque, état d'un port
  • Recevoir des alertes : l'équipement prévient de lui-même quand un lien tombe ou qu'un ventilateur s'arrête

En théorie, il permet aussi de modifier la configuration. En pratique, on ne s'en sert presque jamais pour ça et on a de bonnes raisons de l'interdire.

L'architecture : manager, agent et MIB

Trois éléments travaillent ensemble.

  • Le manager : le serveur de supervision (Zabbix, LibreNMS, Centreon). Il pose les questions et reçoit les alertes
  • L'agent : un petit service qui tourne sur l'équipement supervisé. Il répond aux questions et envoie les alertes
  • La MIB : le catalogue des informations que l'agent sait fournir

Les échanges passent par UDP.

Port Sens Usage
UDP 161 manager vers agent requêtes et réponses
UDP 162 agent vers manager alertes (traps et informs)

UDP n'offre aucune garantie de livraison. Une requête perdue est simplement renvoyée par le manager après un délai. Une alerte perdue, en revanche est perdue pour de bon. On y reviendra.

Les OID et la MIB

Un arbre de numéros

Chaque information porte un identifiant unique, l'OID (Object Identifier). Les OID forment un arbre mondial géré par des organismes de normalisation.

iso (1)
 └─ org (3)
     └─ dod (6)
         └─ internet (1)
             ├─ mgmt (2)
             │   └─ mib-2 (1)          MIB standard : 1.3.6.1.2.1
             │       ├─ system (1)
             │       └─ interfaces (2)
             └─ private (4)
                 └─ enterprises (1)    MIB constructeurs : 1.3.6.1.4.1
                     ├─ cisco (9)
                     └─ mikrotik (14988)

Quelques OID qu'on croise tous les jours :

Nom OID Contenu
sysDescr.0 1.3.6.1.2.1.1.1.0 description du système
sysUpTime.0 1.3.6.1.2.1.1.3.0 temps depuis le démarrage de l'agent
sysName.0 1.3.6.1.2.1.1.5.0 nom de l'équipement
ifDescr 1.3.6.1.2.1.2.2.1.2 nom de chaque interface
ifOperStatus 1.3.6.1.2.1.2.2.1.8 état réel de chaque interface
ifHCInOctets 1.3.6.1.2.1.31.1.1.1.6 octets reçus, compteur 64 bits

Le .0 final désigne l'unique instance d'une valeur simple. Pour une table, le dernier nombre est l'index de la ligne : ifDescr.3 est le nom de l'interface numéro 3.

La MIB

Une MIB est un fichier texte qui décrit une partie de l'arbre : le nom de chaque OID, son type, ses droits d'accès et sa signification. Elle permet d'écrire IF-MIB::ifDescr au lieu de 1.3.6.1.2.1.2.2.1.2.

Il existe deux familles :

  • les MIB standard, décrites dans des RFC, comme MIB-II (RFC 1213) ou IF-MIB (RFC 2863). Tous les équipements les comprennent
  • les MIB constructeur, sous enterprises. Chaque fabricant y range ses informations propres : température des modules Cisco, état des tunnels MikroTik

L'agent n'a pas besoin des fichiers MIB pour fonctionner. Ils servent au manager et aux humains pour traduire les numéros en noms.

Les types de données

Type Usage
INTEGER une valeur entière, ou un état codé (1 = up, 2 = down)
OCTET STRING du texte ou des octets bruts
Counter32 / Counter64 un compteur qui ne fait qu'augmenter
Gauge32 une valeur qui monte et descend
TimeTicks une durée en centièmes de seconde
IpAddress une adresse IPv4

Compteur ou jauge : la différence qui fausse les graphiques

Une jauge donne une valeur directe. Une température de 42 vaut 42.

Un compteur ne fait que grimper. ifInOctets vaut 8 734 501 223 : c'est le total d'octets reçus depuis le démarrage, ce qui ne dit rien sur le trafic actuel. Pour obtenir un débit, le manager lit le compteur deux fois et calcule la différence divisée par le temps écoulé.

débit = (valeur2 - valeur1) / (temps2 - temps1)

Le piège vient des compteurs 32 bits. Ils plafonnent à 2^32, soit environ 4,3 milliards puis repartent de zéro. Sur une interface à 1 Gbit/s saturée, ifInOctets refait le tour en 34 secondes. À 10 Gbit/s, en 3,4 secondes.

Si le manager interroge toutes les cinq minutes, il ne peut pas savoir combien de tours le compteur a faits entre deux lectures. Le graphique devient faux sans prévenir. La solution est d'utiliser les compteurs 64 bits de la table ifXTable : ifHCInOctets et ifHCOutOctets. HC signifie High Capacity. Ils n'existent pas en SNMPv1.

Même logique pour sysUpTime : en centièmes de seconde sur 32 bits, il revient à zéro au bout de 497 jours. Un équipement qui semble avoir redémarré peut simplement avoir dépassé ce cap.

Les opérations

Les messages SNMP s'appellent des PDU (Protocol Data Unit).

PDU Version Rôle
GetRequest v1 lire une ou plusieurs valeurs précises
GetNextRequest v1 lire l'OID qui suit dans l'arbre
SetRequest v1 modifier une valeur
Response v1 réponse de l'agent
Trap v1 alerte envoyée sans accusé de réception
GetBulkRequest v2c lire beaucoup de valeurs d'un coup
InformRequest v2c alerte avec accusé de réception
Report v3 échanges internes à la sécurité de v3

Parcourir une table

GetNext permet de parcourir une branche qu'on ne connaît pas à l'avance. On demande l'OID qui suit, puis celui d'après, jusqu'à sortir de la branche. C'est ce que fait la commande snmpwalk.

Le défaut : un aller-retour réseau par valeur. Sur un switch de 48 ports, lire dix colonnes de la table des interfaces demande près de 500 échanges.

GetBulk, ajouté en v2c, règle le problème. Le manager demande « les 50 valeurs suivantes » en un seul message. C'est le même principe que le problème N+1 dans un ORM : regrouper les lectures au lieu de les faire une par une.

Interroger ou être prévenu

Il y a deux façons d'apprendre ce qui se passe.

  • Le polling : le manager interroge chaque équipement à intervalle régulier, en général entre une et cinq minutes. C'est fiable et ça alimente les graphiques
  • Les alertes : l'équipement prévient dès qu'un événement se produit. C'est immédiat, mais seulement pour les événements prévus par l'agent

Une trap part en UDP sans accusé de réception. Si le paquet se perd, personne ne le saura. Un inform ajouté en v2c attend un accusé de réception et se renvoie s'il ne le reçoit pas.

En pratique, on combine les deux. Les alertes donnent la réactivité, le polling rattrape ce qu'elles ont manqué.

Les trois versions

SNMPv1

La première version a été publiée en 1988 puis révisée en 1990 dans la RFC 1157. Elle pose toute la base : manager, agent, MIB, Get, GetNext, Set et Trap.

Sa sécurité tient en un mot : la communauté. C'est une simple chaîne de caractères envoyée avec chaque requête comme un mot de passe partagé. Elle circule en clair sur le réseau. N'importe qui capable d'écouter le trafic la lit avec Wireshark.

Les valeurs par défaut aggravent les choses : public en lecture, private en écriture, sur des milliers d'équipements jamais reconfigurés.

Autres limites : pas de compteurs 64 bits et une gestion des erreurs rudimentaire. Si une requête demande dix OID et qu'un seul n'existe pas, toute la requête échoue.

SNMPv2c

L'histoire de la v2 est un peu chaotique. Une première SNMPv2, publiée en 1993 proposait un modèle de sécurité ambitieux. Il était si complexe que presque personne ne l'a implémenté. Plusieurs variantes concurrentes ont suivi puis le consensus s'est fait en 1996 sur la plus simple : SNMPv2c.

Le « c » signifie community-based. La v2c garde la sécurité de la v1 avec la communauté en clair et apporte les améliorations du protocole.

  • GetBulk pour lire les tables bien plus vite
  • Inform pour des alertes avec accusé de réception
  • Counter64 pour les compteurs 64 bits, indispensables au-delà de 100 Mbit/s
  • De meilleures erreurs : un OID absent renvoie une exception pour cette variable seulement (noSuchObject, noSuchInstance, endOfMibView), au lieu de faire échouer toute la requête

C'est encore aujourd'hui la version la plus déployée parce qu'elle est simple à configurer. Sa sécurité, elle, n'a pas progressé depuis 1988.

SNMPv3

Publiée en 2002 dans les RFC 3411 à 3418, la v3 garde les opérations de la v2c et remplace entièrement la sécurité. Elle repose sur deux modèles.

USM (User-based Security Model, RFC 3414) remplace la communauté par de vrais utilisateurs. Chaque utilisateur a :

  • un protocole d'authentification : HMAC avec MD5 ou SHA-1 à l'origine puis la famille SHA-2 (SHA-224 à SHA-512) ajoutée par la RFC 7860 en 2016
  • un protocole de chiffrement : DES à l'origine puis AES-128 ajouté par la RFC 3826 en 2004
  • deux mots de passe, un pour chaque protocole

Trois niveaux de sécurité sont possibles :

Niveau Authentification Chiffrement Usage
noAuthNoPriv non non à éviter, à peine mieux qu'une communauté
authNoPriv oui non les données circulent en clair
authPriv oui oui le seul niveau à utiliser

L'authentification garantit que le message vient bien de cet utilisateur et qu'il n'a pas été modifié. Le chiffrement garantit que personne ne peut le lire en chemin.

Deux mécanismes complètent l'ensemble :

  • l'engineID : un identifiant unique par agent. Les clés sont dérivées du mot de passe et de cet identifiant. Le même mot de passe donne donc une clé différente sur chaque équipement. Une clé volée sur un routeur ne sert à rien sur le voisin
  • la fenêtre de fraîcheur : chaque message contient le nombre de redémarrages de l'agent et son horloge. Un message vieux de plus de 150 secondes est rejeté. Rejouer un paquet capturé ne fonctionne donc pas

VACM (View-based Access Control Model, RFC 3415) décide de ce que chaque utilisateur a le droit de voir. On définit des vues, c'est-à-dire des branches de l'arbre puis des groupes d'utilisateurs avec leurs droits sur ces vues. Le serveur de supervision lit tout, l'outil d'inventaire ne voit que la branche system.

Le comparatif

v1 v2c v3
Année 1988 à 1990 1996 2002
Identification communauté communauté utilisateur
Authentification aucune, la communauté circule en clair aucune, la communauté circule en clair HMAC MD5, SHA-1, SHA-2
Chiffrement non non DES, AES
Compteurs 64 bits non oui oui
GetBulk non oui oui
Inform non oui oui
Erreurs par variable non oui oui
Contrôle d'accès fin non non oui (VACM)

MD5 et DES sont aujourd'hui considérés comme faibles. Choisis SHA (idéalement SHA-256 si tes équipements le supportent) et AES.

Interroger un équipement avec Net-SNMP

Net-SNMP fournit les outils en ligne de commande de référence. Sur Debian ou Ubuntu, ils sont dans le paquet snmp.

En v2c

# Une valeur précise : la description du système
snmpget -v2c -c MaCommunaute 192.168.1.1 SNMPv2-MIB::sysDescr.0

# Le même OID, en version numérique
snmpget -v2c -c MaCommunaute 192.168.1.1 1.3.6.1.2.1.1.1.0

# Toute une branche : le nom de chaque interface
snmpwalk -v2c -c MaCommunaute 192.168.1.1 IF-MIB::ifDescr

# La même chose avec GetBulk, 50 valeurs par échange
snmpbulkwalk -v2c -c MaCommunaute -Cr50 192.168.1.1 IF-MIB::ifTable

En v3

snmpget -v3 -l authPriv \
    -u supervision \
    -a SHA -A 'MotDePasseAuthentification' \
    -x AES -X 'MotDePasseChiffrement' \
    192.168.1.1 SNMPv2-MIB::sysUpTime.0

-l fixe le niveau de sécurité. -a et -A donnent le protocole et le mot de passe d'authentification. -x et -X donnent le protocole et le mot de passe de chiffrement. Les mots de passe v3 doivent faire au moins 8 caractères.

Si les noms comme IF-MIB::ifDescr ne sont pas reconnus, les fichiers MIB manquent. Sur Debian, ils sont dans le paquet snmp-mibs-downloader. Les OID numériques fonctionnent dans tous les cas.

Configurer SNMPv3

Dans les trois exemples, on crée un utilisateur supervision en lecture seule avec authentification et chiffrement accessible uniquement depuis le serveur de supervision 192.168.10.5.

Sur Linux avec Net-SNMP

sudo apt install snmpd libsnmp-dev

# L'outil de création d'utilisateur demande que le service soit arrêté
sudo systemctl stop snmpd

sudo net-snmp-create-v3-user -ro \
    -a SHA -A 'MotDePasseAuthentification' \
    -x AES -X 'MotDePasseChiffrement' \
    supervision

sudo systemctl start snmpd

-ro donne un accès en lecture seule. L'outil vient du paquet libsnmp-dev sur Debian et Ubuntu.

Par défaut, l'agent n'écoute que sur la machine locale (agentaddress 127.0.0.1,[::1]). Pour l'ouvrir au réseau, remplace cette ligne dans /etc/snmp/snmpd.conf :

# Écouter sur toutes les interfaces, en UDP
agentaddress udp:161

# Supprimer ou commenter les lignes rocommunity et rwcommunity :
# aucune communauté v1 ou v2c ne doit rester active

Puis limite l'accès au port 161 au seul serveur de supervision avec le pare-feu :

sudo nft add rule inet filter input ip saddr 192.168.10.5 udp dport 161 accept
sudo nft add rule inet filter input udp dport 161 drop

Ces deux règles supposent une table inet filter avec une chaîne input comme dans la configuration par défaut de nftables sur Debian. Saisies ainsi, elles disparaissent au redémarrage : pour les garder, ajoute-les dans /etc/nftables.conf.

Sur Cisco IOS

! La vue : ce que l'utilisateur a le droit de lire
snmp-server view LECTURE iso included

! Seul le serveur de supervision peut interroger
ip access-list standard SNMP-SUPERVISION
 permit 192.168.10.5

! Le groupe v3 : authentification et chiffrement obligatoires (priv)
snmp-server group SUPERVISION v3 priv read LECTURE access SNMP-SUPERVISION

! L'utilisateur, rattaché au groupe
snmp-server user supervision SUPERVISION v3 auth sha MotDePasseAuthentification priv aes 128 MotDePasseChiffrement

Un piège surprend tout le monde la première fois : les utilisateurs SNMPv3 n'apparaissent pas dans show running-config. Les mots de passe sont transformés en clés dès la saisie. Pour vérifier, utilise show snmp user.

Sur MikroTik RouterOS

/snmp community
add name=supervision addresses=192.168.10.5/32 security=private \
    authentication-protocol=SHA1 authentication-password=MotDePasseAuthentification \
    encryption-protocol=AES encryption-password=MotDePasseChiffrement \
    read-access=yes write-access=no

/snmp set enabled=yes

Dans RouterOS, le nom de la communauté sert de nom d'utilisateur v3. security=private correspond au niveau authPriv. Pense aussi à restreindre ou désactiver la communauté public créée par défaut.

Sécurité : les pièges classiques

Les communautés par défaut. public et private sont les premiers mots que teste un scanner. Un équipement qui répond à public livre sa configuration réseau, ses interfaces et parfois ses tables ARP et de routage.

L'accès en écriture. Avec une communauté en écriture, on peut modifier la configuration, couper une interface ou sur certains équipements, télécharger la configuration complète. En supervision, on n'en a pas besoin. Lecture seule partout.

L'exposition sur Internet. Le port UDP 161 ne doit jamais être ouvert sur Internet. En plus de la fuite d'informations, SNMP sert aux attaques par amplification. L'attaquant envoie une petite requête GetBulk en usurpant l'adresse de sa victime et l'agent répond à la victime avec une réponse beaucoup plus grosse. Des milliers d'agents mal configurés deviennent ainsi des canons à trafic.

La v2c sur un réseau partagé. Si la v2c est inévitable (vieil équipement, outil limité), isole le trafic SNMP dans un VLAN d'administration et filtre par adresse source.

Les algorithmes faibles. MD5 et DES ne devraient plus être utilisés. SHA et AES sont pris en charge par tous les équipements récents.

Les traps v3. Pour une trap v3, c'est l'engineID de l'émetteur qui sert à dériver les clés. Le récepteur doit donc connaître l'engineID de chaque équipement qui lui envoie des traps. Les informs n'ont pas ce problème, car c'est l'engineID du récepteur qui est utilisé. C'est une raison de plus de préférer les informs.

Les outils qui s'appuient sur SNMP

  • Zabbix : supervision complète avec des modèles prêts à l'emploi pour la plupart des constructeurs
  • LibreNMS : découverte automatique du réseau et graphiques sans configuration
  • Centreon : solution française très présente dans les entreprises et les collectivités
  • Prometheus avec snmp_exporter : pour intégrer les équipements réseau à une supervision déjà basée sur Prometheus et Grafana
  • GLPI : l'inventaire réseau de l'agent GLPI découvre les équipements et leurs ports par SNMP

SNMP a-t-il encore sa place ?

Les grands réseaux passent progressivement à la télémétrie en flux (streaming telemetry, gNMI). Ce n'est plus le manager qui interroge : l'équipement pousse ses données en continu toutes les quelques secondes. Pour la configuration, NETCONF et RESTCONF ont remplacé depuis longtemps les SetRequest.

Pourtant, SNMP reste le seul langage que parlent à la fois un switch de dix ans, un onduleur, une imprimante et un routeur neuf. Pour superviser un parc hétérogène, il n'a pas de vrai concurrent.

La bonne pratique tient en trois points : SNMPv3 en authPriv, lecture seule et un accès limité au seul serveur de supervision.

Pour aller plus loin

Un exercice pour finir. Lance snmpwalk -v2c -c public sur un équipement de ton réseau avec l'accord de son responsable. S'il répond, tu viens de trouver ton premier chantier de sécurité.

Commentaires (0)

Laisser un commentaire

Vous n'êtes pas connecté

Vous pouvez commenter en renseignant votre nom et votre email. Votre message sera publié après modération. Avec un compte, il apparaît immédiatement et reste modifiable.

Votre email ne sera pas publié.

Aucun commentaire pour le moment

Soyez le premier à commenter cet article !