- Publicado em
Monitoramento de PPPoE, DHCP e OSPF por Interface no Mikrotik usando scripts
- Autores
- Nome
- Felipe Padilha
Introdução
Embora o Mikrotik ofereça suporte a SNMP para monitoramento, nem todos os parâmetros ou estados são facilmente exportáveis por ele, especialmente em cenários mais complexos. Muitas informações dinâmicas — como leases de DHCP por interface, sessões PPPoE e adjacências OSPF — não estão disponíveis para monitoramento via SNMP.
O Mikrotik RouterOS possui uma linguagem de script própria, que apesar de limitada em alguns aspectos, permite realizar tarefas de consulta, processamento e formatação de dados.
Ao estruturarmos a saída dos scripts em formato JSON, facilitamos a integração com ferramentas como o Zabbix, (ou qualquer sistema que consiga fazer parsing de JSON). Essa abordagem reduz o esforço de tratamento da resposta, tornando o monitoramento muito mais direto e padronizado.
Link para o tutorial em vídeo
Explicação geral do funcionamento dos scripts
Os scripts são executados diretamente no RouterOS via SSH e têm como objetivo coletar informações que não são facilmente acessíveis via SNMP. Cada script percorre os elementos desejados (interfaces, servidores PPPoE, adjacências OSPF, etc.), extrai dados relevantes e os organiza em formato JSON, facilitando o consumo por sistemas de monitoramento como o Zabbix.
A estrutura geral do funcionamento dos scripts é:
- Coleta dos dados relevantes (ex.: servidores DHCP, sessões PPPoE, vizinhos OSPF);
- Contagem ou leitura de atributos de cada objeto (ex.: quantidade de leases, clientes ativos, estado da adjacência);
- Construção de um objeto JSON por item, contendo:
- Um identificador (ex.: interface, servidor, router_id);
- Um objeto com os valores monitoráveis (ex.: leases, clientesAtivos, mudancas_estado);
- Montagem final em JSON válido com todos os itens dentro de uma lista em data.
Esse formato permite:
- Utilizar Low-Level Discovery (LLD) no Zabbix para identificar dinamicamente os itens a serem monitorados;
- Configurar Item Prototypes com JSONPath para extrair dados específicos;
O script deve ser salvo em System -> Scripts e conseguimos rodá-lo pela CLI do Mikrotik por meio do comando system script run nome_do_script
.
Quantidade de Leases DHCP por Interface
:global lista [/ip dhcp-server find];
:global total [:len $lista];
:global contador 0;
:put "{ \"data\": [";
:foreach i in=$lista do={
:local servidor [/ip dhcp-server get value-name=name $i];
:local interface [/ip dhcp-server get value-name=interface $i];
:local leases [:len [/ip dhcp-server lease find where server=$servidor]];
:if ($contador < $total) do={
:if ($contador = ($total - 1)) do={
:put ("{ \"interface\": \"$interface\", \"servidor\": \"$servidor\", \"dados\": { \"leases\": $leases } }");
} else={
:put ("{ \"interface\": \"$interface\", \"servidor\": \"$servidor\", \"dados\": { \"leases\": $leases } },");
}
};
:set contador ($contador + 1);
};
:put "] }\n";
Configuração do item no Zabbix
Vamos usar dois itens, um item normal, que irá executar o script e receber o retorno de todas as entradas e um item de descoberta automática dependente, que para cada entrada irá criar um item de monitoramento.

- Nome: Item Mestre - Monitoramento DHCP
- Tipo: Agente SSH
- Chave: ssh.run[monitoramento_dhcp,,,,]
- Método de autenticação: Senha
- Nome do usuário: conforme sua estrutura
- Senha: conforme sua estrutura
- Script executado:
/system script run monitoramento_dhcp
- Intervalo de atualização: 5m

- Nome: Descoberta Clientes DHCP
- Tipo: Item dependente
- Chave: descoberta.clientes.dhcp
- Item mestre: Item Mestre - Monitoramento DHCP

{#INTERFACE}
: $.inteface{#SERVIDOR}
: $.servidor

- Nome: {#INTERFACE}({#SERVIDOR}) - Quantidade de Leases
- Tipo: Item dependente
- Chave: dhcp.lease.[{#SERVIDOR}]
- Tipo de informação: Numérico (inteiro sem sinal)
- Item mestre: Item Mestre - Monitoramento DHCP

$.data[?(@.interface == '{#INTERFACE}')].dados.leases.first()
Quantidade de sessões PPPoE por Interface
:global lista [/interface pppoe-server server find];
:global total [:len $lista];
:global contador 0;
:put "{ \"data\": [";
:foreach i in=$lista do={
:local servidor [/interface pppoe-server server get value-name=service-name $i];
:local clientesAtivos [:len [/interface pppoe-server find where service=$servidor]];
:if ($contador < $total) do={
:if ($contador = ($total - 1)) do={
:put ("{ \"servidor\": \"$servidor\", \"dados\": { \"clientesAtivos\": $clientesAtivos } }");
} else={
:put ("{ \"servidor\": \"$servidor\", \"dados\": { \"clientesAtivos\": $clientesAtivos } },");
}
};
:set contador ($contador + 1);
};
:put "] }\n";
Configuração do item no Zabbix

- Nome: Item Mestre - Monitoramento PPPoE
- Tipo: Agente SSH
- Chave: ssh.run[monitoramento_pppoe,,,,]
- Método de autenticação: Senha
- Nome do usuário: conforme sua estrutura
- Senha: conforme sua estrutura
- Script executado:
/system script run monitoramento_pppoe
- Intervalo de atualização: 5m

- Nome: Descoberta Servidores PPPoE
- Tipo: Item dependente
- Chave: descoberta.servidores.pppoe
- Item mestre: Item Mestre - Monitoramento PPPoE

{#SERVIDOR}
: $.servidor

- Nome: {#SERVIDOR} - Clientes Ativos
- Tipo: Item dependente
- Chave: pppoe.ativos.[{#SERVIDOR}]
- Tipo de informação: Numérico (inteiro sem sinal)
- Item mestre: Item Mestre - Monitoramento PPPoE

$.data[?(@.servidor== '{#SERVIDOR}')].dados.clientesAtivos.first()
Estado do vizinho OSPF
:global lista [/routing ospf neighbor find];
:global total [:len $lista];
:global contador 0;
:put "{ \"data\": [";
:foreach i in=$lista do={
:local routerId [/routing ospf neighbor get value-name=router-id $i];
:local address [/routing ospf neighbor get value-name=address $i];
:local status [/routing ospf neighbor get value-name=state $i];
:local uptime [/routing ospf neighbor get value-name=adjacency $i];
:local quantidadeMudancas [/routing ospf neighbor get value-name=state-changes $i];
:if ($contador < $total) do={
:if ($contador = ($total - 1)) do={
:put ("{ \"router_id\": \"$routerId\", \"address\": \"$address\", \"dados\": { \"status\": \"$status\", \"uptime\": \"$uptime\", \"mudancas_estado\": $quantidadeMudancas } }");
} else={
:put ("{ \"router_id\": \"$routerId\", \"address\": \"$address\", \"dados\": { \"status\": \"$status\", \"uptime\": \"$uptime\", \"mudancas_estado\": $quantidadeMudancas } },");
}
};
:set contador ($contador + 1);
};
:put "] }\n";
Configuração do item no Zabbix

- Nome: Item Mestre - Monitoramento OSPF
- Tipo: Agente SSH
- Chave: ssh.run[monitoramento_ospf,,,,]
- Método de autenticação: Senha
- Nome do usuário: conforme sua estrutura
- Senha: conforme sua estrutura
- Script executado:
/system script run monitoramento_ospf
- Intervalo de atualização: 5m

- Nome: Descoberta Neighbors OSPF
- Tipo: Item dependente
- Chave: descoberta.neighbors.ospf
- Item mestre: Item Mestre - Monitoramento OSPF

{#ADDRESS}
: $.address{#ROUTER_ID}
: $.router_id

- Nome: {#ROUTER_ID}({#ADDRESS}) - Estado da Sessão
- Tipo: Item dependente
- Chave: ospf.state.[{#ROUTER_ID}.{#ADDRESS}]
- Tipo de informação: Numérico (inteiro sem sinal)
- Item mestre: Item Mestre - Monitoramento OSPF

$.data[?(@.router_id == '{#ROUTER_ID}' && @.address == '{#ADDRESS}')].dados.status.first()