Atenção

Blog em construção... Se tiver sugestões, serão bem vindas !!!

segunda-feira, 3 de junho de 2013

Instalando e configurando SNMP no Linux

Fonte: http://www.tocadoelfo.com.br/2011/04/instalando-e-configurando-snmp-no-linux.html

Eu não sei quanto a vocês, mas desde que conheci a ferramenta Nagios, para monitoramento de rede, eu passei a dar mais valor nessa coisa de gerenciamento ativo de redes. Não porque eu tivesse a intenção de aplicar isso em lugar nenhum, mas é que a possibilidade de saber o estado de cada máquina (e cada switch/roteador/servidor) da rede me fez querer conhecer mais dessa ferramenta. E tudo acaba passando pelo protocolo SNMP, já que é ele o protocolo que é utilizado para fazer gerência de redes e é implementado por praticamente todos os equipamentos de rede que possuam um mínimo de "inteligência".

Então, estou aqui postando este tutorial sobre SNMP, ensinando como configurar e usar o mesmo para obter estatísticas da sua rede. Aproveitem!


Um pouco de Teoria sobre SNMP


Então, como falei a pouco, o SNMP (do inglês Simple Network Management Protocol - Protocolo Simples de Gerência de Rede) é um protocolo da camada de aplicação para gerência de redes, que roda em cima do protocolo UDP, e que facilita a troca de informações entre dispositivos da rede.


Ao contrário de outros sistemas de gerenciamento, o SNMP funciona como cliente-servidor invertido. Isso significa que cada host monitorado possui seu próprio servidor SNMP, que roda na porta 161, e o software de gerência é nada mais do que um cliente que se conecta em cada um dos hosts e faz as operações de GET e SET definidas pelo protocolo. Somente no modo TRAP que a operação é diferente, pois esta operação é disparada sempre que algum evento programado no host é alcançado (host desconecta/conecta, processamento/memória passa de determinado nível) e então ele envia uma mensagem para o software de gerência, que então se encarregará de fazer o devido processamento da mensagem...





Por conta dessa estrutura, não se considera o SNMP como sendo uma arquitetura cliente/servidor mas sim uma arquitetura peer-to-peer, pois os hosts também podem trocar informações entre si, como informações de alteração de rotas, ou mesmo latência de canais, no caso de roteadores. É dado o nome de gerente para a estação de gerenciamento e de agente para a aplicação que roda no dispositivo de rede.


Versões do SNMP


O SNMP possui atualmente três versões, cada uma com suas características.


SNMPv1
: Primeira versão do protocolo, lançado em 1988, e que implementa os principais comandos do protocolo: GetRequest, SetRequest, GetResponse e GetNextRequest. A segurança é implementada usando o conceito de string comunitária, ou seja, uma string que era compartilhada com todos que necessitassem de obter informações do sistema.

SNMPv2
: Segunda versão do protocolo. Trouxe inovações nas áreas de performance, segurança e confidencialidade e comunicações agente-agente. A diferença aqui é que além de poder usar a já conhecida string comunitária, era possível definir usuários e criadas visões específicas da árvore, de forma que as ações de usuário pudessem ser melhor controladas, com uma granularidade menor. No entanto, essa versão com usuários não foi bem aceita, e lançaram então a SNMPv2c, que nada mais é do que a SNMPv2 sem o recurso de controle de usuários, mas com todos os outros recursos da versão.

SNMPv3
: A terceira versão trouxe várias mudanças na forma como as coisas são feitas internamente, apesar de ter mantido o PDU praticamente idêntico ao das versões anteriores. O objetivo disso foi permitir que o protocolo pudesse ser estendido sem que houvesse a necessidade de se modificar o código existente, através do uso de módulos de funcionalidades. Aqui finalmente o suporte a usuários foi estabelecido como padrão e ainda foi adicionado o suporte a criptografia dos dados, feito através de cifras de HASH e de criptografia simétrica por chave compartilhada.

Estruturação dos dados no protocolo SNMP


A maioria dos roteadores e servidores mantém estatísticas operacionais em identificadores de objetos (OIDs) que você pode facilmente recuperar via SNMP. Para facilitar o acesso à essas OIDs, os equipamentos provêm uma base de informações chamada MIB (Management Information Base), que identifica as OIDs contidas no equipamento. As OIDs são estruturadas sob a forma de árvores, o que permite a estruturação dos dados de forma hierárquica e seu acesso via uma série de números que identificam cada ramo da árvore. E como a identificação de cada ramo é padronizada, o acesso a um determinado ramo pode ser feito diretamente através da OID ou simplificada, através de apelidos que tornam mais "humana" a visualização da estrutura.



Instalando ferramentas SNMP no Linux


Bom, chega de falar de teoria. Vamos primeiramente instalar as ferramentas para suportar SNMP no Linux. Aqui vamos demonstrar como fazer em uma distribuição Ubuntu Server.


Primeiramente vamos instalar o agente e ferramentas de gerenciamento para o protocolo SNMP, com o seguinte comando:

$ sudo apt-get install snmp snmpd

Depois de instalado, é necessário também instalar várias MIBs que o agente SNMP irá precisar. Para isso use o comando:
$ sudo apt-get install snmp-mibs-downloader

Ele vai instalar um programa que irá, em seguida, baixar todas as MIBs que o sistema precisará para funcionar corretamente. São muitas, e dependendo da sua conexão, pode demorar.

Depois de instaladas as MIBs, você deve reiniciar o serviço do SNMP para que as novas entradas sejam processadas.


Liberando o acesso externo


Dependendo da forma como foi instalado o SNMP, pode ser necessária a alteração de uma entrada para fazer com que o serviço receba requisições externas. Para isso, você vai abrir o arquivo /etc/default/snmpd e procurar pela linha a seguir:

SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -g snmp -I -smux -p /var/run/snmpd.pid 127.0.0.1'

Para permitir que o serviço receba requisições de todas as interfaces, basta apagar o ip de loopback contido na linha. Ela ficará da seguinte forma:
SNMPDOPTS='-Lsd -Lf /dev/null -u snmp -g snmp -I -smux -p /var/run/snmpd.pid'

Reinicie o serviço com o comando sudo service snmpd restart e você poderá verificar se o serviço está recebendo conexões com o seguinte comando:
$ netstat -a | grep -i snmp

Caso esteja tudo funcionando perfeitamente, você verá a seguinte saída:
udp 0 0 localhost:snmp *:*

Configurando o SNMP em um servidor Linux


Agora que criamos nosso agente SNMP, vamos tratar de fazer algumas configurações. O arquivo
/etc/snmp/snmpd.conf é bastante explicativo em suas opções, mas nós vamos aqui fazer um arquivo novo, do zero, com as nossas configurações personalizadas.

Então, primeiramente, vamos fazer um backup do arquivo original e criar um arquivo vazio, que usaremos nesse post:

# cd /etc/snmp/
# mv snmpd.conf snmpd.conf.old
# touch snmpd.conf
# chmod 600 snmpd.conf

Agora, abra o arquivo em um editor qualquer para adicionar nossa primeira Community String:
rocommunity publico

Salve o arquivo e reinicie o serviço com o comando service snmpd restart.

Para testar, podemos rodar o comando snmpwalk, que percorrerá toda a MIB, mostrando as OIDs encontradas:

snmpwalk -c publico -v 1 [ip.do.servidor]

Ao executar este comando, você verá uma quantidade enorme de informação relacionada ao servidor. Na maioria dos casos, você não vai querer que todas estas informações estejam disponíveis para todos os usuários. Em vista disso, vamos começar a tratar um pouco mais sobre segurança.

Segurança Básica com SNMP


A maioria dos dispositivos que suportam SNMP não encriptam a string comunitária. Isso abre um leque de possibilidades de acesso de qualquer máquina que possa alcançar o servidor via rede. Informações contidas nas MIBs dão bastantes detalhes da estrutura interna da rede, do funcionamento do servidor ou equipamento que está rodando o agente. Então, por questões de segurança, devemos limitar o acesso a essa informação.


O arquivo
snmpd.conf possui vários dispositivos de segurança para permitir que somente conexões confiáveis possam fazer requisições ao agente. Estes comandos são:

com2sec
- define quais redes podem fazer requisições e seta a string comunitária correspondente;
group
- define o protocolo que será usado para cada rede criada anteriormente;
view
- define quais MIBs estarão visíveis para
access
- define quais as formas de acesso às mibs, permitindo somente a leitura ou a escrita de informações, de acordo com o grupo.

Como exemplo, olhe o seguinte código:

## sec.name source community
## ======== ====== =========
com2sec local localhost privado
com2sec rede1 172.16.0.0/24 rede1
com2sec rede2 192.168.0.0/24 redeadm

## Access.group.name sec.model sec.name

## ================= ========= ========
group grupo1 v1 local
group grupo1 v1 rede1
group grupo2 v2c rede2

## MIB.view.name incl/excl MIB.subtree

## ============== ========= ===========
view todas-mibs included .1.3.6.1.2.1

## MIB

## group.name context sec.model sec.level prefix read write notif
## ========== ======= ========= ========= ====== ==== ===== =====
access grupo1 "" v1 noauth exact todas-mibs none none
access grupo2 "" v2c noauth exact todas-mibs todas-mibs none

Neste arquivo, estamos definindo o seguinte:
A máquina local usará a string comunitária privado, está ligado ao grupo 1 que permite acessar as mibs definidas na view todas-mibs com o protocolo SNMPv1 e não permite escrita de nenhum dado;
A rede 172.16.0.0/24, de nome rede1 usará a string comunitária rede1, está também ligada ao grupo 1 com as mesmas configurações acima;
A rede 192.168.0.0/24, de nome rede2 usará a string redeadm, está ligada ao grupo 2, que usa o protocolo SNMPv2c e que pode ler e escrever em todas as MIBs relacionada na view todas-mibs.

Este é o mecanismo de segurança existente para a versão 2c do protocolo SNMP.


SNMP na versão 3


A versão 3 do protocolo SNMP é uma alternativa mais segura às versões anteriores do protocolo, na medida que este permite o uso de encriptação de dados baseado em usuário / senha criados no arquivo
snmpd.conf, para autenticação.

Para criarmos um usuário, vamos usar o comando
net-snmp-config:
net-snmp-config --create-snmpv3-user -ro -a MD5 -A suasenha usuariov3 -V todas-mibs

Aqui definimos um usuário que possui somente permissões de leitura chamado "usuariov3", que utiliza a senha "suasenha" e definimos para o usuário qual view ele deverá usar.

Atente para a saída do comando:

adding the following line to /var/lib/snmp/snmpd.conf:
createUser usuariov3 MD5 "suasenha" DES
adding the following line to /usr/share/snmp/snmpd.conf:
rouser usuariov3

As informações de usuário/senha estão sendo salvas no arquivo /var/lib/snmp/snmpd.conf enquanto o tipo do usuário é salvo no arquivo /usr/share/snmp/snmpd.conf. Neste caso, criamos um usuário e senha comuns, e o tráfego de dados para este não é encriptado. Para criar um usuário que trafegue dados de forma encriptada, o comando é um pouco maior:
# net-snmp-config --create-snmpv3-user -ro -a MD5 -A suasenha -x DES -X chaveprivada usuariov3 -V todas-mibs

Aqui agora definimos o usuário "usuariov3crip" com a senha "suasenha", só que adicionalmente à senha, adicionamos uma chave privada, "chaveprivada", que deve ser utilizada para descriptografar o tráfego entre o agente e o monitor, quando utilizar este usuário.

Para executar uma consulta com o primeiro usuário, você pode usar a seguinte sintaxe:

snmpwalk -v 3 -u usuariov3 -l authNoPriv -a MD5 -A suasenha [ip.do.servidor]

Para executar uma consulta com o segundo usuário, que encripta os dados transmitidos, você usa a sintaxe:
snmpwalk -v 3 -u usuariov3 -l authPriv -a MD5 -A suasenha -x DES -X chaveprivada [ip.do.servidor]

Finalizando a configuração de segurança


Bem, até aqui nós criamos uma política de strings comunitárias para a versão 1 e 2c do SNMP, e criamos um usuário para a versão 3. No entanto, na versão 3 não definimos nenhuma forma de limitar a visão do usuário às MIBS.


Para isso, basta configurar uma access para usar o protocolo na versão 3 e solicitar o uso de autenticação e/ou criptografia. O nosso arquivo anterior ficará da seguinte forma:

## sec.name source community
## ======== ====== =========
com2sec local localhost privado
com2sec rede1 172.16.0.0/24 rede1
com2sec rede2 192.168.0.0/24 redeadm

## Access.group.name sec.model sec.name

## ================= ========= ========
group grupo1 v3 local
group grupo1 v3 rede1
group grupo2 v3 rede2

## MIB.view.name incl/excl MIB.subtree

## ============== ========= ===========
view todas-mibs included .1.3.6.1.2.1

## MIB

## group.name context sec.model sec.level prefix read write notif
## ========== ======= ========= ========= ====== ==== ===== =====
access grupo1 "" v3 auth exact todas-mibs none none
access grupo2 "" v3 priv exact todas-mibs todas-mibs none

Finalizando


Aqui demonstramos como criar um servidor simples usando SNMP. Espero ter ajudado um pouco com este post. Só lembrando que no arquivo
/etc/snmp/snmpd.conf original, você encontra mais informações sobre como configurar de outras maneiras o agente.

Monitorando um Access Point DD-WRT remotamente com tcpdump, netcat e Wireshark

Fonte: www.tocadoelfo.com.br/2012/07/monitorand-um-access-point-dd-wrt.html


Há alguns dias venho efetuando uma série de testes em meu access point no sentido de controlar um pouco o tráfego de saída. Eu tenho um AP com o firmware DD-WRT instalado e eu criei uma série de regras usando o "tc", ferramenta do pacote netfilter do kernel linux usada para fazer trafic shaping e gerenciamento de banda. O cenário é o seguinte:


  1. Todo o tráfego de saída por uma interface para um determinado IP não irá bloquear o resto do do tráfego.
  2. Algumas portas e protocolos terão prioridades diferenciadas (SSH, torrent).

No entanto, as regras que eu coloquei vinham falhando frequentemente. Era como se simplesmente não houvesse controle da banda. Foi então que eu pensei em procurar uma forma de monitorar o tráfego passante pelo AP e usar o Wireshark para contabilizar se houve diferença nas velocidades.

Mas, espere aí! Não têm Wireshark para o DD-WRT! Por motivos óbvios ele não caberia nem nos sonhos mais profundos de um psicopata. Claro, tenho o Wireshark instalado na minha máquina virtual em ksa, mas como poderia usá-lo para monitorar uma interface de rede em um dispositivo remoto?


Wireshark, Tcpdump e arquivos PCAP

Googleando um pouco (e fuçando na interface de captura) eu descobri que o Wireshark abre arquivos do tipo PCAP. Esses arquivos nada mais são do que o fluxo de dados de uma interface (ou de todas) salvo em um arquivo, para posterior processamento (eu usei isso no post sobre criptografia de redes sem fio).

Ok, eu ainda tinha um problema. Como gerar esse arquivo PCAP à partir do meu Access Point para carregar depois no Wireshark? Me lembrei na hora do tcpdump. O tcpdump têm uma opção de capturar o stream de uma interface (ou de todas) e salvar em um arquivo. Até aí tudo bem. Fui verificar se o DD-WRT possuía a ferramenta, mas não a encontrei. A solução foi instalar a mesma (a partir do post Installing TCPDump on DD-WRT WRT54GL) e gerar o arquivo.

Mas peraí, eu tenho outro problema! Não há espaço suficiente no AP para armazenar o arquivo! Nessa hora, quase que instantaneamente veio à minha cabeça a idéia de usar o NetCat pra transmitir os dados do tcpdump para o computador.

A solução era simples:

  1. No Computador, executar o netcat em modo servidor e direcionando sua saída em arquivo;
  2. No AP, executar o tcpdump com os parâmetros de captura básicos e enviar sua saída para o netcat rodando em modo cliente, conectado ao servidor no computador;
  3. No Wireshark, carregar o arquivo e quantificar o percentual de pacotes passantes para os protocolos com prioridades especificadas;

Descobrir como enviar o dump para a saída padrão foi fácil, depois de 10 minutos de man eu encontrei a opção -w -, que diz para o tcpdump salvar o fluxo RAW na saída padrão (que estará ligada via pipe com o netcat). No final, o comando inteiro ficou assim:

# tcpdump -i any -s 0 -U -n -w - | nc 172.16.0.117 9999

Explicando:

  1. O parâmetro "-i any" diz para capturar os pacotes de todas as interfaces (mas sem fazer modo promíscuo);
  2. O parâmetro "-s" diz quantos bytes do pacote devem ser salvos (0 indica o pacote inteiro);
  3. O parâmetro "-U" diz para o tcpdump não esperar o buffer de saída encher antes de enviar para o pipe (flush a cada pacote escrito);
  4. O parâmetro "-n" impede que o tcpdump faça a conversão dos endereços ip e de porta para seus nomes;
  5. O parâmetro "-w -" diz que o dump é para ser salvo em um arquivo, no caso, o descritor usado é o da saída padrão.

Até aqui tudo bem. Criei o servidor no Computador, iniciei a captura no AP, mas logo que os pacotes começaram a chegar, notei uma anomalia no tráfego. Haviam MUITOS pacotes vindo do AP em direção ao Computador. Nem precisei pensar muito pra perceber que o próprio processo do NetCat estava gerando seus próprios pacotes de rede, que eram capturados pelo tcpdump, que os enviava pelo netcat, que gerava mais pacotes e ... Você pegou né? Recursão. E essa recursão chegou a um ponto que eu precisei reiniciar o AP pois até mesmo a sessão SSH havia congelado. A solução era simples: excluir a comunicação entre as duas máquinas. Assim, o comando cresceu um pouco:

# tcpdump -i any -s 0 -U -n not host 172.16.0.117 -w - | nc 172.16.0.117 9999

Ok, logo que isso foi feito, o tráfego de pacotes se normalizou mas ... Outra anomalia. O tráfego da sessão SSH e do cliente de Torrent da minha máquina não estavam sendo monitorados. Com um pouco mais de inspeção, percebi que nenhum tráfego estava. Logo, vi que precisaria filtrar melhor esses dados, pois a minha máquina era a máquina de teste. Então, o comando mudou novamente para:

# tcpdump -i any -s 0 -U -n not dst port 9999 and not src port 9999 -w - | nc 172.16.0.117 9999

Com essa regra, somente os pacotes com origem ou destino na porta 9999 serão bloqueados, assim todo o resto do tráfego será capturado.

Configurações Finais

Depois disso, sobra só configurar o Computador. Eu poderia usar um arquivo comum e ficar atualizando no Wireshark que teria o efeito desejado. Mas, é possível fazer isso de forma que o mesmo possa capturar os pacotes de acordo com que eles vão chegando. Para isso, é só criar um arquivo fifo, direcionar a saída do netcat para esse arquivo recém criado e mapear nas opções do Wireshark o path desse arquivo. Esse mapeamento pode ser feito tanto por comando no terminal quanto pelas opções do ambiente gráfico.

Claro que não é nessa ordem que se faz as coisas. Pra funcionar direito, você precisa fazer assim:

Criar o arquivo fifo;

$ rm captura
$ mkfifo captura

Configurar o Wireshark para capturar os pacotes do fifo;

$ wireshark -k -i ./captura &

Criar o servidor netcat e apontar para o arquivo fifo;

$ nc -l -p 9999 > captura

Carregar o tcpdump escrevendo na saída padrão e capturando com o netcat conectado ao servidor criado anteriormente;

# tcpdump -i any -s 0 -U -n not dst port 9999 and not src port 9999 -w - | nc 172.16.0.117 9999

Ser feliz com sua captura remota e começar a analisar o tráfego.

Conclusão.

Essa pode não ser a maneira mais prática de se testar as regras criadas no tc, mas foi a solução mais funcional que encontrei até agora. Ela resolveu uma parte do problema, que foi o de verificar a quantidade de pacotes passantes. Claro que eu não obtive todas as informações que eu precisava mas depois eu descobri a ferramenta iptraf que me dava um relatório bem mais preciso das estatísticas de rede. Agora, só me resta descobrir uma forma de trabalhar com essa estrutura e com o iptraf, já que o iptraf é grande demais para colocar dentro do AP com o DD-WRT.

Fontes:

http://wiki.wireshark.org/CaptureSetup/Pipes
http://blog.notreally.org/2007/01/24/how-to-monitor-packets-from-a-remote-interface/