SNMP v3

par franck, juillet 2007 maj par julien, décembre 2008

Présentation

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.

Installation / Configuration de SNMP v3

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.

Les agents

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 :

  • “rouser” définit un utilisateur ayant accès en lecture seule à toutes les MIB (sinon, on peut la préciser en rajouter “system” a la fin, par exemple). Le mode “priv” force l'utilisation du chiffrement
  • “createUser” crée cet utilisateur avec un mot de passe scellé avec HMAC-SHA et une passphrase de chiffrement pour AES
  • les lignes syslocations et syscontact sont purement facultatives

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

Test de SNMP v3

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.

Vérifications, conclusion de la partie "configuration de SNMP"

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:

  1. test : un compte avec authentification HMAC-SHA et chiffrement AES
  2. youpi : un compte sans rien

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.

1er screenshot : la réponse en clair

2eme screenshot : la réponse 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 :

1. la réponse en clair

    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

2. la réponse chiffrée

    msgData: encryptedPDU (1)
        encryptedPDU: 7551A8AFF145EDDEDD81ACD2632540F0F1FB98A117D7E7F9...

Ca c'est de la requête bien cryptée des familles ! 8-)

A lire :

D'un point de vue “configurationnel”

D'un point de vue sécuritaire :

~~DISCUSSION~~

fr/ressources/dossiers/supervision/snmpv3.txt · Last modified: 2011/03/16 01:41 (external edit)
CC Attribution-Noncommercial-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0