netsnmp GEM提供了SNMP协议(V1/2C ABD V3)的Ruby Native实现。
将此行添加到您的应用程序的gemfile:
gem 'netsnmp'然后执行:
$ bundle
或自行安装:
$ gem install netsnmp
该宝石提供:
如果您在Ruby Toolbox中寻找SNMP宝石,则会找到一堆。您可能会问,为什么不使用其中一个呢?
他们中的大多数仅实现V1和V2,因此,如果您的要求是使用V3,则只剩下2个选择:Net-SNMP(自2013年以来不受欢迎)及其后续净SNMP2,该净SNMP2最初是作为叉子来修复一些无人看管的错误。两个库都使用FFI包装C NetSNMP库,这使它们容易受到以下错误的影响(两个库中都有经验):
所有这些问题都在这里解决。
您可以使用规格/支持下提供的Docker容器来测试这些示例(示例中使用的端口应为映射到端口161的Docker外部端口)。
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 . closeSNMP V2/V1示例将是相似的(当心初始化属性的差异)。
所有以前的示例均已指定原始类型,即除非另有说明,否则它将尝试将Ruby“原始”类型转换为ASN.1原始类型,而VICE-RESSA::
这意味着,如果您将value: 43传递给#set调用,它将用ASN.1整数构建一个varbind。如果您发布#get ,并且响应包含一个asn.1整数,则它将返回整数。
但是,SNMP定义了特定于应用程序的ASN.1类型,尽管有限,但有限制。目前,对IP地址和时间表有所支持。
如果创建一个IPAddr对象(Ruby Standard Library ipaddr )并将其传递到#set调用,则将映射到SNMP内容特定的代码。如果#get调用的响应包含一个IP地址,则将映射到IPAddr对象。
NETSNMP::Timeticks类型是该库的内部,但它是Ruby Numeric类型。您可以安全地使用它“作为数字”,即执行计算。
Counter32和Counter64类型将映射到普通整数。
您可以在此处找到使用示例。如果您需要对缺失类型的支持,则有以下选项:
#set呼叫中使用:type参数: # 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将加载已知或广告(通过MIBDIRS )目录的默认MIB(前提是它们安装在系统中)。这些将用于OID转换。
有时,您需要更多地加载自己的MIB,在这种情况下,您可以使用以下API:
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" )您可以使用软件包管理器安装常见的SNMP MIB:
# using apt-get
> apt-get install snmp-mibs-downloader
# using apk
> apk --update add net-snmp-libs
在Ruby中,通常会建议您不要在线程上共享IO对象。相同的原则在此处适用于NETSNMP::Client :只要您在执行线程中使用它,它应该安全。因此,这样的事情是可能的:
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 :proxy对象作为已经打开的通信渠道传递给客户端。非常重要的是:您必须照顾生命周期,因为客户不会连接并且不会关闭对象,因此它不会对其进行控制。
传递代理对象时,您可以省略:host参数。
代理对象必须是实现#send鸭型,这是接收发送PDU有效载荷的方法,并返回接收PDU的有效载荷。
这是一个小伪代码示例:
# 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 . close有关此主题的更多信息,规格测试了该特征针对赛璐oid-io。如果某人足够友好地提供实施,则可以添加事件机器。
该库在红宝石语言中具有一些缺失功能的解决方法,即字节阵列结构的不存在。我们拥有的最接近的是一个字节流,该字节流是带有ASCII编码的字符串。将一种方法添加到名为#xor的字符串类中,以用于内部所需的某些操作。为了防止不必要的猴子点,已经采用了改进。
如果#xor在某个时候成为您使用的瓶颈,则该宝石也支持Xorcist。您只需要将其添加到gemfile中(或在系统中安装):
# Gemfile
gem 'netsnmp'
# or, in the command line
$ gem install netsnmp
netsnmp将自动拾取它。
如果您经常在启用SNMP V3和AUTH/PRIV SECurity Level的情况下使用此宝石,那么您会有一种有趣的感觉,一切都会更快一些。好吧,这基本上是因为该宝石的真正性能瓶颈是用于授权和加密的auth和通过密钥的产生。尽管对于每个客户来说,这是一次性的事情,但如果您在> 100个主机上运行,它的滞后将很明显。
有一个建议的工作,但是只有在所有主机上使用相同的用户/authpass/privass时,才能使用!!! 。然后谨慎使用此操作:
$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 该库支持并针对Ruby版本2.1或更新的Ruby 3(包括Ruby 3)进行了测试。它还支持和测试Truffleruby。
所有编码/解码/加密/解密/摘要均使用openssl完成,这是(仍然)标准库的一部分。如果在某个时候删除了openssl ,而不是专门分发,则必须自己安装。希望这将永远不会发生。
它还使用openssl asn.1 API来编码/解码BER,该bers已知是严格的,如果不符合支持的RFC,则可能无法解码PDU。
您可以将NETSNMP_DEBUG设置为应有的调试级别(当前1和2)。日志将写入stderr。
您还可以为特定客户设置它:
manager2 = NETSNMP :: Client . new ( debug : $stderr , debug_level : 2 , ... . ) 该库使用RSPEC。客户端规格是“集成”测试,因为我们与SNMPSIM构建的SNMP代理模拟器进行了通信。
您可以通过输入来运行所有测试:
> bundle exec rake spec
# or
> bundle exec rspec
...
运行测试的最直接方法是使用docker-compose设置(这也是CI中使用的)。与您要定位的Ruby版本一起运行:
> docker-compose -f docker-compose.yml -f docker-compose-ruby-${RUBY_MAJOR_VERSION}.${RUBY_MAJOR_VERSION}.yml run netsnmp
CI针对所有受支持的Ruby版本进行了测试。如果更改破坏了Ruby的特定版本,请确保您对解决边缘情况的适当更改进行适当的更改,或者在问题板上让我知道,以便我可以提供帮助。
SNMP模拟器在docker设置中的自己的容器中运行。
您可以自己安装软件包(EX: pip install snmpsim )并在本地运行服务器,然后将SNMP_PORT环境变量设置为SNMP Simulator正在运行。
CI的工作是:
该宝石不支持一些功能。它的构建是为了为客户(或经理,以SNMP语言)的实现提供,并且满足了要求。但是,这些著名的错过将脱颖而出:
因此,如果您喜欢宝石,但宁愿实现这些功能,请通过向我们发送PR来提供帮助,我们将很乐意对其进行审查。