segunda-feira, 11 de junho de 2018

Installing ELK Stack - Elasticsearch Logstash and Kibana on a Minimal Ubuntu System

This post opens a series about the ELK stack, having a minimal Ubuntu as a base OS.

Ubuntu image can be obtained here https://help.ubuntu.com/community/Installation/MinimalCD

You will want at least 2GB of RAM memory in your machine, although the minimal recomendation is 1GB. When selecting packages, OpenSSH server, depending on your setup, might be the only dependency.

Some packages that might be of use:

apt-get install vim net-tools python-pip

These are required for the installation:

apt-get install gnupg apt-transport-https

Install java 8

apt-get install openjdk-8-jdk

Configure sources

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list

sudo apt-get update && sudo apt-get install logstash elasticsearch kibana

In the file /etc/kibana/kibana.yml update the server.host parameter to the one used in your environment:

server.host: “192.168.1.5”

And finally, to make Elasticsearch and Kibana start automatically at boot:

systemctl enable elasticsearch.service
systemctl enable kibana.service


You will end up with 4GB used in your hard drive, and a functional ELK stack server.



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!


segunda-feira, 21 de setembro de 2015

Solving the "COMXAudio::Decode timeout" error in omxplayer with Raspberry Pi

I have been receiving the error message "COMXAudio::Decode timeout" repeated several times when trying to play large files in omxplayer, often 1080p mkv or mp4 files.

Messages appear like this

 COMXAudio::Decode timeout  
 COMXAudio::Decode timeout  
 COMXAudio::Decode timeout  
 COMXAudio::Decode timeout  

The solution is to allocate more memory to the video processing unit. To do so, you should add the following line in your /boot/config.txt, and reboot your Raspberry Pi.

 gpu_mem=128  

When you apply this solution in a Raspberry Pi 2 model, with 1GB RAM memory, the unit will remain with 860 MB for linux use.

 :~# free -m  
        total    used    free   shared  buffers   cached  
 Mem:      860    757    103     24    250    189  
 -/+ buffers/cache:    316    543  
 Swap:      0     0     0  

See what other options can be configured at config.txt.