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來提供幫助,我們將很樂意對其進行審查。