snmp supervision
par franck, juillet 2007 maj par julien, décembre 2008
On cherche à mettre en place des outils permettant de surveiller les serveurs linuxwall.info. Pour cela l'outil le plus classique est SNMP.
SNMP (Simple Network Management Protocol) est un protocole particulièrement adapté à la surveillance et la mesure de noeuds dans un réseau informatique. Il peut être également étendu à leur gestion dans une certaine mesure (c'est-à-dire agir sur ces noeuds). SNMP n'a pas bonne presse en terme de sécurité, mais il est toutefois possible d'arriver à un bon compromis en faisant attention à ce que l'on fait. On dispose pour cela dans la version 3 d'un cryptage et d'une authentification.
La version 3, telle qu'elle est définie dans la RFC 2570 et 2574, vise à pallier les déficiences de la version 2 afin d'utiliser SNMP de façon sécurisée de bout en bout.
À cette fin, elle permet de définir les autorisations et les contrôles d'accès. D'où la naissance du modèle USM (User-based Security Model) pour éviter la falsification des messages de commande en utilisant des mots de passe personnels scellés avec HMAC-MD5 ou HMAC-SHA, au choix. Mieux encore, lors de la transmission d'un message, USM modifie à chaque noeud la clé de chiffrement, ce qui évite, si un segment est endommagé, de menacer l'intégrité des informations reçues par le reste du réseau.
De plus, un cryptage des données est mise en place, en ayant recours cette fois à l'algorithme DES ou AES. La version 3 de SNMP abrite en outre un mécanisme de synchronisation entre les différents moteurs SNMP afin d'empêcher la duplication d'un message lors de son trajet en s'appuyant sur le temps parcouru depuis l'émetteur jusqu'au récepteur.
Les données décrites et transportées par ce protocole utilisent un nommage hiérarchique. Certaines branches sont normalisées et décrivent donc des mesures et des unités connues, d'autres branches sont maintenues par des entreprises pour leur besoins propre (CISCO, etc). L'ensemble du catalogue des informations gérables via SNMP s'appelle la MIB (Management Information Base). Techniquement, le nommage d'une information précise dans la hiérarchie d'une MIB se fait à l'aide d'une notation sous forme d'identifiants séparés par des points (un chemin hiérarchique), et qui commencent par un “1” (.1.3.6.1.6.3.1.1.5.3). On peut aussi récupérer des informations directement avec leurs noms (sysName.0).
Une fois que toutes les informations sont récupérées, on utilisera Cacti pour faire de beaux graphiques.
Ici, on va voir comment configurer la supervision d'une machine grace aux agents SNMP. Pour la doc, voir les pages de man de snmpd.conf et snmp.examples.
Chaque machine que l'on souhaite monitorer est composée d'un agent et de traps. Les agents servent les informations aux clients qui les contactent et/ou envoient périodiquement ces informations au moyen de traps.
Pour monitorer notre machine, on a besoin du daemon “snmpd”. On ajoute également “snmp” pour pouvoir tester avec le client en local. (Pour utiliser le chiffrement, installer le packet “openssl”)
# apt-get install snmp snmpd
La configuration de l'agent est très simple. On remplace le fichier automatiquement créé par Debian (et particulièrement verbeux) par quelque chose de très basique.
On demande la création d'un seul utilisateur via la ligne “createUser”. Il faut lancer le serveur une fois avec cette ligne dans le fichier de configuration pour que l'utilisateur soit créé.
Attention, la passphrase pour AES doit être supérieure à 8 caractère, sinon snmpd plantera au lancement avec ces lignes dans syslog :
Oct 12 12:54:52 sachiel snmpd[4777]: Error: passphrase chosen is below the length requirements of the USM (min=8). Oct 12 12:54:52 sachiel snmpd[4777]: /etc/snmp/snmpd.conf: line 3: Error: could not generate the authentication key from the supplied pass phrase.
# vi /etc/snmpd/snmpd.conf rouser <utilisateur> priv createUser <utilisateur> SHA <supermotdepasse> AES <superpassphrase> syslocation Paris, France syscontact adresse@email.com
Explication :
On peut ensuite enlever la ligne “createUser” et relancer le serveur avec le fichier snmpd.conf suivant :
# vi /etc/snmpd/snmpd.conf rouser <utilisateur> priv system syslocation Paris, France syscontact adresse@email.com
On ne stocke donc pas de mot de passe dans la config.
Après le restart, syslog affiche simplement les lignes :
Oct 12 12:57:14 miniarael snmpd[4800]: Received TERM or STOP signal... shutting down... Oct 12 12:57:16 miniarael snmpd[4813]: NET-SNMP version 5.4.1
et l'on a un socket UDP en écoute sur le port 161 :
# netstat -upan |grep snmp Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name udp 0 0 127.0.0.1:161 0.0.0.0:* 4662/snmpd
SNMPwalk permet d'afficher le contenu de la MIB. Vous pouvez ensuite choisir une valeur particulière avec SNMPget.
$ snmpwalk -v 3 -u <utilisateur> -l authPriv -a SHA -A <supermotdepasse> -x AES -X <superpassphrase> 127.0.0.1
pour avoir l'uptime
$ snmpget -v 3 -u <utilisateur> -l authPriv -a SHA -A <supermotdepasse> -x AES -X <superpassphrase> 127.0.0.1 sysUpTime.0 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (107614) 0:17:56.14
ou la charge de eth0
$ snmpget -v 3 -u <utilisateur> -l authPriv -a SHA -A <supermotdepasse> -x AES -X <superpassphrase> 127.0.0.1 ifInOctets.2 IF-MIB::ifInOctets.2 = Counter32: 94056351
Si l'on prend la MIB des interfaces réseaux, par exemple, on a la liste des valeurs disponibles dans la RFC 2863 :
IfEntry ::= SEQUENCE { ifIndex InterfaceIndex, ifDescr DisplayString, ifType IANAifType, ifMtu Integer32, ifSpeed Gauge32, ifPhysAddress PhysAddress, ifAdminStatus INTEGER, ifOperStatus INTEGER, ifLastChange TimeTicks, ifInOctets Counter32, ifInUcastPkts Counter32, ifInNUcastPkts Counter32, -- deprecated ifInDiscards Counter32, ifInErrors Counter32, ifInUnknownProtos Counter32, ifOutOctets Counter32, ifOutUcastPkts Counter32, ifOutNUcastPkts Counter32, -- deprecated ifOutDiscards Counter32, ifOutErrors Counter32, ifOutQLen Gauge32, -- deprecated ifSpecific OBJECT IDENTIFIER -- deprecated }
Bon, tout cela marche en local, mais qu'en est il de l'exterieur ??
SNMPd écoute par défaut que les requêtes sur l'adresse IP 127.0.0.1:161 en UDP. Seule la machine sur laquelle SNMPd est installé peut donc faire des requêtes SNMP, comme le montre netstat :
# netstat -upan |grep snmp Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name udp 0 0 127.0.0.1:161 0.0.0.0:* 4662/snmpd
Si on fait le test avec nmap depuis l'exterieur
sachiel:# nmap -sU -p 161 192.168.0.20 Interesting ports on 192.168.0.20: PORT STATE SERVICE 161/udp closed snmp
et depuis l'intérieur
sachiel:# nmap -sU -p 161 127.0.0.1 Interesting ports on wiki.linuxwall.info (127.0.0.1): PORT STATE SERVICE 161/udp open|filtered snmp
Il faut donc modifier la conf, et d'après la doc :
snmpd 127.0.0.1:161 127.0.0.1:6161 The AgentX port option ('-x') works in much the same way.
On adapte, en conséquence, nos paramètres de lancement du démon afin d'écouter sur la bonne interface (ici, 192.32.189.158) :
sachiel:# vi /etc/default/snmpd [...] SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -I -smux -p /var/run/snmpd.pid 192.32.189.158' [...]
Vérification :
# netstat -upan |grep snmp udp 0 0 192.32.189.158:161 0.0.0.0:* 4762/snmpd
Attention toutefois, en faisant cela 127.0.0.1 ne sera plus accessible. En local du serveur, il faudra donc lancer les commande directement sur l'adresse IP.
Le chiffrement des communications en AES dans SNMPv3 est uniquement fait sur la valeur retournée par le protocole. Ce qui laisse l'ensemble des champs SNMP de la requête et de la réponse libres.
Afin de tester cela, on va utiliser deux comptes:
De fait, snmpd.conf ressemble à cela :
rouser test priv system rouser youpi noauth system createUser test SHA testmotdepasse AES testpassphrase createUser youpi syslocation Paris, France syscontact adresse@email.com
On va lancer un tcpdump pour écouter les communications et visualiser tout cela dans Wireshark.
# tcpdump -w /home/julien/dumpsnmp.pcap -s 0 -XSvni lo udp and port 161 tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
note : si l'argument “-s 0” de tcpdump n'est pas positionné, ce dernier ne capture pas la totalité de chaque paquet mais seulement les 68 premiers octets, ce qui n'est pas suffisant pour SNMP
Puis, on lance deux requêtes, une par test avec la sécurité activée, l'autre par youpi à poil. Les deux font un GET sur la même valeur.
# snmpget -v 3 -u youpi -l noauthnopriv 192.32.189.158 ifInOctets.2 IF-MIB::ifInOctets.2 = Counter32: 97826353 # snmpget -v 3 -u test -l authPriv -a SHA -A testmotdepasse -x AES -X testpassphrase 192.32.189.158 ifInOctets.2 IF-MIB::ifInOctets.2 = Counter32: 97836087
Les résultats sont OK, on visualise le fichier obtenu avec Wireshark. Les paquets 1 à 4 sont la requête en clair, les paquets 5 à 8 la requête chiffrée.
On voit bien les bits Encrypted et Authenticated qui sont valorisés à 1 pour la requête chiffrée alors qu'il sont à 0 pour la requête en clair.
On peut également vérifier le champ msgData de chaque paquet :
msgData: plaintext (0) plaintext contextEngineID: 80001F888056FFB63F2CB9F148 1... .... = Engine ID Conformance: RFC3411 (SNMPv3) Engine Enterprise ID: net-snmp (8072) Engine ID Format: Reserved/Enterprise-specific (128): Net-SNMP Random Engine ID Data: 56FFB63F Engine ID Data: Creation Time: Oct 12, 2008 10:45:32 contextName: <MISSING> data: get-response (2) get-response request-id: 1790278574 error-status: noError (0) error-index: 0 variable-bindings: 1 item IF-MIB::ifInOctets.2 (1.3.6.1.2.1.2.2.1.10.2): 97826353 Object Name: 1.3.6.1.2.1.2.2.1.10.2 (IF-MIB::ifInOctets.2) IF-MIB::ifEntry.ifIndex: 2 IF-MIB::ifInOctets: 97826353
msgData: encryptedPDU (1) encryptedPDU: 7551A8AFF145EDDEDD81ACD2632540F0F1FB98A117D7E7F9...
Ca c'est de la requête bien cryptée des familles !
A lire :
D'un point de vue “configurationnel”
D'un point de vue sécuritaire :
~~DISCUSSION~~