Solução para rotear / proxy SNMP Traps (ou Netflow, UDP genérico, etc.) para monitoramento de rede?

15

Estou implementando uma solução de monitoramento de rede para uma rede muito grande (aproximadamente 5000 dispositivos de rede). Gostaríamos que todos os dispositivos em nossa rede enviassem traps SNMP para uma única caixa (tecnicamente provavelmente será um par de caixas HA) e, em seguida, essa caixa passasse os traps SNMP para as caixas de processamento reais. Isso nos permitirá ter várias caixas de back-end lidando com traps e distribuir a carga entre essas caixas de back-end.

Um recurso importante de que precisamos é a capacidade de encaminhar os traps para uma caixa específica, dependendo do endereço de origem do trap. Alguma sugestão para a melhor maneira de lidar com isso?

Entre as coisas que consideramos estão:

  • Usando o snmptrapd para aceitar os traps, e enviá-los para um script personalizado do manipulador de perl escrito, para reescrever o trap e enviá-lo para a caixa de processamento adequada
  • Usando algum tipo de software de balanceamento de carga em execução em uma caixa Linux para lidar com isso (tendo alguma dificuldade em encontrar muitos programas de balanceamento de carga que manipularão UDP)
  • Usando um appliance de balanceamento de carga (F5, etc)
  • Usando IPTables em uma caixa Linux para rotear os traps SNMP com NATing

No momento, implementamos e estamos testando a última solução, com uma caixa Linux com IPTables configurada para receber os traps e, dependendo do endereço de origem do traps, reescreva-o com um destino NAT (DNAT) para que o pacote seja enviado para o servidor apropriado. Por exemplo:

# Range: 10.0.0.0/19       Site: abc01    Destination: foo01
iptables -t nat -A PREROUTING -p udp --dport 162 -s 10.0.0.0/19 -j DNAT --to-destination 10.1.2.3
# Range: 10.0.33.0/21       Site: abc01    Destination: foo01
iptables -t nat -A PREROUTING -p udp --dport 162 -s 10.0.33.0/21 -j DNAT --to-destination 10.1.2.3
# Range: 10.1.0.0/16       Site: xyz01    Destination: bar01
iptables -t nat -A PREROUTING -p udp --dport 162 -s 10.1.0.0/16 -j DNAT --to-destination 10.3.2.1

Isso deve funcionar com excelente eficiência no roteamento básico de armadilhas, mas nos deixa completamente limitados ao que podemos trabalhar e filtrar com o IPTables, por isso estamos preocupados com a flexibilidade para o futuro.

Outro recurso que realmente gostaríamos, mas que não é "obrigatório", é a capacidade de duplicar ou espelhar os pacotes UDP. Ser capaz de pegar uma armadilha de entrada e encaminhá-la para vários destinos seria muito útil.

Alguém já tentou alguma das soluções possíveis acima para balanceamento de carga de traps SNMP (ou Netflow, UDP geral, etc.)? Ou alguém pode pensar em outras alternativas para resolver isso?

Christopher Cashell
fonte

Respostas:

4

Um colega de trabalho acabou de me mostrar um samplicator . Essa ferramenta parece ser uma solução perfeita para o que eu estava procurando. No site da ferramenta:

Este programa simples escuta datagramas UDP em uma porta de rede e envia cópias desses datagramas para um conjunto de destinos. Opcionalmente, ele pode realizar amostragem, ou seja, em vez de encaminhar todos os pacotes, encaminhar apenas 1 em N. Outra opção é que ele pode "falsificar" o endereço de origem IP, de modo que as cópias pareçam vir da fonte original e não do relé . Atualmente, suporta apenas IPv4.

Pode ser usado para distribuir, por exemplo, pacotes Netflow, traps SNMP (mas não informa) ou mensagens Syslog para vários receptores.

Christopher Cashell
fonte
3

Eu mesmo implementaria a solução, pois não sei se você encontrará algo tão específico quanto desejar.

Eu usaria uma linguagem de alto nível como ruby ​​para implementar as regras de equilíbrio e até mesmo o ouvinte de trap. Por exemplo, usar essas bibliotecas parece fácil .

Ouça as armadilhas:

m = SNMP::TrapListener.new(:Port => 1062, :Community => 'public') do |manager|
  manager.on_trap_default { |trap| p trap }
end
m.join

Você deve adicionar a lógica do saldo no on_trap_defaultbloco.

Enviar armadilhas:

Manager.open(:Version => :SNMPv1) do |snmp|
  snmp.trap_v1(
    "enterprises.9",
    "10.1.2.3",
    :enterpriseSpecific,
    42,
    12345,
    [VarBind.new("1.3.6.1.2.3.4", Integer.new(1))])
end

Para construir o daemon, você pode usar a gema ruby do daemon-kit .

Se você simplificar e definir bons objetos, poderá manter o software sem muito esforço.

chmeee
fonte
Agradeço a resposta, mas honestamente, se eu mesmo criar algo, ele será baseado no snmptrapd do Net-SNMP e implementado no Perl, pois o snmptrapd tem suporte interno para aceitar traps e chamar módulos Perl para lidar com eles. Isso o torna mais simples e com melhor suporte (temos uma dúzia de caras que podem lidar com Perl básico e um cara que (quase) brincou com Ruby).
Christopher Cashell
1

Seu principal problema será: como você sabe o IP real do dispositivo do qual você está recebendo os traps?

Se você estiver usando o SNMP v1, poderá tirar o IP do cabeçalho da armadilha. Se você estiver usando traps v2 ou v3, precisará correlacionar o ID do snmpengine ao ip que você buscou anteriormente no dispositivo. Engineid normalmente não é um item de configuração obrigatório para a maioria das implementações SNMP e, portanto, você não pode confiar totalmente nisso sozinho.

O fallback é que você pode usar o IP de origem no cabeçalho do pacote udp. Obviamente, isso falhará, se sua armadilha for roteada através de outro EMS / NMS ou se você tiver um NAT entre o dispositivo e o aplicativo mgmt.

  1. Se você não precisar dar suporte a traps NAT / encaminhados de outros NMS, faça uma cópia do pacote udp e faça a rota com base no ip

  2. Se você precisar dar suporte a isso, precisará analisar a interceptação SNMP e verificar a correspondência de ID do mecanismo para v2 / v3. Na v1, você pode lê-lo no campo de endereço do agente no cabeçalho SNMP.


fonte
0

mais um hack baseado em filtro de rede:

iptables -t nat -A PREROUTING -d 10.0.0.1 -p udp --dport 162 -m random --average 33 -j DNAT --to-destination 10.0.0.2:162
iptables -t nat -A PREROUTING -d 10.0.0.1 -p udp --dport 162 -m random --average 33 -j DNAT --to-destination 10.0.0.3:162
# everything else goes to other consumer
iptables -t nat -A PREROUTING -d 10.0.0.1 -p udp --dport 162 -j DNAT --to-destination 10.0.0.4:162

[suposição - todos os traps são enviados para 10.0.0.1, que os redireciona para 10.0.0.2, 10.0.0.3, 10.0.0.4]

contanto que você tenha traps snmp de um pacote - isso deve espalhar a carga muito bem - nesse caso, em três máquinas. [embora eu não tenha testado].

pQd
fonte
Na verdade, não queremos que a carga se espalhe aleatoriamente. Queremos que todos os traps de uma determinada sub-rede atinjam a mesma máquina, para que possamos correlacionar eventos a sites específicos. No momento, minhas regras do IPTables definem o destino DNAT com base na origem da armadilha.
Christopher Cashell
@ Christopher Cashell - em alternativa à sua solução, você pode usar o módulo netfilter u32 para o servidor de destino 'hash' com base no endereço IP src. por exemplo, pegue os últimos 2 bits do endereço IP src e espalhe a carga para 4 'consumidores' snmp. netfilter.org/documentation/HOWTO/…
pQd
@Christopher Cashell stearns.org/doc/iptables-u32.v0.1.html é um bom tutorial para a partida do u32. alternativamente - veja o projeto "servidor virtual linux" - eles podem fazer o balanceamento de carga para pacotes udp baseados no src / dst ip também.
PQD
0

Eu acho que a resposta de chmeee é o caminho certo a seguir. Livre-se do UDP e do SNMP o mais cedo possível, pois eles são horríveis de gerenciar.

Agora estou construindo um sistema que colocará todos os eventos (incluindo traps) em uma fila JMS e, em seguida, use todas as maravilhas do sistema de mensagens corporativo para fazer o balanceamento de carga e o failover.

Aleksandar Ivanisevic
fonte
Eu acho que você está entendendo mal. . . Não estou tentando criar um sistema de monitoramento completo, apenas um roteador de armadilha SNMP. Temos 5000 dispositivos de rede e centenas de milhares de portas que estamos monitorando aqui. Não tem como eu estar reinventando essa roda. . . apenas tentando melhorar as ferramentas que temos.
9359 Christopher Cashell
Entendi bem, provavelmente você não me entendeu;) O JMS é usado como transporte, porque os corretores modernos têm todos esses recursos agradáveis ​​de failover, persistência e balanceamento. Você pode POSTAR para uma URL, enviar um email, SOAP, o que funcionar. O UDP nunca foi criado para ser confiável ou equilibrável, pois não tem conceito de fluxo de dados ou controle de fluxo. Você será ferrado a longo prazo tentando fazer o UDP fazer o que não foi projetado para fazer.
Aleksandar Ivanisevic
Agradeço a sugestão, mas realmente não tenho absolutamente nenhuma intenção ou interesse em criar meu próprio sistema de monitoramento de rede em nível empresarial. Já existem muitos deles disponíveis, e a implementação de um com o conjunto de recursos e a escalabilidade exigidos exigiria uma equipe de uma dúzia de programadores por 2 a 4 anos. Não é viável ou desejável. Isso me deixa interagindo com os sistemas existentes e me deixa lidando com muito SNMP sobre UDP.
Christopher Cashell
0

Seu principal problema será: como você sabe o IP real do dispositivo do qual você está recebendo os traps?

Para obter o IP do remetente original, você pode tentar corrigir o snmptrapd com este patch - https://sourceforge.net/p/net-snmp/patches/1320/#6afe .

Isso modifica a carga útil, para que os cabeçalhos IP sejam mantidos intactos, para que eles não entrem no seu roteamento e / ou NAT.

Pik Master
fonte