Skip to content

RZL Rogério

Um site do Rogér(io)

  • Blog
  • Sobre

Monitorando a expiração de um domínio

Posted on 31 de julho de 2021 - 31 de julho de 2021 by rzlrogerio

Bom, esse é um ponto que muitas empresas deixam passar, pois os serviços de gerenciamento de domínios, como o RegistroBr e outros, enviam notificações por correio eletrônico, porém muitas vezes acabam passando por regras de “lixo eletrônico”, fora o fato que e-mail não é monitoria.

Então esse script é bem simples; ele verifica a data de expiração de um domínio, seja ele mantido no Brasil ou em outros países e usando a mesmo padrão apresentado anteriormente envia um alarme para o Zabbix.

Obs.: vejam que em todos os scripts eu tento manter o mais simples possível, deixando claro quais foram os comandos utilizados.

#!/bin/sh

GRP_ID="107"
GRUPO="dominios_intranet"

TEMPLATE_ID="14909"
NAME_TEMPLATE="TPL-intranet-registro-DOMS"

## Agente de envio
ZBXPRX="zbxtrapper01.intranet"
ZBXSND=$(which zabbix_sender)

# Exportando o proxy
PROXY="techtools-proxy.intranet"
PRX_ID="10334"

LISTA_DOMS="/usr/local/bin/monits/lista-dominios.txt"

DOMS=$(cat $LISTA_DOMS | rev | awk -F'.' '{ print $1"."$2"."$3  }' | rev | sed 's/www.//g' | sort -u)

# 30 dias em segundos
LIMIT="2592000"

fn_send_zabbix()
{
  $ZBXSND -z $ZBXPRX -s $dom-DOM -k status-dom -o "$VALUE"
}

fn_make_host()
{
  JSON_AUTH=`mktemp --suffix=-ZABBIX-CERT-AUTH`
  JSON_ITEM=`mktemp --suffix=-ZABBIX-CERT-ITEM`

  # Endpoint do Zabbix
  ZABBIX_API="http://zabbix.intranet/zabbix/api_jsonrpc.php"

  # Usuari0 e senha no zabbix e rundeck
  USER="usuario_zabbix"
  PASS="senha"

cat > $JSON_AUTH <<END
{
  "jsonrpc": "2.0",
  "method": "user.login",
  "params": {
    "user": "$USER",
    "password": "$PASS"
  },
  "id": 1,
  "auth": null
}
END

  # Fazendo o post e salvando o cookie
  COOKIE=$(curl -s -i -X POST -H 'Content-Type:application/json' -d@$JSON_AUTH $ZABBIX_API | grep jsonrpc | jq -r .result)

# Agora criamos o item
cat > $JSON_ITEM <<END
{
  "jsonrpc": "2.0",
  "method": "host.create",
  "params": {
    "host": "$dom-DOM",
    "interfaces": [
    {
      "type": 1,
      "main": 1,
      "useip": 1,
      "ip": "127.0.0.1",
      "dns": "$dom-DOM",
      "port": "10050"
    }
    ],
    "groups": [
    {
      "groupid": "$GRP_ID"
    }
    ],
    "templates": [
      {
      "templateid": "$TEMPLATE_ID"
     }
    ]
  },
  "id": 1,
  "auth": "$COOKIE"
  }
END

  # Criando o item
  curl -s -i -H 'Content-Type: application/json-rpc' -d@$JSON_ITEM $ZABBIX_API
  sleep 1

  # como zabbix nao tem criacao com o proxy - update na seq
  WS_UPDATE="http://zabbix.intranet/zabbix-balancer/ws/update-zabbix-proxy.php"

  # Executando o update
  curl -s --data "proxy_hostid=$PRX_ID&host=$dom-DOM" -X POST $WS_UPDATE
  sleep 1
}

fn_get_expire_international()
{
  DOMS=`cat $LISTA_DOMS | grep -v br | rev | awk -F'.' '{ print $1"."$2 }' | rev | sort -u`

  for dom in `echo $DOMS`
  do
    fn_make_host
    DT=`whois $dom | grep expires | awk '{ print $2 }'`
    test -z $DT
    if [ `echo $?` != 0 ]
    then
      EXP=`curl -s https://www.whois.com/whois/$dom | grep -i expire | awk -F'Expires On' '{ print $2  }' | awk -F'</div><div' '{ print $2  }' | cut -f2 -d">"`

      ANO=`echo $EXP | awk -F'-' '{ print $1 }'`
      MES=`echo $EXP | awk -F'-' '{ print $2 }'`
      DIA=`echo $EXP | awk -F'-' '{ print $3 }'`

      EXP="$MES/$DIA/$ANO 00:00:00"
      TIME_EXP=$(date -d "${EXP}" +"%s")
      NOW=`date +%s`

      DIF=`echo "$TIME_EXP - $NOW" | bc -l`
      if [ $DIF -lt $LIMIT ]
      then
        VALUE="Whois.com: O dominio $dom vai expirar em menos de 30 dias ou ja esta expirado - Expiracao em: $DIA/$MES/$ANO"
        fn_send_zabbix
      else
        VALUE="ok"
        fn_send_zabbix
      fi
    else
      VALUE="O dominio $dom nao foi encontrado no Whois.com"
      fn_send_zabbix
    sleep 10
    fi
  done
}

fn_get_expire()
{
  DOMS=`cat $LISTA_DOMS | grep br | rev | awk -F'.' '{ print $1"."$2"."$3 }' | rev | sort -u`

  for dom in `echo $DOMS`
  do
    fn_make_host
    DT=`whois $dom | grep expires | awk '{ print $2 }'`
    test -z $DT
    if [ `echo $?` != 0 ]
    then
      ANO=`echo $DT | cut -c1-4`
      MES=`echo $DT | cut -c5-6`
      DIA=`echo $DT | cut -c7-8`

      EXP="$MES/$DIA/$ANO 00:00:00"
      TIME_EXP=$(date -d "${EXP}" +"%s")
      NOW=`date +%s`

      DIF=`echo "$TIME_EXP - $NOW" | bc -l`
      if [ $DIF -lt $LIMIT ]
        then
          VALUE="RegistroBR: O dominio $dom vai expirar em menos de 30 dias ou ja esta expirado - Expiracao em: $DIA/$MES/$ANO"
          fn_send_zabbix
        else
          VALUE="ok"
          fn_send_zabbix
      fi
    else
      VALUE="O dominio $dom nao foi encontrado no RegistroBR"
      fn_send_zabbix
    sleep 10
    fi
  done
}

fn_gc()
{
  rm -f $JSON_AUTH $JSON_ITEM
}
# main
fn_get_expire

Obs.: O arquivo “/usr/local/bin/monits/lista-dominios.txt” deve ter um domínio por linha, exemplo:

www.google.com
www.microsoft.com.br

É isso ai.

Vamos falar de monitoria de sistemas

Posted on 3 de julho de 2021 - 17 de julho de 2021 by rzlrogerio

Ok, sei que parece uma tema batido, antigo, que todos já sabem, mas ainda temos muitas empresas que estão no mercardo sem uma visão completa (parcial) do seu ambiente, sistemas e componentes e que ainda sofrem e somente são notificadas de problemas quando um usuário reclama diretamente ou pior ainda, nos tempos atuais nas redes sociais.

Existem diversas ferramentas de mercado, pagas com suporte com diversos recursos e muitas de código aberto sem custo de aquisição, mas que requerem algum trabalho de administração e customização, as pagas também tem e muitas vezes pagamos por algo que nunca é entregue.

Aqui vamos falar de uma de código aberto que amplamente utilizada, com diversos recursos que facilitam a vida dos administradores de sistemas, o Zabbix.

O que é Zabbix

Segundo o site oficial “Zabbix is professionally developed free and open-source software with no limits or hidden costs“, traduzindo ao pé da letra:

Zabbix é um software livre e de código aberto desenvolvido profissionalmente, sem limites ou custos ocultos

https://www.zabbix.com/features

Concordo, é livre e de código aberto e praticamente não existe limites do que podemos fazer com ele, basta um pouco de criatividade e um pouco de conhecimento do uso de API (Interface de Programação de Aplicativos) para conseguir extrair o melhor dele.

Existem diversos roteiros de instalação e em geral todos seguem a instalação da distribuição, eu só muito fã do Debian e seu padrão com o conjunto de comandos apt, e fortemente eu recomendo o seu uso.

Aqui vamos ter um outro foco, não vamos falar sobre a instalação e vamos ser mais práticos usando recursos que facilitam o dia-a-dia.

Basicamente

o Zabbix é formado por um servidor de banco de dados, um servidor da aplicação e um servidor web e podemos ter todos estes componentes no mesmo servidor instalado, mas um outro componente importante é Zabbix Proxy.

O proxy (Zabbix proxy) é um componente que atua como um recebedor e executor de comandos removendo a carga de executar as tarefas de consulta de estados e recebimento de eventos do servidor principal. Podemos ter proxies em diferentes redes, datacenter, namespaces, etc, ou seja, a definição do escopo é bem livre.

fonte: https://www.zabbix.com/forum/filedata/fetch?id=360921&d=1543849726

O trapper

O Zabbix Trapper é uma monitoração feita recebendo dados enviados ao invés de ir busca-los. (https://www.zabbix.com/documentation/current/pt/manual/config/items/itemtypes/trapper)

Simples, né?

Sim e extremamente barato sobre o custo do processamento e permite uma grande flexibilidade para os administradores e desenvolvedores criarem rotinas para monitorar os seus sistemas e componentes, pois pegamos um resultado esperado, criamos um template com items que receberão os eventos desejados, algo bem flexível e dinâmico.

Nesse site https://www.zabbix.com/documentation/current/pt/manual/config/items/itemtypes/trapper temos um exemplo prático de como preparar um template com um item do tipo trapper.

Aqui temos um pequeno exemplo de como monitorar a expiração de certificados web e notificar a expiração para o Zabbix:

#!/bin/sh

# lista de dominios com certificado

# zabbix
GRP_ID="67"
TEMPLATE_ID="10321"

DOMS=$(cat /usr/local/bin/monits/lista-dominios.txt)

# Variaveis gerais
LIMITDAY_WARN="60"
LIMITDAY_CRIT="30"

## Agente de envio
ZBXPRX="zbxtrapper01.intranet"
ZBXSND=$(which zabbix_sender)
PRX_ID="10334"

# criado o item no zabbix
fn_make_item()
{
  JSON_AUTH=`mktemp --suffix=-ZABBIX-CERT-AUTH`
  JSON_ITEM=`mktemp --suffix=-ZABBIX-CERT-ITEM`

# Endpoint do Zabbix
        ZABBIX_API="http://zabbix.intranet/zabbix/api_jsonrpc.php"

        # Usuari0 e senha no zabbix e rundeck
        USER="svc_monit"
        PASS="a_sua_senha" # recomendo o uso de um vault

cat > $JSON_AUTH <<END
{
    "jsonrpc": "2.0",
    "method": "user.login",
        "params": {
            "user": "$USER",
            "password": "$PASS"
        },
        "id": 1,
        "auth": null
}
END

  # Fazendo o post e salvando o cookie
  COOKIE=$(curl -s -i -X POST -H 'Content-Type:application/json' -d@$JSON_AUTH $ZABBIX_API | grep jsonrpc | jq -r .result)

# Agora criamos o item
cat > $JSON_ITEM <<END
{
    "jsonrpc": "2.0",
    "method": "host.create",
    "params": {
        "host": "$name",
        "interfaces": [
            {
                "type": 1,
                "main": 1,
                "useip": 1,
                "ip": "127.0.0.1",
                "dns": "$name",
                "port": "10050"
            }
        ],
        "groups": [
            {
                "groupid": "$GRP_ID"
            }
        ],
        "templates": [
            {
                "templateid": "$TEMPLATE_ID"
            }
        ]
    },
        "id": 1,
        "auth": "$COOKIE"
}
END

  # Criando o item
  curl -s -i -H 'Content-Type: application/json-rpc' -d@$JSON_ITEM $ZABBIX_API
  sleep 1

  # como zabbix nao tem criacao com o proxy - update na seq
  WS_UPDATE="http://zabbix.intranet/zabbix-balancer/ws/update-zabbix-proxy.php"

  # Executando o update
  curl -s --data "proxy_hostid=$PRX_ID&host=$name" -X POST $WS_UPDATE
  sleep 1
}

fn_send_zabbix()
{
  MSG="$name IP - $endip exp $expiry_days dias - $LEVEL"

  $ZBXSND -z $ZBXPRX -s $name -k validade_cert -o "$MSG"
}

fn_check_cert()
{
  now_epoch=$( date +%s )
  expiry_date=$( echo | openssl s_client -showcerts -servername $name -connect $endip:443 2>/dev/null | openssl x509 -inform pem -noout -enddate | cut -d "=" -f 2 )
  echo -n " $expiry_date"
  expiry_epoch=$( date -d "$expiry_date" +%s )
  expiry_days="$(( ($expiry_epoch - $now_epoch) / (3600 * 24) ))"

  if [ $expiry_days -lt $LIMITDAY_CRIT ]
  then
    LEVEL="CRIT"
    fn_send_zabbix

  elif [ $expiry_days -gt $LIMITDAY_CRIT ] && [ $expiry_days -lt $LIMITDAY_WARN ]
  then
    LEVEL="WARN"
    fn_send_zabbix
  else
    LEVEL="OK"
    fn_send_zabbix
  fi
}

# chamo o for
for name in `echo $DOMS`
do
   endip=$(host $name | grep has | grep -v "IPv6" | tail -n 1 |  awk '{ print $NF }')

    echo "exit" | nc -w 3 $endip 443 > /dev/null

    if [ `echo $?` == 0 ]
    then
      fn_make_item
      fn_check_cert
    fi
done

###
rm -f /tmp/*-ZABBIX-CERT-*

Observações:

  • cat /usr/local/bin/monits/lista-dominios.txt – um site/dominio por linha, exemplo:
    • www.google.com
    • www.microsoft.com
  • vou documentar o código “update-zabbix-proxy.php”, pois ele não é nativo do Zabbix
  • e como obter os “IDs” dos itens do Zabbix como Templates, Items, Grupos, etc

O update-zabbix-proxy.php

Bom, não se se todos sabem, mas a API do Zabbix no método de criação de um novo host (aqui vai ter outra explicação sobre algo que uso) não permite indicar qual será o proxy responsável pela monitoria: https://www.zabbix.com/documentation/current/manual/api/reference/host/create

No passado eu usava uma rotina via banco de dados para corrigir esta configuração, porém era bem ruim.

Com isso em mente, tempos atrás consegui um código com um amigo, “Nilton Souza” ( ele precisa autorizar colocar o e-mail dele aqui), que é responsável por receber a requisição para que logo após do uso o método de criação de um novo host a gente consiga alterar o proxy.

O código é em php, segue:

<?php

define('MYSQL_HOST', '127.0.0.1');
define('MYSQL_PORT', 3306);
define('MYSQL_USER', 'root');
define('MYSQL_PASS', '');
define('MYSQL_DB', 'zabbix');

if (!empty($_POST['proxy_hostid']) && !empty($_POST['host'])) {
    $connStr = 'mysql:host=' . MYSQL_HOST . ';port=' . MYSQL_PORT . ';dbname=' . MYSQL_DB;

    try {
        $conn = new PDO($connStr, MYSQL_USER, MYSQL_PASS);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $update = "UPDATE hosts
                      SET proxy_hostid = '{$_POST['proxy_hostid']}'
                    WHERE host = '{$_POST['host']}'";

        $conn->exec($update);
    } catch (Exception $e) {
        http_response_code(500);
        echo "ERRO: {$e->getMessage()}\n";
    }
}

Esse código deve ficar publicado no seu servidor web (preferencialmente no FE do Zabbix), nesse exemplo estamos usando um servidor Apache Httpd:

pwd
/etc/httpd/conf.d

cat zabbix-update.conf

Alias /zabbix-balancer "/var/www/html/zabbix-balancer"

<Directory /var/www/html/zabbix-balancer>

        Options Indexes FollowSymLinks MultiViews ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
        DirectoryIndex smokeping.fcgi

</Directory>

Dessa forma conseguimos usar via método POST, conforme nosso script anterior:

WS_UPDATE="http://zabbix.intranet/zabbix-balancer/ws/update-zabbix-proxy.php"

# Executando o update
curl -s --data "proxy_hostid=$PRX_ID&host=$name" -X POST $WS_UPDATE

Como obter os “IDs” dos itens do Zabbix como Templates, Items, Grupos, etc

Agora vou explicar a maneira mais fácil de obter os IDs que vamos usar nos nossos scripts.

Existem duas maneiras de fazer isso:

1a – via banco de dados, já usei, funciona, mas requer mais tempo

2a – via interface do Zabbix, bem simples

Vamos seguir com a segunda opção!!!

Vou considerar que você já tem o seu template pronto, se não faça um agora mesmo, lembre-se de adicionar um item do tipo trapper.

Exemplo de um template com um item do tipo trapper.

Faça uma busca pelo nome do seu template no Zabbix:

Exemplo de busca

O seu template deverá ser mostrado na seleção conforme abaixo:

Resultado da busca

Clique no nome do template

Será apresentada a tela abaixo:

Resultado com template

Repare na tela que eu coloquei o cursor do mouse sobre o nome do template e na barra de status do navegador foi exibida uma URI com o templateid, no nosso caso é o 35833.

Esse ID será usado no nosso script para que quando ocorrer a criação de um novo hosts, já ocorra a indicação de qual será o template utilizado.

Esse recurso, pode ser feito para grupos, itens, gráficos, ou seja, se é um objeto no Zabbix podemos consultar o seu ID de uma maneira rápida é fácil

Sobre “host”

Um pouco antes, eu indiquei que falaria sobre o host criado no Zabbix, eu particularmente gosto de falar que é um agregador ou agregação, pois um host pode ser um equipamento físico, um servidor virtual ou até mesmo um conjunto de identificação de sistemas e componentes, ou seja, não um equipamento ou um servidor.

É melhor eu dar um exemplo.

Digamos que você tem um sistema de entrada de dados, aqui vamos chamá-lo de “cadastro” e esse sistema tem componentes que são servidos em servidores físicos/virtuais, cloud, switchs, roteadores, fw e caso um destes recursos cause problema nos seus componentes o seu sistema “cadastro” poderá apresentar falhas.

Então podemos adicionar um novo hosts no Zabbix com o nome de “Cadastro”, fazer o relacionamento dele com um Template com itens o tipo trapper e passar a monitorar o “estado” do seu “Cadastro”, veja, não vamos relacionar o sistema em um outro servidor, isso será monitorado pelo Zabbix usando o Agent, mas sim, vamos ter um “status” dinâmico bastando coletar outras métricas e usar relacionamentos que indique a saúde do seu sistema.

Um exemplo que uso é a monitoria do Health da AWS, veja, no meu ambiente eu não tenho um servidor chamado AWS, mas a minha empresa depende dela, então nos criamos um programa que pega o status da página de status da AWS e envia o resultado para o Zabbix que trata dentro de uma trigger, basicamente fazendo isso no final:

/usr/bin/zabbix_sender -z zbxtrapper01.intranet -s AWS_HEALTH -k status -o 0

A minha trigger trata o codigo “0” – se for 0 é ok, se não é incidente.

No Zabbix eu criei um “host” (agregação) com o nome de AWS_HEALTH

Objeto “host” no Zabbix

E nesta agregação (viu, mudei aqui) eu tenho um template relacionado com um item do tipo trapper

Template com item Trapper

Obs: vou publicar esse script.

Ok, voltei a publicar…

Posted on 3 de julho de 2021 - 3 de julho de 2021 by rzlrogerio

Vamos ver como vai ser.

Vou tentar ser direto visando ajudar os analistas de tecnologia da informação.

Sei pouco e o pouco que sei vou tentar transmitir.

Obrigado.

Posts recentes

  • Monitorando a expiração de um domínio
  • Vamos falar de monitoria de sistemas
  • Ok, voltei a publicar…

Comentários

    Proudly powered by WordPress | Theme: micro, developed by DevriX.