%
Puffy image/svg+xml Puffy 2019-06-14 Stéphane HUC OpenBSD Team Inkscape Puffy OpenBSD https://www.openbsd.org/art4.html English "Puffy", it's a symbol of OpenBSD

Pysnmp: outil Python pour SNMP (authPriv v3)

Article publié, le et modifié le
5 minutes de lecture

Cet article contient 882 mots.
Source brute de l'article :
Commit version : 698e16e

Description

pysnmp est une librairie en Python, multiplateforme pour SNMP , capable d’agir en tant qu’agent, gestionnaire, proxy, sur les trois versions du protocole SNMP, de “discuter” sur les protocoles réseaux IPv(4|6).

Le propos est de (dé) montrer l’utilisation de pysnmp avec l’authentification forte de la v3 de SNMP.

Documentation

Installation

  • OpenBSD 6.6
  • Version : 4.4.6

Sous OpenBSD, Installez le paquet py3-snmp

Malheureusement, cette version ne semble pas (pleinement ?) fonctionnelle.

Donc, installons-le par le biais de l’outil pip : # python3.7 -m pip install --upgrade --user pysnmp

Travailler avec les MIB OpenBSD

L’équipe OpenBSD a créé ses propres MIB - ce sont des arborescences de données, que l’on peut aussi appeler “base de données arborescente” -

pysnmp nativement n’est pas capable de les interroger. Mais heureusement, on peut lui “donner à manger”.

Avec pysnmp est fourni un outil nommé mibdump.py - depuis la v4.3 ; avant il fallait utiliser build-pysnmp-mib.py -, et lui indiquer le chemin des MIB d’OpenBSD.

Ces MIB sont fournis dans le répertoire /usr/share/snmp/mibs/.

$ for file in /usr/share/snmp/mibs/*; do mibdump.py $file; done
Source MIB repositories: /usr/share/snmp/mibs, file:///usr/share/snmp/mibs, http://mibs.snmplabs.com/asn1/@mib@
Borrow missing/failed MIBs from: http://mibs.snmplabs.com/pysnmp/notexts/@mib@
Existing/compiled MIB locations: pysnmp.smi.mibs, pysnmp_mibs
Compiled MIBs destination directory: /home/zou/.pysnmp/mibs
MIBs excluded from code generation: INET-ADDRESS-MIB, PYSNMP-USM-MIB, RFC-1212, RFC-1215, RFC1065-SMI, RFC1155-SMI, RFC1158-MIB, RFC1213-MIB, SNMP-FRAMEWORK-MIB, SNMP-TARGET-MIB, SNMPv2-CONF, SNMPv2-SMI, SNMPv2-TC, SNMPv2-TM, TRANSPORT-ADDRESS-MIB
MIBs to compile: OPENBSD-BASE-MIB
Destination format: pysnmp
Parser grammar cache directory: not used
Also compile all relevant MIBs: yes
Rebuild MIBs regardless of age: no
Dry run mode: no
Create/update MIBs: yes
Byte-compile Python modules: yes (optimization level no)
Ignore compilation errors: no
Generate OID->MIB index: no
Generate texts in MIBs: no
Keep original texts layout: no
Try various file names while searching for MIB module: yes
Created/updated MIBs: OPENBSD-BASE-MIB
Pre-compiled MIBs borrowed:
Up to date MIBs: OPENBSD-BASE-MIB, SNMPv2-CONF, SNMPv2-SMI, SNMPv2-TC
Missing source MIBs:
Ignored MIBs:
Failed MIBs:
()

je n’ai volontairement recopié que la sortie écran du premier fichier

Les lignes à vérifier sont :

  • MIBs to compile qui nous montre quel fichier est compilé
  • Created/updated MIBs qui nous restitue le nom du nouveau fichier compilé
  • Ignored MIBs et Failed MIBs qui peut informer des informations MIB défectueuses ou ignorées

Une fois le traitement terminé, les nouveaux fichiers compilés ont été créés dans : ~/.pysnmp/mibs/

Mais avant de (sa?)voir comment utiliser les fichiers MIB nouvellement créés, voyons comment utiliser pysnmp dans le contexte de SNMPv3. Je m’attarderais très particulièrement sur la manière de l’utiliser avec l’authentification forte.

Coding

Appelons l’outil :

from pprint import PrettyPrinter
from pysnmp.hlapi import *
from pysnmp.smi.view import MibViewController

pp = PrettyPrinter(indent=4)

Puis paramétrons les variables nécessaires pour l’authentification forte, à savoir :

host = "localhost"
user = "uenc"
authkey = "zx4pyrfyeu5x5c3kxqirhtsxksbmawju"
privkey = "XHVBzYUpP8dKns75BaSwq6t7SUgF6oMz"

j’ai repris celles de l’exemple, dans l’article sur l’outil natif à OpenBSD, snmp , ni plus ni moins.

SNMP Engine, MIB View Controller

Une des premières choses à déclarer est le Contrôleur de Vue MIB, qui nécessite la création d’un moteur SNMP :

# create SNMP Engine and MIB view Controller
se = SnmpEngine()
mvc = se.getUserContext('mibViewController')
if not mvc:
   mvc = MibViewController(se.getMibBuilder())

Et, maintenant, nous allons voir comment appeler les MIB d’OpenBSD !

OID + MIB

# get Object Identity and Type
oi = ObjectIdentity('iso.org.dod.internet.private.enterprises.openBSD.memMIBObjects')

oi.addMibSource('~/.pysnmp/mibs/')

oi.loadMibs('OPENBSD-BASE-MIB')
oi.loadMibs('OPENBSD-CARP-MIB')
oi.loadMibs('OPENBSD-MEM-MIB')
oi.loadMibs('OPENBSD-PF-MIB')
oi.loadMibs('OPENBSD-RELAYD-MIB')
oi.loadMibs('OPENBSD-SENSORS-MIB')
oi.loadMibs('OPENBSD-SNMPD-CONF')

oi.resolveWithMib(mvc)
  • ObjectIdenttity() : en premier, nous construisons un objet identifiant, selon un OID précis que nous recherchons - ici le nombre d’interfaces vues par la MIB PF d’OpenBSD
  • addMibSource() : référence le chemin où ont été créé les fichiers MIB précédemment
  • loadMibs() : pour appeler chacun des fichiers MIB créés précédemment
    • pour info, selon l’OID recherché, il n’est pas forcément nécessaire de toutes les charger -
  • resolvedWithMib() : nous permet d’appliquer le Contrôleur de Vue MIB sur l’objet

Continuons avec la gestion des données utilisateurs nécessaires à l’identification :

USM User Data

uud = UsmUserData(user, authKey=authkey, privKey=privkey,
            authProtocol=usmHMAC384SHA512AuthProtocol,
            privProtocol=usmAesCfb128Protocol)

Pour information, les différentes valeurs du protocole de chiffrement d’authentification sont :

  • usmNoAuthProtocol pour aucun protocol
  • usmHMACMD5AuthProtocol pour le chiffrement MD5
  • usmHMACSHAAuthProtocol pour SHA
  • usmHMAC128SHA224AuthProtocol pour SHA-224
  • usmHMAC192SHA256AuthProtocol pour SHA-256
  • usmHMAC256SHA384AuthProtocol pour SHA-384
  • usmHMAC384SHA512AuthProtocol pour SHA-512

Concernant le chiffrement du protocole de confidentialité, ces valeurs sont :

  • usmNoPrivProtocol si aucun
  • usmDESPrivProtocol pour DES
  • usmAesCfb128Protocol pour AES

(Pour information, il en existe d’autres, mais ce sont surtout des “drafts”, du moins pour l’instant !)

Générateur

Nous avons besoin de construire le générateur de la commande get :

gc = getCmd(se, uud, UdpTransportTarget((host, 161)), ContextData(),
    ObjectType(oi))

Retourner le résultat

# return results
errorIndication, errorStatus, errorIndex, varBinds = next(gc)

# Display informations
if errorIndication:
    print(str(errorIndication))

elif errorStatus:
    print('%s at %s' % (str(errorStatus.prettyPrint()),
        errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))

else:
    for varBind in varBinds:

        oid = varBind[0]
        value = varBind[1]

        print(oid)
        print(value)

ne pas s’inquiéter du temps que mets la requête à s’afficher ; cela est dû au chiffrement des informations

L’exécution nous retourne ceci :

1.3.6.1.4.1.30155.5

Fin

Pour finir, nous venons de voir que discuter avec l’outil pysnmp sur SNMPv3 avec authentification forte EST possible.

Le plus délicat est de récupérer les informations dans les MIB. Trés vite, vous allez avoir à buter sur des erreurs incompréhensibles, et difficiles à résoudre. Et, ça, ça le don de m’énerver ! (enfin presque…)

Remerciements

  • J’ai beaucoup appris grâce à cet article, trouvé sur le site Makina Corpus.