====== En savoir un peu plus ====== Nous avons rapidement vu les outils permettant de soutirer des informations aux agents SNMP, à cette occasion nous avons parlé de communautés, mais nous n'avons pas vu ce que c'est. Voyons ceci en configurant (un minimum) un agent SNMP sur une distribution GNU/Linux. ===== Les versions de SNMP ===== Il semble bien qu'au final, seules les versions 1, 2c (classique) et 3 soient utilisées. La version 3 apporte des fonctions de sécurité (chiffrement et authentification) qui permettent d'utiliser SNMP dans un environnement « hostile », mais n'est pas implémenté sur tous les matériels. Cette version n'apportant rien de plus pour la compréhension du fonctionnement de SNMP, nous n'en parlerons pas d'avantage. La version 1 est généralement implémentée sur tous les équipements proposant SNMP, de même que la version 2c, qui ne fait qu'ajouter des compteurs sur 64 bits et une commande supplémentaire : ''GetBulk-Request''. Cette nouvelle commande donne le même résultat que la commande ''Get-next-request'', mais de façon plus efficace. Nous verrons cela plus loin dans les analyses de trames. Ces deux versions offrent une sécurité tout à fait indigente. Il n'y a ni chiffrement des données, ni authentification (aussi bien de l'agent que du manager). Dans un environnement « hostile » il restera possible de pallier cet inconvénient par l'usage de tunnels chiffrés, de vlans etc. Voyons tout de même ce que proposent les versions 1 et 2 en termes de restrictions d'accès. ==== Les communautés et leurs privilèges ==== Nous illustrerons le propos en configurant l'agent ''snmpd'' proposé dans les distributions GNU/Linux. Une communauté représente un groupe d'utilisateurs. Nous nous sommes jusqu'ici déclarés de la communauté ''public'' (option ''-c public'' dans les diverses commandes). Par défaut, la plupart des équipements proposent les communautés ''public'' et ''private''. Il est toutefois possible de les renommer ou d'en créer d'autres. La communauté ''public'' n'a généralement accès qu'en lecture, et pas forcément à toute l'étendue des informations exposées. La communauté ''private'' est généralement exploitée pour écrire (donc reconfigurer) un équipement et disposer de la totalité des informations que l'agent sait exposer. Il est donc nécessaire d'en réserver l'accès aux seuls administrateurs autorisés, mais ceci ne peut se faire que sur la base des adresses IP des managers, ce qui reste très rudimentaire. Il est clair que dans un environnement hostile, il reste assez simple d'utiliser SNMP (v 1 et 2) à des fins tout à fait malveillantes. Nous allons faire quelques manipulations sur notre Lynx Lucide pour illustrer les restrictions que l'on peut appliquer avec les communautés. Nous avons fait, lors de l'installation de ''snmpd'' une modification de la configuration par défaut. Revoici une configuration minimale, équivalente, ne prenant en compte que les versions 1 et 2c de SNMP : com2sec readonly default public com2sec readwrite default private group MyROGroup v1 readonly group MyROGroup v2c readonly group MyRWGroup v1 readwrite group MyRWGroup v2c readwrite view all included .1 access MyROGroup "" any noauth exact all none none access MyRWGroup "" any noauth exact all all none La logique séquentielle de ce fichier n'est pas forcément la meilleure pour en comprendre le principe. Commençons donc par les ''view''. == Les « view » == Ici nous n'avons qu'une ''view'' qui inclut la totalité de l'arbre (.1) et qui s'appèle ''all''. Nous aurions pu tout aussi bien écrire view bidule included .1 ou view machin included .1 le mot-clé est ''view'' le nom de la vue sera ''all'' (ou ''bidule'' ou ''machin'') et ce qui est inclus dans cette vue c'est ''.1'' c'est-à-dire la totalité de ce que l'agent peut proposer. == Les « group » == Nous créons des noms de groupes auxquels nous associons un « nom de sécurité », en fonction de la version du protocole utilisé. Ceci n'a de réel sens qu'avec la version 3, mais en v1 et en v2c, il faut en passer par là quand même. Nous avons écrit : group MyROGroup v1 readonly group MyROGroup v2c readonly group MyRWGroup v1 readwrite group MyRWGroup v2c readwrite Nous aurions aussi bien pu faire : group voyeurs v1 regarderMaisPasToucher group voyeurs v2c regarderMaisPasToucher group violeurs v1 regardeEtPlus group violeurs v2c regardeEtPlus pas forcément du meilleur gout, mais tout aussi correct syntaxiquement parlant. Ces groupes et noms de sécurité nous serviront plus loin. == Les « access » == Ils sont de la forme : access GROUP CONTEXT {any|v1|v2c|usm} LEVEL PREFX READ WRITE NOTIFY On va faire simple : * le ''CONTEXT'' n'a de sens que pour la version 3 ; * le ''LEVEL'' est forcément ''noauth'' pour les versions 1 et 2c ; * le ''PREFIX'' n'a pas de sens pour v1 et v2c, nous mettrons ''exact'' ; * le ''NOTIFY'' « is not currently used ». reste donc : * le ''GROUP'' est un nom que l'on a créé de toutes pièces, juste au dessus ; * le ''READ'' sera le nom de la vue dans laquelle le groupe aura le droit de lire ou ''none'' s'il ne peut rien lire (ce qui n'aurait aucun sens, pourquoi créer un groupe qui aurait le droit de ne rien lire) ; * le ''WRITE'' sera le nom de la vue dans laquelle le groupe pourra écrire (ou ''none'' s'il ne peut écrire). Ainsi, dans notre fichier : access MyROGroup "" any noauth exact all none none access MyRWGroup "" any noauth exact all all none Veut dire qu'il existe deux groupes, ''MyROGroup'' et ''MyRWGroup'' : * ''MyROGroup'' peut lire dans la vue ''all'' mais ne peut y écrire et ce, en utilisant aussi bien les protocoles v1 que v2c ; * ''MyRWGroup'' peut aussi bien lire qu'écrire dans la vue ''all'' aussi bien en v1 qu'en v2c. == Le « com2sec » == C'est ici que l'on recolle tous les morceaux, en ajoutant en prime les communautés. De la forme : com2sec [-Cn CONTEXT] SECNAME SOURCE COMMUNITY * ''CONTEXT'' n'a toujours pas de sens en v1 ni en v2c) ; * ''SECNAME'', ça vient d'un peu plus haut dans l'explication ; * ''SOURCE'', c'est l'adresse IP source (ou le sous-réseau IP, ou ''default'' si c'est « wide open ») ; * ''COMMUNITY'', c'est le nom de la communauté dans laquelle l'agent s'est déclaré. Nous avons : com2sec readonly default public com2sec readwrite default private Autrement dit, le groupe de sécurité ''readonly'' (qui aurait pu s'appeler ''regarderMaisPasToucher'') est attaché à la communauté ''public''. Comme ce groupe de sécurité est attaché au groupe ''MyROGroup'' (qui aurait pu s'appeler ''voyeurs'') pour les protocoles v1 et v2c et que ce groupe ''MyROGroup'' peut aussi bien en v1 qu'en v2c lire et seulement lire partout, il s'ensuit que tout manager qui se connectera sur notre hôte en se déclarant de la communauté ''public'' pourra lire ce qu'il veut. L'ennui, c'est que si le manager se déclare de la communauté ''private'', qui est attachée au groupe de sécurité ''readwrite'' (qui aurait pu s'appeler ?...) depuis n'importe où (''default'') et que ce groupe de sécurité est attribué au groupe ''MyRWGroup'' (qui aurait pu s'appeler ?...), lequel peut lire dans ''all'' mais aussi y écrire, alors ce manager pourra modifier tout ce qui est modifiable sur notre hôte, preuve que notre configuration est complètement nulle. En fait, elle est là pour l'exemple, nous en ferons une moins sale par la suite. == Particularité Debian == (Et dérivées) Le fichier ''/etc/default/snmpd'' contient des options ajoutées lors du lancement du service ''snmpd''. Ces options, par défaut, limitent le service à écouter sur 127.0.0.1 :
# This file controls the activity of snmpd and snmptrapd

# MIB directories.  /usr/share/snmp/mibs is the default, but
# including it here avoids some strange problems.
export MIBDIRS=/usr/share/snmp/mibs

# snmpd control (yes means start daemon).
SNMPDRUN=yes

# snmpd options (use syslog, close stdin/out/err).
SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -g snmp -I -smux -p /var/run/snmpd.pid 127.0.0.1'

# snmptrapd control (yes means start daemon).  As of net-snmp version
# 5.0, master agentx support must be enabled in snmpd before snmptrapd
# can be run.  See snmpd.conf(5) for how to do this.
TRAPDRUN=no

# snmptrapd options (use syslog).
TRAPDOPTS='-Lsd -p /var/run/snmptrapd.pid'

# create symlink on Debian legacy location to official RFC path
SNMPDCOMPAT=yes
Un simple ''man snmpd'' nous indiquera clairement (une fois n'est pas coutume) qu'il suffit d'enlever l'adresse locale dans la ligne d'options pour que ''snmpd'' écoute sur toutes les interfaces. Notez que si nous avons deux interfaces, dont par exemple une attachée à un vlan (un vlan pourquoi pas réservé à l'administration des équipements), nous pouvons forcer ''snmpd'' à n'écouter que sur cette interface, ce qui permettrait de sécuriser quelque peu le dispositif. Après modification de cette ligne et redémarrage du service, nous pouvons constater que :
# netstat -lupn
Connexions Internet actives (seulement serveurs)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat       PID/Program name
udp        0      0 0.0.0.0:68              0.0.0.0:*                           639/dhclient    
udp        0      0 0.0.0.0:47712           0.0.0.0:*                           618/avahi-daemon: r
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           618/avahi-daemon: r
udp        0      0 0.0.0.0:161             0.0.0.0:*                           1507/snmpd
===== C'est compris ? ===== Bien sûr ! Et ceci va nous permettre de créer une configuration un peu plus complète de la façon suivante : * une communauté ''public'', qui aura droit à l'accès en lecture seule, mais seulement à la branche ''system'' pour tous ceux qui peuvent joindre notre agent, quelle que soit leur adresse IP ; * une communauté ''private'' aura droit à la lecture seule de toutes les informations possibles, mais seulement à partir d'un réseau IP particulier ; * une communauté ''admin'' pourra lire et écrire partout où c'est possible, mais depuis une adresse IP bien particulière. Voici la configuration proposée : com2sec voirUnPeu default public com2sec voirTout 192.168.0.0/24 private com2sec voirEtToucher 192.168.0.16 admin group touristes v1 voirUnPeu group touristes v2c voirUnPeu group riverains v1 voirTout group riverains v2c voirTout group proprio v1 voirEtToucher group proprio v2c voirEtToucher view system included .1.3.6.1.2.1.1.1 view all included .1 access touristes "" any noauth exact system none none access riverains "" any noauth exact all none none access proprio "" any noauth exact all all none ==== Interro surprise 2 ==== - Quelqu'un se déclarant de la communauté ''public'' pourra-t-il - se connecter depuis n'importe quelle adresse IP ? - obtenir les informations de la branche ''.iso.org.dod.internet.mgmt.mib-2.interfaces'' ? (on pourra s'aider de ''snmptranslate'' pour obtenir la version numérique de cette branche) - Quelqu'un se déclarant de la communauté ''private'' pourra-t-il - obtenir les informations de la branche ''.iso.org.dod.internet.mgmt.mib-2.interfaces'' s'il dispose de l'adresse 192.168.1.25 ? - obtenir les informations de la branche ''.iso.org.dod.internet.mgmt.mib-2.interfaces'' s'il dispose de l'adresse 192.168.0.25 ? - Quelqu'un se déclarant de la communauté ''admin'' depuis l'adresse IP 192.168.0.17 - pourra-t-il obtenir les informations de la branche ''.1.3.6.1.2.1.2'' ? - pourra-t-il modifier une valeur accessible en écriture (SNMPv2-MIB::sysLocation par exemple) ? Réponses toujours en dernière page.