quinta-feira, 14 de abril de 2011

Instalando e configurando SNMP no Linux

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.

Eh isso. Abração pra vcs!

Fontes:
Net-SNMP Tutorial -- snmpd
Configuring SNMPv3 Security Settings
Quick HOWTO : Ch22 : Monitoring Server Performance