A GEM netsnmp fornece uma implementação nativa do Ruby do protocolo SNMP (V1/2C ABD V3).
Adicione esta linha ao GemFile do seu aplicativo:
gem 'netsnmp'E depois execute:
$ bundle
Ou instale você mesmo como:
$ gem install netsnmp
Esta jóia fornece:
Se você procurar gemas SNMP na Ruby Toolbox, encontrará um monte. Você pode perguntar: por que não usar apenas um deles?
A maioria deles implementa apenas V1 e V2; portanto, se o seu requisito é usar o V3, você ficará com apenas 2 opções: Net-SNMP (não forçado desde 2013) e seu acompanhamento NET-SNMP2, que começou como um garfo para corrigir alguns bugs deixados sem assistência. Ambas as bibliotecas embrulham a biblioteca C NetSNMP usando o FFI, o que as deixa vulneráveis aos seguintes bugs (experientes nas duas bibliotecas):
Todos esses problemas são resolvidos aqui.
Você pode usar o contêiner do docker fornecido sob especificação/suporte para testar esses exemplos (a porta usada nos exemplos deve ser a porta externa do Docker mapeada para a porta 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 . closeOs exemplos SNMP V2/V1 serão semelhantes (cuidado com as diferenças nos atributos de inicialização).
Todos os exemplos anteriores foram feitos especificando tipos primitivos, ou seja, a menos que especificado de outra forma, ele tentará converter um tipo "primitivo" para um tipo primitivo ASN.1 e vice-versa:
Isso significa que, se você passar value: 43 para a chamada #set , ele criará um Varbind com um inteiro ASN.1. Se você emitir um #get e a resposta contém um número inteiro ASN.1, ele retornará um número inteiro.
No entanto, o SNMP define os tipos ASN.1 específicos para aplicativos, para os quais há suporte, embora limitado. Atualmente, há suporte para endereços IP e horários.
Se você criar um objeto IPAddr ( ipaddr da biblioteca padrão ruby) e passar para a chamada #set , ele mapeará para o código específico do conteúdo do SNMP. Se a resposta de uma chamada #get contiver um endereço IP, ele mapeará para um objeto IPAddr .
O tipo NETSNMP::Timeticks é interno a esta biblioteca, mas é um tipo Numeric rubi. Você é seguro usá -lo "como numérico", ou seja, executar cálculos.
Os tipos Counter32 e Counter64 serão mapeados para números inteiros simples.
Você pode encontrar exemplos de uso aqui. Se você precisar de suporte para um tipo ausente, você terá as seguintes opções:
:type chamadas #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 carregará os MIBs padrão de diretórios conhecidos ou anunciados (via MIBDIRS ) (desde que sejam instalados no sistema). Estes serão usados para a conversão OID.
Às vezes, você precisa carregar mais, seus próprios MIBs; nesse caso, você pode usar a seguinte 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" )Você pode instalar MIBs SNMP comuns usando seu gerenciador de pacotes:
# using apt-get
> apt-get install snmp-mibs-downloader
# using apk
> apk --update add net-snmp-libs
Em Ruby, você geralmente é aconselhado a não compartilhar objetos de IO nos threads. O mesmo princípio se aplica aqui ao NETSNMP::Client : desde que você o use em um thread de execução, ele deve se comportar com segurança. Então, algo assim seria possível:
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 ) O IO do Event também é suportado, pois você pode passar um objeto :proxy como um canal de comunicação já aberto ao cliente. Muito importante: você deve cuidar do ciclo de vida, pois o cliente não se conectará e não fechará o objeto, não assumirá o controle sobre ele.
Ao passar um objeto de proxy, você pode omitir o parâmetro :host .
O objeto proxy deverá ser um #send de implementação do tipo pato, que é um método que recebe a carga útil de envio da PDU e devolva a carga útil do PDU receptor.
Aqui está um pequeno exemplo pseudo-código:
# 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 . closePara obter mais informações sobre esse assunto, as especificações testam esse recurso contra o celulóide-IO. Uma EventMachine poderia ser adicionada, se alguém tivesse a gentileza de fornecer uma implementação.
Esta biblioteca possui algumas soluções alternativas para alguns recursos ausentes no idioma Ruby, a saber, a inexistência de uma estrutura de matriz de bytes. O mais próximo que temos é um fluxo de bytes apresentado como uma string com codificação ASCII. Um método foi adicionado à classe String chamada #xor para algumas operações necessárias internamente. Para impedir que os atos de macacos desnecessários foram empregados.
Se #xor se tornar em algum momento o gargalo do seu uso, esta jóia também tem suporte ao Xorcist. Você só precisa adicioná -lo ao seu GemFile (ou instalá -lo no sistema):
# Gemfile
gem 'netsnmp'
# or, in the command line
$ gem install netsnmp
e netsnmp o pegá automaticamente.
Se você usar esta jóia frequentemente com o nível de segurança SNMP V3 e AUTH/PRIV ativado, terá uma sensação engraçada de que tudo pode ser um pouco mais rápido. Bem, isso ocorre basicamente porque o verdadeiro gargalo de desempenho desta jóia é a geração das teclas de autenticação e aprovação usadas para autorização e criptografia. Embora isso seja uma coisa única para cada cliente, seu atraso será perceptível se você estiver executando em> 100 hosts.
Existe um trabalho recomendado, mas isso só é utilizável se você estiver usando o mesmo usuário/authpass/privp em todos os hosts !!! . Use isso com cuidado, então:
$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 Esta biblioteca suporta e é testada contra o Ruby Versions 2.1 ou mais recente, incluindo o Ruby 3. Também suporta e testes contra o Truffleruby.
Todas as codificações/decodificação/criptografia/descriptografia/digestas são feitas usando openssl , que ainda faz parte da biblioteca padrão. Se em algum momento openssl for removido e não é especificamente distribuído, você precisará instalá -lo sozinho. Espero que isso nunca aconteça.
Ele também usa a API openssl ASN.1 para codificar/decodificar Bers, que é conhecido por ser rigoroso, e pode não ser capaz de decodificar PDUs se não estiver em conformidade com o RFC suportado.
Você pode definir o NETSNMP_DEBUG para o nível de depuração do Desface (atualmente, 1 e 2). Os logs serão gravados para Stderr.
Você também pode configurá -lo para um cliente específico:
manager2 = NETSNMP :: Client . new ( debug : $stderr , debug_level : 2 , ... . ) Esta biblioteca usa o RSPEC. As especificações do cliente são testes de "integração", na medida em que nos comunicamos com um simulador de agente SNMP construído por SNMPSIM.
Você pode executar todos os testes digitando:
> bundle exec rake spec
# or
> bundle exec rspec
...
A maneira mais direta de executar os testes é usando a configuração docker-compose (que também é o que é usado no IC). Execute -o contra a versão Ruby que você está segmentando:
> docker-compose -f docker-compose.yml -f docker-compose-ruby-${RUBY_MAJOR_VERSION}.${RUBY_MAJOR_VERSION}.yml run netsnmp
O CI executa os testes contra todas as versões Ruby suportadas. Se as alterações quebrarem uma versão específica do Ruby, certifique -se de cometer alterações apropriadas que abordam o caso Edge ou me avise no quadro de problemas, para que eu possa ajudar.
O simulador SNMP é executado em seu próprio contêiner na configuração docker .
Você pode instalar o pacote (ex: pip install snmpsim ) e executar o servidor localmente e, em seguida, definir a variável de ambiente SNMP_PORT , onde o simulador SNMP está em execução.
O trabalho do CI é:
Existem alguns recursos que esta jóia não suporta. Foi construído apenas para fornecer apenas um cliente (ou gerente, na linguagem SNMP), e os requisitos foram atendidos. No entanto, essas falhas notáveis serão de destaque:
Portanto, se você gosta da jóia, mas prefere implementar esses recursos, ajude -nos enviando um PR e teremos prazer em revisá -la.