Le GEM netsnmp fournit une implémentation native Ruby du protocole SNMP (V1 / 2C ABD V3).
Ajoutez cette ligne à Gemfile de votre application:
gem 'netsnmp'Puis exécuter:
$ bundle
Ou installez-le vous-même comme:
$ gem install netsnmp
Ce joyau fournit:
Si vous recherchez des gemmes SNMP dans Ruby Toolbox, vous trouverez un tas. Vous pouvez demander, pourquoi ne pas simplement utiliser l'un d'eux?
La plupart d'entre eux implémentent uniquement V1 et V2, donc si votre exigence est d'utiliser V3, il vous reste avec seulement 2 choix: Net-SNMP (non avancé depuis 2013) et son suivi net-snmp2, qui a commencé comme une fourche pour corriger certains bogues laissés sans surveillance. Les deux bibliothèques enveloppent la bibliothèque C Netsnmp en utilisant FFI, ce qui les rend vulnérables aux bogues suivants (expérimentés dans les deux bibliothèques):
Tous ces problèmes sont résolus ici.
Vous pouvez utiliser le conteneur Docker fourni sous SPEC / Prise en charge pour tester ces exemples (le port utilisé dans les exemples devrait être le port externe Docker mappé au port 161).
require 'netsnmp'
# example you can test against the docker simulator provided. port attribute might be different.
manager = NETSNMP :: Client . new ( host : "localhost" , port : 33445 , username : "simulator" ,
auth_password : "auctoritas" , auth_protocol : :md5 ,
priv_password : "privatus" , priv_protocol : :des ,
context : "a172334d7d97871b72241397f713fa12" )
# SNMP get
manager . get ( oid : "sysName.0" ) #=> 'tt'
# SNMP walk
# sysORDescr
manager . walk ( oid : "sysORDescr" ) . each do | oid_code , value |
# do something with them
puts "for #{ oid_code } : #{ value } "
end
manager . close
# SNMP set
manager2 = NETSNMP :: Client . new ( host : "localhost" , port : 33445 , username : "simulator" ,
auth_password : "auctoritas" , auth_protocol : :md5 ,
priv_password : "privatus" , priv_protocol : :des ,
context : "0886e1397d572377c17c15036a1e6c66" )
# setting to 43, becos yes
# sysUpTimeInstance
manager2 . set ( "1.3.6.1.2.1.1.3.0" , value : 43 )
manager2 . closeLes exemples SNMP V2 / V1 seront similaires (méfiez-vous des différences dans les attributs d'initialisation).
Tous les exemples précédents ont été effectués en spécifiant les types primitifs, c'est-à-dire que sauf indication contraire, il va essayer de convertir un type "primitif" rubis en un type primitif ASN.1, et vice-versa:
Cela signifie que si vous passez value: 43 à l'appel #set , il va construire un varbind avec un entier ASN.1. Si vous émettez un #get et que la réponse contient un entier ASN.1, il va renvoyer un entier.
Cependant, SNMP définit les types ASN.1 spécifiques à l'application, pour lesquels il existe un support, bien que limité. Actuellement, il existe une prise en charge des adresses IP et des horaires.
Si vous créez un objet IPAddr (Ruby Standard Library ipaddr ) et passez-le à l'appel #set , il mappera au code spécifique au contenu SNMP. Si la réponse d'un appel #get contient une adresse IP, elle mappera à un objet IPAddr .
Le type NETSNMP::Timeticks est interne à cette bibliothèque, mais c'est un type Numeric Ruby. Vous êtes en sécurité pour l'utiliser "comme numérique", c'est-à-dire effectuer des calculs.
Les types Counter32 et Counter64 seront les cartographiques à des entiers simples.
Vous pouvez trouver des exemples d'utilisation ici. Si vous avez besoin d'une prise en charge d'un type manquant, vous avez les options suivantes:
:type dans les appels #set : # as a symbol
manager . set ( "somecounteroid" , value : 999999 , type : :counter64 )
# as the SNMP specific type id, if you're familiar with the protocol
manager . set ( "somecounteroid" , value : 999999 , type : 6 ) netsnmp chargera les MIB par défaut des répertoires connus ou annoncés (via MIBDIRS ) (à condition qu'ils soient installés dans le système). Ceux-ci seront utilisés pour la conversion OID.
Parfois, vous devrez charger plus, vos propres MIB, auquel cas vous pouvez utiliser l'API suivante:
require "netsnmp"
NETSNMP :: MIB . load ( "MY-MIB" )
# or, if it's not in any of the known locations
NETSNMP :: MIB . load ( "/path/to/MY-MIB.txt" )Vous pouvez installer des MIB SNMP communs en utilisant votre gestionnaire de packages:
# using apt-get
> apt-get install snmp-mibs-downloader
# using apk
> apk --update add net-snmp-libs
Dans Ruby, vous êtes généralement conseillé pour ne pas partager des objets IO sur les fils. Le même principe s'applique ici à NETSNMP::Client : à condition que vous l'utilisiez dans un fil d'exécution, il devrait se comporter en toute sécurité. Donc, quelque chose comme ça serait possible:
general_options = { auth_protocol : ... .
routers . map do | r |
Thread . start do
NETSNMP :: Client . new ( general_options . merge ( host : r ) ) do | cl |
cli . get ( oid : " 1.6 . 3 ...... .
end
end
end . each ( & :join ) IO a également été pris en charge, en ce que vous pouvez passer un objet :proxy comme un canal de communication déjà ouvert au client. Très important: vous devez prendre soin du cycle de vie, car le client ne se connectera pas et ne fermera pas l'objet, il ne supposera pas de contrôle.
Lors du passage d'un objet proxy, vous pouvez omettre le paramètre :host .
L'objet proxy devra être une implémentation de type canard #send , qui est une méthode recevant la charge utile PDU d'envoi, et retourne la charge utile du PDU récepteur.
Voici un petit exemple de pseudo-code:
# beware, we are inside a warp-speed loop!!!
general_options = { auth_protocol : ... .
proxy = SpecialUDPImplementation . new ( host : router )
NETSNMP :: Client . new ( general_options . merge ( proxy : proxy ) ) do | cl |
# this get call will eventually #send to the proxy...
cli . get ( oid : " 1.6 . 3 ...... .
end
# client isn't usable anymore, but now we must close to proxy
proxy . closePour plus d'informations sur ce sujet, les spécifications testent cette fonctionnalité contre Celluloïd-io. Une machine d'événement pourrait être ajoutée si quelqu'un aurait eu la gentillesse de fournir une implémentation.
Cette bibliothèque a des solutions de contournement à certaines fonctionnalités manquantes dans la langue Ruby, à savoir l'inexistence d'une structure de tableau d'octets. Le plus proche que nous ayons est un flux d'octet présenté comme une chaîne avec un codage ASCII. Une méthode a été ajoutée à la classe de chaîne appelée #xor pour certaines opérations nécessaires en interne. Pour éviter les salons de singes inutiles, des raffinements ont été utilisés.
Si #xor devient à un moment donné le goulot d'étranglement de votre utilisation, ce joyau a également pris en charge Xorcist. Il vous suffit de l'ajouter à votre gemfile (ou de l'installer dans le système):
# Gemfile
gem 'netsnmp'
# or, in the command line
$ gem install netsnmp
et netsnmp le ramassera automatiquement.
Si vous utilisez souvent ce joyau avec SNMP V3 et Auth / PRIVE Sécurité activé, vous aurez ce sentiment drôle que tout pourrait être un peu plus rapide. Eh bien, c'est essentiellement parce que le véritable goulot d'étranglement des performances de ce joyau est la génération des clés AUTH et PASS utilisées pour l'autorisation et le cryptage. Bien que ce soit une chose unique pour chaque client, son décalage sera perceptible si vous utilisez> 100 hôtes.
Il y a une réalisation recommandée, mais cela n'est utilisable que si vous utilisez le même utilisateur / authpass / privpass sur tous les hôtes !!! . Utilisez-le avec soin, alors:
$shared_security_parameters = NETSNMP :: SecurityParameters . new ( security_level : :authpriv , username : "mustermann" ,
auth_protocol : :md5 , priv_protocol : :aes , ... .
# this will eager-load the auth/priv_key
...
# over 9000 routers are running on this event loop!!! this is just one!
NETSNMP :: Client . new ( share_options . merge ( proxy : router_proxy , security_parameters : $shared_security_parameters . dup ) . new do | cl |
cli . get ( oid : .....
end Cette bibliothèque prend en charge et est testée contre Ruby Versions 2.1 ou plus récente, y compris Ruby 3. Il prend également en charge et teste également TrufflerUby.
Tous les codages / décodage / chiffrement / décryptage / digestion sont effectués à l'aide openssl , qui fait (toujours) une partie de la bibliothèque standard. Si à un moment donné openssl est supprimé et n'est pas spécifiquement distribué, vous devrez l'installer vous-même. J'espère que cela n'arrivera jamais.
Il utilise également l'API openssl ASN.1 pour coder / décoder BERS, qui est connue pour être stricte, et peut ne pas être en mesure de décoder PDUS s'il n'est pas conforme au RFC pris en charge.
Vous pouvez soit définir le NETSNMP_DEBUG au niveau de débogage désigné (actuellement, 1 et 2). Les journaux seront écrits à Stderr.
Vous pouvez également le définir pour un client spécifique:
manager2 = NETSNMP :: Client . new ( debug : $stderr , debug_level : 2 , ... . ) Cette bibliothèque utilise RSpec. Les spécifications du client sont des tests "d'intégration", en ce sens que nous communiquons avec un simulateur d'agent SNMP SNMPS SNMPSIM.
Vous pouvez exécuter tous les tests en tapant:
> bundle exec rake spec
# or
> bundle exec rspec
...
Le moyen le plus simple d'exécuter les tests est d'utiliser la configuration docker-compose (qui est également ce qui est utilisé dans l'IC). Exécutez-le contre la version Ruby que vous ciblez:
> docker-compose -f docker-compose.yml -f docker-compose-ruby-${RUBY_MAJOR_VERSION}.${RUBY_MAJOR_VERSION}.yml run netsnmp
Le CI exécute les tests par rapport à toutes les versions Ruby prises en charge. Si les modifications cassent une version spécifique de Ruby, assurez-vous de commettre des modifications appropriées sur le cas Edge, ou faites-le moi savoir dans le conseil des problèmes, afin que je puisse vous aider.
Le simulateur SNMP s'exécute dans son propre conteneur dans la configuration docker .
Vous pouvez installer le package vous-même (ex: pip install snmpsim ) et exécuter le serveur localement, puis définir la variable d'environnement SNMP_PORT , où le simulateur SNMP s'exécute.
Le travail du CI est:
Il existe certaines fonctionnalités que ce joyau ne prend pas en charge. Il a été conçu pour fournir une implémentation client (ou gestionnaire, en langue SNMP) uniquement, et les exigences ont été remplies. Cependant, ces ratés notables se distingueront:
Donc, si vous aimez le gemme, mais que vous préférez ces fonctionnalités implémentées, veuillez aider en nous envoyant un RP et nous le réviserons avec plaisir.