domingo, 24 de setembro de 2017

Descobrindo portas não utilizadas em switches

Contexto


Quando você se depara com um switch lotado de cabos, e vê que precisa comprar um novo, pode se perguntar se todos aqueles pontos realmente estão em uso. A idéia de desenvolver um script para identificar quais portas estão sem uso a mais de um determinado tempo surgiu para resolver esta situação.

O script percorre todos os switches de um determinado grupo do Zabbix, gerando um html para cada um, informando quais portas estão sem uso.

A interação com a base de dados é realizada através da ferramenta PyZabbix, e com os switches é feita através do protocolo SNMP.

Instalação

Em um sistema baseado em Debian:

    apt-get install python-setuptools python-dev build-essential
    easy_install pip
    pip install --upgrade virtualenv
    pip install pyzabbix
    pip install pysnmp-apps
    pip install pysnmp==4.3.0
    yum install python-devel pysnmp-mibs

O script pode ser obtido no github upTimePort.py

Configuração

Os seguintes parâmetros estão no início do arquivo de script upTimePort.py. Configure o usuário do zabbix que irá executar o script. Certifique-se de que o usuário possui direitos para acessar o grupo de equipamentos de switches:

    user = "Admin"

A senha para este usuário:

    secret = "zabbix"

A URL para a Api do Zabbix:

    zapi = ZabbixAPI("http://127.0.0.1/zabbix")

A comunidade SNMP para acessar os switches:

    community = "public"

O ID para o grupo de hosts de switches:

    switchGroupID="8"

O caminho para o script de relatório:

reportScript = "/root/scripts/upTimePort/report.py"

O diretório de saída do relatório:

outputDirectory = "/var/www/html/reports/upTimePort"

Você pode configurar por quanto tempo uma porta deve ficar sem uso para que ela seja apresentada no relatório:

#seconds * 100
target=259200000

Utilização

     ./upTimePort.py

Este script não precisa de parâmetros.


sábado, 9 de setembro de 2017

Utilizando o Zabbix como fonte de nomes para outras ferramentas

Contexto


O Zabbix, dependendo de sua aplicação, pode concentrar diversas informações importantes sobre equipamentos, como por exemplo, seus nomes, localidades, aplicações associadas, áreas de negócio, entre outras. A idéia deste post é apresentar um script para extrair este tipo de informação, e gerar um arquivo de dicionário, que pode ser utilizado na ferramenta logstash.

A interação com a base de dados é realizada através da ferramenta PyZabbix.

Instalação

Em um sistema baseado em Debian:

apt-get install python-setuptools python-dev build-essential
easy_install pip
pip install --upgrade virtualenv
pip install pyzabbix

Configuração

Os seguintes parâmetros estão no início do arquivo de script updateNamesFromInventory.py. Configure o usuário do Zabbix que terá acesso via API. Certifique-se de que o usuário possui direitos suficientes para alterar os hosts:

user = "Admin"

A senha para este usuário:

secret = "zabbix"

A URL para a API do Zabbix:

zapi = ZabbixAPI("http://127.0.0.1/zabbix")

As expressões regulares para seleção dos grupos deve ser padronizada conforme a utilização em seu ambiente.

Utilização

 ./zabbixKibanaDictionaries.py -h
Usage: zabbixKibanaDictionaries.py [options]

Options:
  -h, --help            show this help message and exit
  -t TYPE, --type=TYPE  output type: host, location, trend, environment, team,
                        service or office [default: host]


Exemplo de arquivo de saída

Ao utilizar o tipo de saída de serviço, por exemplo, obtemos a seguinte saída:

"10.24.0.10": CFTV
"10.70.0.50": Mysql
"10.90.0.75": Backup

Exemplo de utilização do dicionário no logstash

filter{
    translate{
        fallback => "desconhecido"
        override => true
        field =>  "[sflow.dstIP]"
        destination => "[sflow.DstService]"
        dictionary_path = "/path/to/dictionary.yaml"
    }
}

Exemplo de utilização no kibana





sexta-feira, 8 de setembro de 2017

Gerando um mapa de calor com a quantidade de usuários por ponto de acesso

Contexto

Uma informação importante para o gerenciamento de redes sem fio, é conhecer quais equipamentos são os mais e os menos utilizados. Uma métrica de utilização importante é a quantidade de usuários por ponto de acesso.

O conhecimento desta informação auxilia na decisão para remanejamento físico de equipamentos e também orienta a necessidade de aquisição de equipamentos adicionais para determinadas localidades.

O ambiente apresentado neste post é composto por uma Controladora Ruckus SmartZone, e aproximadamente 600 pontos de acesso.

Para fornecer a visualização apresentada neste post, os dados foram obtidos através da ferramenta de gerenciamento Zabbix, e apresentados pelo Grafana.

Obtenção dos dados

Optou-se pela obtenção dos dados diretamente a partir da controladora, devido à facilidade de cadastro de apenas um objeto de monitoramento.

Foi elaborado um template para o Zabbix utilizando as informações  do fabricante, encontradas neste documento. O template está disponível no share.zabbix.

Para poder gerar o mapa de calor não apenas pelo nome do ponto de acesso, mas também pela localização e pelo grupo, foi gerada na descoberta de baixo nível um item não normalizado com todas estas informações no nome, relacionando a quantidade de usuários, com a chave abaixo:

discovery[{#SNMPVALUE},.1.3.6.1.4.1.25053.1.4.2.1.1.2.2.1.1,{#GROUP},1.3.6.1.4.1.25053.1.4.2.1.1.2.2.1.2,{#DESCRIPTION},1.3.6.1.4.1.25053.1.4.2.1.1.2.2.1.22,{#NAME},1.3.6.1.4.1.25053.1.4.2.1.1.2.2.1.5]



E a criação do item:



Visualização

Para a visualização foi utilizado o plugin de mapa de calor Savantly para o Grafana. Foi considerado como 80 usuários o máximo da escala para o número de usuários por ponto de acesso.

Segue o JSON para a produção do painel:

{
  "chartId": "chart_9",
  "colors": [
    "rgba(50, 172, 45, 1)",
    "rgba(241, 255, 0, 1)",
    "rgba(245, 54, 54, 1)"
  ],
  "format": "none",
  "height": "600",
  "id": 9,
  "legend": {
    "avg": false,
    "current": true,
    "max": false,
    "min": false,
    "show": true,
    "total": false
  },
  "links": [],
  "mappingType": 1,
  "maxDataPoints": 100,
  "nullPointMode": "connected",
  "seriesOverrides": [],
  "span": 12,
  "targets": [
    {
      "application": {
        "filter": "NN"
      },
      "functions": [
        {
          "def": {
            "category": "Alias",
            "defaultParams": [
              "/(.*)/",
              "$1"
            ],
            "name": "replaceAlias",
            "params": [
              {
                "name": "regexp",
                "type": "string"
              },
              {
                "name": "newAlias",
                "type": "string"
              }
            ]
          },
          "params": [
            "/.*#(.*) Auth Clients/i",
            "$1"
          ],
          "text": "replaceAlias(/.*#(.*) Auth Clients/i, $1)"
        }
      ],
      "group": {
        "filter": "Tipo - Controlador Wifi Ruckus"
      },
      "host": {
        "filter": "/.*/"
      },
      "item": {
        "filter": "/.*/"
      },
      "mode": 0,
      "options": {
        "showDisabledItems": false
      },
      "refId": "A"
    }
  ],
  "thresholds": "0,80",
  "timeFrom": "1h",
  "title": "Mapa de Calor de Quantidade de Usuários por Ponto de Acesso",
  "treeMap": {
    "colorByFunction": "current",
    "debug": false,
    "depth": 0,
    "enableGrouping": true,
    "enableTimeBlocks": false,
    "groups": [
      {
        "key": "server",
        "value": "/^.*./g"
      }
    ],
    "ids": [
      "alias"
    ],
    "mode": "squarify",
    "nodeSizeProperty": "value",
    "sizeByFunction": "current"
  },
  "type": "savantly-heatmap-panel",
  "valueMaps": [
    {
      "op": "=",
      "text": "N/A",
      "value": "null"
    }
  ]
}

Resultado

Os nomes foram alterados para manter a privacidade:





terça-feira, 5 de setembro de 2017

Atualizando o nome do host no Zabbix a partir de um campo do inventário

Contexto

Uma das primeiras dificuldades ao tentar automatizar a implantação do Zabbix, é que ao configurar o auto-discovery, você percebe que o equipamento é cadastrado com seu endereço ip, e não existe uma forma pronta de fazer com que o nome seja populado a partir de algum outro campo. O caminho mais óbvio é a utilização de dados do inventário para tal tarefa.

Tendo este cenário em vista, resolvi desenvolver um script para automatizar esta tarefa. O script pode ser obtido neste repositório

updateNamesFromInventory

Descrição

O script copia o nome que está no inventário para o nome do equipamento. Caso exista uma atualização no inventário, o nome também é atualizado. Para evitar a criação de nomes duplicados, nestes casos é adicionado o endereço de ip antes do nome. Em alguns casos, é desejável que este equipamento fique desabilitado, para evitar que um mesmo equipamento seja monitorado múltiplas vezes através de cada um de seus endereços, como pode ocorrer em roteadores e firewalls. Você pode então, configurar uma lista de grupos para quais os hosts devem ser desabilitados. O comportamento padrão, é manter o equipamento habilitado.

Toda interação com a base do Zabbix é feita através da API PyZabbix

Instalação

Em um sistema baseado em Debian:

apt-get install python-setuptools python-dev build-essential
easy_install pip
pip install --upgrade virtualenv
pip install pyzabbix

Configuração

Os seguintes parâmetros estão no início do arquivo de script updateNamesFromInventory.py. Configure o usuário do Zabbix que terá acesso via API. Certifique-se de que o usuário possui direitos suficientes para alterar os hosts:

user = "Admin"

A senha para este usuário:

secret = "zabbix"

A URL para a API do Zabbix:

zapi = ZabbixAPI("http://127.0.0.1/zabbix")

Os ids dos grupos de hosts nos quais os hosts devem ser desabilitados se o nome for repetido:

disableIfDuplicatedGroups=[8,9]

Utilização

 ./updateNamesFromInventory.py

Este script não possui parâmetros externos.

Para referência de performance, para renomear uma base com aproximadamente 3 mil equipamentos, o script leva pouco mais de um minuto. Ele pode ser executado múltiplas vezes para manter a base atualizada.


domingo, 3 de setembro de 2017

Monitoramento de Redes - Automatizando o descobrimento de redes pelo Zabbix

Contexto

O Zabbix possui uma ótima funcionalidade para a descoberta automática de equipamentos utilizando regras de descoberta. Nesta funcionalidade é necessário cadastrar em quais redes o sistema irá procurar, e quais verificações devem ser feitas em cada rede. Isto funciona muito bem quando você gerencia uma rede com poucos intervalos de endereços IPs, e quando ela sofre poucas alterações.

Mas e se você possui uma rede muito grande, quais são as alternativas?

Se a rede conta com uma ferramenta de gerenciamento de endereços (IPAM - IP address management), como o IPPlan, GLPI-IPAM ou phpIpam por exemplo, estes podem servir como uma boa fonte para realizar este cadastro. A análise de tabelas de roteamento também pode ser uma fonte valiosa de informações para o cadastro.

Mas e se eu precisar cadastrar centenas ou milhares de redes?

A idéia para o desenvolvimento de um script para automaticamente descobrir redes IPs e  cadastrá-las no Zabbix surgiu de uma necessidade que tive para cadastrar muitas centenas de redes, e também mantê-las atualizadas.

ipDiscovery

O script ipDiscovery busca via API no Zabbix todos os equipamentos de um grupo, preferencialmente roteadores e firewalls, e realiza consultas SNMP na variável ipAddrTable rfc1213-mib2.asn1. Estas redes são então cadastradas nas regras de descoberta, também utilizando a API, com base em uma regra previamente cadastrada e definida como template.

Instalando o script

Em sistemas baseados em debian:

apt-get install python-setuptools python-dev build-essential
easy_install pip
pip install --upgrade virtualenv
pip install pyzabbix
pip install ipaddress
pip install pysnmp


Configuração

Os parâmetros abaixo estão no início do arquivo de script ipDiscovery.py. Configure o usuário do Zabbix que irá acessar a API. Certifique-se de que este possui direitos suficientes para acessar os cadastros e também para criar as regras de descoberta:

user = "Admin"

Configure a senha para este usuário:

secret = "zabbix"

A URL para o acesso à API do Zabbix:

zapi = ZabbixAPI("http://127.0.0.1/zabbix")

A comunidade SNMP para acesso aos dispositivos:

community = "public"

O nome do grupo de equipamentos do Zabbix onde deve-se buscar as informações do dispositivo:

routersGroupName="Router"

O nome da regra de descoberta do Zabbix que será utilizado como padrão para a criação de outras novas:

templateDiscoveryRule="TEMPLATE"

Somente incluir redes IP que estejam dentro do intervalo(s) abaixo:

includeIfInRange=["10.0.0.0/8","172.16.0.0/12","192.168.0.0/16"]

Não inclua redes IP que estejam no intervalo especificado abaixo. No caso da rede se encaixar na regra de inclusão e também de exclusão, ela não será incluída:

ignoreIfInRange=["127.0.0.0/8"]

Alguns dispositivos podem possuir centenas de interfaces, então você pode dividi-las em várias regras. Este atributo define o máximo do número de redes em cada regra. Você não deve configurar um número maior que 112, ou pode ser que atinja a restrição do Zabbix do número máximo de caracteres por regra.

maxNetPerRule = 10

Utilização

 ./ipDiscovery.py -h
Usage: ipDiscovery.py [options]

Options:
  -h, --help            show this help message and exit
  -t TYPE, --type=TYPE  output type: html, csv or api [default: html]

./ipDiscovery .py -t html

Isto irá produzir uma tabela em html utilizando o Ajax DataTables, conforme este exemplo.

./ipDiscovery.py -t csv

Isto irá produzir um arquivo csv no seguite padrão:

AdslRouter,1-lo,127.0.0.1/8
AdslRouter,12-ppp0,179.181.19.234/32
AdslRouter,4-br0,192.168.1.1/24

./ipDiscovery.py -t api

Esta opção irá criar as regras de descoberta conforme configurado no script.



Performance

No ambiente no qual realizei os testes foi possível o cadastro de 600 redes ips em menos de 3 minutos.

Seus comentários ou dúvidas são bem vindos!