Simple Network Management Protocol
Directory
Sources
1. Introduction
SNMP
signifie Simple Network Management Protocol. C’est un protocole de gestion de réseau. Concrètement il permet de superviser l’état des équipements réseaux ou d’un parc informatique, aussi bien que le materiel que les services:
- Routeurs, switchs
- Stations de travail
- Imprimantes
- Services (messagerie, ftp, ssh, http, processus, mémoire, …)
Par supervision il faut comprendre “obtenir des informations” sur l’état de ces “éléments”. Ce protocole permet aussi d’effectuer des actions de maintenance comme redémarrer un service ou une machine, nettoyer les têtes de lecture d’une imprimante, …
Fonctionnement
SNMP se base sur l’idée qu’un système de supervision de réseau se compose de
- Noeuds à administrer (Managed Nodes), contenant chacun un agent.
- agent $ \Rightarrow $ service qui dialogue avec les managers pour échanger des informations sur l’état du noeud.
- D’au moins une station d’administration, le manager (Network Management Station)
- D’un protocole permettant d’échanger de l’information entre les agents et le NMS ce protocole est
SNMP
- Le manager envoie des requêtes de type
GET
aux agents pour récuperer de l’information sur un service/une machine via le protocole SNMP - Il peut aussi envoyer des requêtes
SET
pour modifier l’état des services et/ou de la machine gérés par l’agent - Les agents peuvent envoyer des requêtes de type
TRAP
au manager pour signaler un dysfonctionnement - Les agents peuvent être regroupés au travers d’un agent maître
- Les informations accessibles et fournies par les agents sont organisées dans une base “virtuelle” appelée MIB. Cette base est normalisée
Pourquoi utiliser SNMP?
- Protocole ancien supporté par presque tous les constructeurs de matériel réseau
- Depuis la version 2, il est sécurisé, offrant un accès restreint à certaines informations et s’appuie sur des protocoles de chiffrement comme
SSH
etTLS
(mais avec ses propres librairies et outils internes). - L’information contenue dans les MIBs est normalisée: quelque soit l’appareil et son constructeur, une même information sera accessible au même endroit et de la même manière.
Vous êtes l’administrteur réseau et vous voulez connaître la mémoire totale disponible d’une machine, vous l’obtiendrez de la même façon quelque soit l’OS (mac/W/Unix/android) et le matériel utilisé (AMD, ARM, Intel,…).
- Il est simple (les agents sont légers, la complexité est déportée au niveau des managers)
- Indépendant de l’architecture réseau et des éléments (Pc, imprimante, routeurs, …)
- Extensible, on peut personnaliser les bases d’informations en plus de ce qu’offre le standard
- Robuste: S’appuie sur
UDP
ouTCP
: fonctionnera encore lorsque le réseau aura de graves problèmes d’engorgement (passe enUDP
).
Meta
Globlement ce protocole est très pratique, et est très répandu. Il peu de concurrents matures mais il souffre de certains points négatifs:
-
Parfois, il n’est pas simple: Les MIBs sont “lisibles par l’homme” mais ceux qui arrivent à le lire ne sont pas tous vraiment humains
-
Le protocole est simple mais son implémentation peu être complexe
-
La version 3 a implémenté sa propre couche
SSH
plutôt que de faire commeHTTPS
(duHTTP
overSSH
). Ceci rend pénible les communications: il n’y a pas d’auto-négociation pour le chiffrement et vous devez vous-même fournir 5 informations pour créer une connexion sécurisée -
Certains concurrents commencent à voir le jour comme
WMI
et offrent une langage d’interrogation plus riche (WQL)
Historique
- La première version du protocole date de 1989: Elle n’offre pas de sécurité et utilise l’MIB v1 qui reste assez simple
- La seconde version a été publiée en 1993
- $ \Rightarrow $ plus de sécurité tant au niveau de l’authentification que du chiffrement
- $ \Rightarrow $ permet l’administration distribuée
- $ \Rightarrow $ apporte une version plus riche de la MIB (MIB-2)
- La version 3 a été publiée en 1998
- $ \Rightarrow $ apporte des transactions chiffrées via
SSH
- $ \Rightarrow $ plus modulaire
- $ \Rightarrow $ apporte des transactions chiffrées via
Dans les faits
- La version 2 a eu du mal à démarrer et plusieurs “releases” ont été faites. C’est la version “2c” qui a su s’imposer. Plus d’informations:
- La version 3, tout comme la v2 a eu du mal à s’imposer aussi. Elle n’est toujours pas supportée par tous les matériels aujourd’hui même si cela s’est bien amélioré. Les problèmes de sécurité étant devenu vraiment sensibles de nos jours, elle est la version recommandée.
SNMP
domine le monde TCP/IP et il est le standard recommandé depuis mai 1990
2. Les MIBs
La Management Information Base est une base de données “virtuelle” permettant d’organiser de manière hiérarchique les informations fournies par les agents sur les équipements.
Ce n’est pas une base de données à proprement parler comme une base relationnelle. Elle n’existe qu’au travers de l’agent qui est libre de l’implémenter comme il le souhaite. Quand l’agent ne fonctionne pas, il n’y a pas de données dans la MIB. Seule la description de la MIB (un fichier texte) existe.
Une MIB décrit en fait comment numéroter/accéder à l’information.
C’est l’agent qui stock (mais on devrait dire gère) comme il veut cette information, laquelle est le plus souvent “volatile”.
Il est très important de bien comprendre le point précédent, c’est ce qui gêne souvent la compréhension des MIBs par les nouveaux arrivants sur ce protocole.
Prenons l’exemple du nombre de processus actifs sur une machine. Celui-ci est identifié de façon unique par la MIB-2. Mais cette information est demandée par l’agent au système d’exploitation au moment ou il reçoit une requête pour cette dernière, car cette donnée est changeante à chaque instant. Elle n’est donc pas “stockée” par l’OS. Elle n’est pas accessible au travers d’une requête SQL
. Elle est fournie quand on la demande , et tant que l’agent ne l’a pas demandée lui-même à l’OS, elle n’est pas vraiment disponible ou n’a pas encore d’existence.
- Le manager demande l’information à l’agent
- L’agent reçoit la demande et appelle une primitive système pour l’obtenir
- L’agent retourne l’information au manager
C’est une information “volatile” qui n’est pas vraiment stockable.
Note perso: en gros, l’agent demande une information qui a une certaine relevance à un moment T.
Beaucoup d’informations issues des MIBs sont de cette nature, d’autres sont parfois stockées quelque part, comme le responsable d’une machine, le port d’un service ou encore l’état d’une ligne élecrtique ou d’une diode (éteinte, allumée).
Selon les constructeurs/OS ces informations sont stockées physiquement différemment, mais la MIB les normalise pour la grande majorité afin qu’une même information soit toujours demandée de la même manière par le manager. C’est à l’agent de savoir ou aller la chercher selon le matériel/service géré.
Cela apporte beaucoup de facilités dans l’écriture de sondes/outils de supervisions. C’est une des grandes forces de ce standard.
MIB-2
Une des MIB les plus connues est la MIB-2, décrite par la RFC 1213. Elle est mise en oeuvre dans la presque totaltalité des équipements TCP/IP. Elle compte 10 groupes:
- système
- interfaces
- Adresse Translation
- IP
- ICMP
- TCP
- UDP
- EGP
- transmission
- SNMP
C’est a dire que toute information que vous pourriez demander concernant la MIB-2 sera classée dans l’un de ces groupes. Des exemples d’informations que vous pourriez retrouver dans ces ensembles, sont:
- liste des processus (avec info mémoire et CPU)
- débits réseaux
- load average
- utilisation mémoire
- contact du système $ \Rightarrow $ uptime
- utilisation de l’espace disque
- tables de routage
Exemple de descitpion d’une MIB
Les mibs sont décrites dans un “langage” appelé ASN.1. L’exemple suivant présente l’information “descitpion d’interface (réseau)” telle que décrite en ASN.1:
ifDescr OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..255))
ACCESS read-only
STATUS mandatory
DESCRIPTION
"A textual string containing information about the
interface. This string should include the name of
the manufacturer, the product name and the version
of the hardware interface."
::= { ifEntry 2 }
La lecture de la définition de cette donnée est assez compréhensible par elle-même:
- nom:
ifDescr
- type:
DisplayString
: une string de 255 char max - mode d’accès: “lecture seule”
- son état (
STATUS
): “obligatoire” - enfin son emplacement dans le noeud parent
ifEntry
: 2ème sous-élément du noeudifEntry
### Organisation de l’information dans les MIBs
Pour bien comprendre cette description “hiérarchique” de la donnée ifDescr
, voici un graph représentant la hiérarchie principale de toutes les MIBs:
Sous le noeud racine, noté .
se trouvent 3 informations numérotées:
CCITT
avec le numéro 0ISO
avec le numéro 1ISO - CCITT
avec le numéro 2
Sous le noeud ISO
se trouvent 4 informations, elles aussi numérotées:
- standard, avec le numéro 0
- registration authority, avec le numéro 1
- member body, avec le numéro 2
- organization, avec le numéro 3
Le chemin d’accès à l’information organisation
située sous ISO
, elle-même située sous la racine sera .1.3
ou encore .ISO.organzation
.
Par exemple, l’accès à l’information MIB-2 se fera via le chemin:
.1.3.6.1.2.1
ou encore
.ISO.organisation.DoD.Internet.management.MIB-2
En gros
Les MIBs définissent des informations en ASN.1 lesquelles sont accessibles via un chemin exprimé avec des numéros ou les noms des informations parentes.
Les OID
Les informations sont donc numérotées selon leur ordre dans l’arbre de la MIB, ces numéros sont appelées OID (Object IDentifier). Voici quelques exemples d’OIDs:
.1.3.6.1.2.1.1 system : uptime, contact, nom
.1.3.6.1.2.1.2 interfaces: interfaces réseau
.1.3.6.1.2.1.4 ip: ip routing, etc
.1.3.6.1.2.1.5 icmp: icmp errors, discards... (icmp c'est par exemple le ping)
.1.3.6.1.2.1.6/7 tcp ou udp: états des connexions tcp ou udp
La question devient maintenant “Comment trouver toutes les informations desponibles dans une MIB?” Les réponses seront:
- En lisant les standards et normes associés rfc1213
- En exécutant des requêtes avec des outils
SNMP
qui permettent de parcourir toute l’arborescence d’une MIB - En parcourant ces MIBs via des sites Internet qui ont l’amabilité de les représenter facilement, comme le site IP Monitor
On observera sur ce dernier que le chemin complet à l’information ifDescr
est fournit par l’OID 1.3.6.1.2.1.2.2.1.2
. C’est ce que va nous permettre de fire PySNMP: Envoyer des requêtes demandant la valeur d’un noeud (une information) située à un emplacement précis dans une MIB ou modifiant cette valeur.
Et c’est tout…
Un univers de MIBs
Il exite beaucoup de MIBs différentes:
- Selon le matériel (routeur, imprimante…) les informations sont différentes
- Pour cette raison, certains équipements ou constructeurs fournissent donc leurs propres MIB définissant une branche dans l’arbre des OIDs avec un numéro officiel défini auprès de l’IANA (Internet Assigned Numbers Authority). On retrouve par exemple CISCO à cette branche de l’arbre:
iso.org.dod.internet.private.entreprise.cisco
=1.3.6.1.4.1.9
. A cet emplacement,CISCO
est libre de proposer les MIBs décrivant les informations de ses propres matériel comme il l’entend. Beaucoup d’autres sociétés en font autant, comme Alcatel/Nokia pour ne citer qu’eux.
Les sites/logiciels comme IP monitor présentent de nombreuses MIB pour différents types d’informations/matériel/services
3. Les communautés
L’accès aux informations d’une MIB est filtré par ce qu l’on appelle la “communauté”, sauf version 3 du protocole. La “communauté” est une sorte de de mot partagé, “public” par défaut. “public” peut-être rapproché du login “anonymous” disponible sur la plupart des serveurs ftp
.
Une demanade d’informations est toujours exécutée via une communauté. Selon la communauté utilisée, les informations reçues seront différentes:
- la communauté “public” donne accès au niveau “read-only”
- il existe un niveau privé en lecture/écriture (communauté “private”) qui est le plus souvent désactivé (il donne accès à toute la configuration système en écriture)
Donc quand nous souhaitons accéder à/ou modifier une information d’un agent, on:
- envoie une requête
GET
/SET
à l’agent - en fournissant le chemin de l’information désirée, son OID
- en fournissant la communauté utilisée (“private” pour les modifications)
- en fournissant l’adresse IP/nom de domaine ou s’exécute l’agent
- le port utilisé est par défaut le port
161
4. Utilisation du protocole en ligne de commande
Pour bien comprendre ce que permet ce protocole, nous allons exécuter les commandes de base avec des outils systéme. Ceci permettra de toucher du doigt la mécanique sous-jacente et de vérifier que les agents comprennent bien nos roquêtes avant de les écrire en Python.
Les commandes
Requêtes proposées par le protocole pour permettre aux manager et agents de s’échanger de l’information:
GET
$ \Rightarrow $ demande la valeur d’un OID par le manager à l’agent. L’agent retourne l’information via un message de typeRESPONSE
GETNEXT
$ \Rightarrow $ demande l’information suivante dans la MIB. Permet de parcourir une MIB sans connaître ce qu’elle contientSET
$ \Rightarrow $ modifie la valeur associée aa un OIDGETBULK
$ \Rightarrow $ demande tout un ensemble d’infos au manager contenant l’information demandéeRESPONSE
$ \Rightarrow $ message envoyé par l’agent au manager contenant l’information demandéeTRAP
: $ \Rightarrow $ message envoyé par l’agent au manager pour signaler un problèmeINFORM
$ \Rightarrow $ msg envoyé par le manager. Confirme réception duTRAP
.
Prérequis
Pour lancer nos premières commandes, il convient de disposer d’un agent et d’un manager.
Pour le manager, nous pouvons installer les outils snmp
et mibs
de base via ces commandes
sudo apt-get install snmp snmp-mibs-downloader
sudo apt-get install smitools libsmi
Pour trouver un agent, nous pouvons:
- Essayer avec une imprimante réseau ou une machine possédant une adresse Ip. Généralement elles sont compatibles avec les protocoles
SNMP
- Installer notre propre agent en suivant le tutoriel suivant: how to install and configure an SNMP Daemon and client (linux)
- Lancer nos commandes vers l’agent
demo.snmplabs.com
librement accessible via Internet.
Si nous ne disposons pas de la possibilité d’installer les commandes
SNMP
sous Linux, il est bon de savoir que la librairiePySNMP
propose des scripts équivalents en pur Python qu’on peut installer avec la commandepip install pysnmp-apps
La commande GET
Accepte plusieurs paramètres dont:
-v
$ \Rightarrow $ version du protocole-c
$ \Rightarrow $ communauté-O
$ \Rightarrow $ format de sortie (a,f,n,s,…)
exemple
Avant tout il faut commenter la ligne contenant mibs :
dans /etc/snmp/snmp.conf
sol@debian:~/Downloads/Python-3.6.1$ snmpget -v2c -c public -Oa demo.snmplabs.com sysDescr.0
SNMPv2-MIB::sysDescr.0 = STRING: Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686
La version du protocole à utiliser est obligatoire, dans la commande précédente, nous utilisons le protocole version 2c
(v2c
) et la communauté public
. Nous demandons l’information sysDescr
. Pour ce faire nous ajoutons le chemin .0
qui désigne la valeur du noeud sysDescr
.
Les autres valeurs sous un noeuds (.1.2
, etc…) désignent les sous éléments de ce dernier. Les informations peuvent donc être demandées via le chemin complet comme sous la forme d’un OID
numérique 1.3.6.1.2.1.1.1.0
(ou textuel ou encore via le nom court. $ \Rightarrow $ normalement unique).
Même commande avec l’OID:
sol@debian:~/Downloads/Python-3.6.1$ snmpget -v2c -c public -Oa demo.snmplabs.com 1.3.6.1.2.1.1.1.0
iso.3.6.1.2.1.1.1.0 = STRING: "Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686"
La commande GETNEXT
Elle accepte les mêmes paramètres que GET
mais retourne non pas l’OID
demandé mais celui qui suit dans l’arborescence. En chainant un GET
puis plusieurs GETNEXT
on peut donc consulter tout l’arbre d’une MIB
.
sol@debian:~/Downloads/Python-3.6.1$ snmpgetnext -v2c -Oa -c public -Os demo.snmplabs.com sysDescr.0
sysObjectID.0 = OID: netSnmpAgentOIDs.10
On peut exécuter GETNEXT
sur n’importe quel noeud, donc la racine d’une MIB mais parcoutir tout un arbre est laborieux.
Les commandes GET BULK et WALK
Pour éviter d’envoyer plusieurs commandes GET
les unes après les autres ce qui surcharge les échanges réseau, il est possible de demander à consulter plusieurs OID
en une seule fois via la commande GET BULK
. Mais tous les agents ne le supportent pas.
On peut aussi utiliser la commande WALK
pour parcoutir toute une arborescence, comme on le ferait avec GET
et GET NEXT
. Mais c’est la commande WALK
qui les exécute pour nous.
sol@debian:~/Downloads/Python-3.6.1$ snmpwalk -v2c -On -c public -Os demo.snmplabs.com system
sysDescr.0 = STRING: Linux zeus 4.8.6.5-smp #2 SMP Sun Nov 13 14:58:11 CDT 2016 i686
sysObjectID.0 = OID: netSnmpAgentOIDs.10
sysUpTimeInstance = Timeticks: (274672133) 31 days, 18:58:41.33
sysContact.0 = STRING: SNMP Laboratories, info@snmplabs.com
sysName.0 = STRING: new system d
sysLocation.0 = STRING: San Francisco, California, United States
sysServices.0 = INTEGER: 72
sysORLastChange.0 = Timeticks: (274672261) 31 days, 18:58:42.61
sysORID.1 = OID: snmpFrameworkMIBCompliance
sysORID.2 = OID: snmpMPDCompliance
sysORID.3 = OID: usmMIBCompliance
sysORID.4 = OID: snmpMIB
sysORID.5 = OID: tcpMIB
sysORID.6 = OID: ip
sysORID.7 = OID: udpMIB
sysORID.8 = OID: vacmBasicGroup
sysORDescr.1 = STRING: The SNMP Management Architecture MIB.
sysORDescr.2 = STRING: The MIB for Message Processing and Dispatching.
sysORDescr.3 = STRING: The management information definitions for the SNMP User-based Security Model.
sysORDescr.4 = STRING: The MIB module for SNMPv2 entities
sysORDescr.5 = STRING: The MIB module for managing TCP implementations
sysORDescr.6 = STRING: The MIB module for managing IP and ICMP implementations
sysORDescr.7 = STRING: The MIB module for managing UDP implementations
sysORDescr.8 = STRING: View-based Access Control Model for SNMP.
sysORUpTime.1 = Timeticks: (1506) 0:00:15.06
sysORUpTime.2 = Timeticks: (1506) 0:00:15.06
sysORUpTime.3 = Timeticks: (1506) 0:00:15.06
sysORUpTime.4 = Timeticks: (1506) 0:00:15.06
sysORUpTime.5 = Timeticks: (1506) 0:00:15.06
sysORUpTime.6 = Timeticks: (1506) 0:00:15.06
sysORUpTime.7 = Timeticks: (1506) 0:00:15.06
sysORUpTime.8 = Timeticks: (1506) 0:00:15.06
Traduire les OIDs
La commande snmptranslate
permet de traduire des OID
du mode numérique au mode texte et inversément
sol@debian:~/Downloads/Python-3.6.1$ snmptranslate -On SNMPv2-MIB::sysDescr.0
.1.3.6.1.2.1.1.1.0
sol@debian:~/Downloads/Python-3.6.1$ snmptranslate .1.3.6.1.2.1.1.1.0
SNMPv2-MIB::sysDescr.0
Modifier un OID, la commande SET
La commande snmpset
permet de modifier la valeur d’un OID
. Elle n’est disponible qu’avec le protocole v2 et la communauté private
ou le protocole v3.
L’exemple suivant est fourni par le protocole v3. Les paramètres utilisés sont:
-u
$ \Rightarrow $ utilisateur-l
$ \Rightarrow $ niveau de sécurité pour s’identifier-a
$ \Rightarrow $ protocole d’authentification (chiffrement mdp)-A
$ \Rightarrow $ mot de passe d’authentification-x
$ \Rightarrow $ algorithme de chiffrement pour la connexion-X
$ \Rightarrow $ mot de passe/salt pour le chiffrement de la connexion
C’est là qu’on découvre le côté pénible du protocole v3 qui implémente lui-même les connexions SSH
sans faire de SNMP
over SSH
: Il n’y a pas d’auto-négociation des algorithmes de chiffremen, il faut tout préciser par sois-même. Vrmt chiant…
N’a pas fonctionné chez moi.
$ snmpget localhost sysLocation.0
SNMPv2-MIB::sysLocation.0 = STRING: Rouans
$ snmpset -u demo -l authPriv -a MD5 -x DES -A pass1 -X pass2 localhost sysLocation.0 s "Earth"
SNMPv2-MIB::sysLocation.0 = STRING: Earth
$ snmpget localhost sysLocation.0
SNMPv2-MIB::sysLocation.0 = STRING: Earth
Recommandations concernant l’utilisation du protocole SNMP et outils associés
Les versions 1 et 2 du protocole sont insuffisamment sécurisées (pas du tout pour la première)
La protection dans la v2 du protocole se fait uniquement via les communautés
qui n’utilisent pas de mdp. Ce n’est pas très fiable comme type de protection, car il suffit de connaître le nom de la communauté pour accéder aux informations d’un matériel qui pourrai s’avérer être sensible.
Les agents de Windwos XP étaient particulièrement réputés pour proposer dans leur configuration par défaut beaucoup trop d’informations sensibles, comme les logins des utilisateurs qui étaient accessibles directement via la communauté public
.
Dans la pratique l’agent fournit par les outils NetSNMP (sous linux) est relativement lent et n’est pas forcément très bien sécurisé, beaucoup de failles sont découvertes régulièrement.
Aussi quelque soit la solution retenue, désactivez systématiquement le mode anonyme, ou alors contrôlez chaque information proposée. Puis créer des ACLS
d’accès à chaque MIB
par utilisateur afin d’avoir une maîtrise complète de qui peut faire quoi.
Enfin, il est très important de privilégier la version 3 du protocole !