Monitoramento e gerenciamento remotos de dispositivos baseados em Linux / OpenWrt / Lede através da porta 80 ...

Olá pessoal, esta é a minha primeira experiência em Habré. Quero escrever sobre como gerenciar equipamentos de rede não padrão em uma rede externa. O que significa não-padrão: na maioria dos casos, para controlar o equipamento em uma rede externa, você precisa:

  • O endereço IP público. Bem, ou se o equipamento estiver localizado atrás do NAT de alguém, o IP público e a porta "encaminhada".
  • O túnel (PPTP / OpenVPN / L2TP + IPSec, etc.) para o nó central através do qual ele estaria acessível.

Portanto, você precisará da minha bicicleta quando os métodos padrão não forem adequados para você, por exemplo:
  1. O equipamento está localizado atrás do NAT e, além do http usual (porta 80), tudo está fechado. A situação é bastante normal para grandes redes corporativas federais. Registrar portas - elas podem, mas não imediatamente, não rapidamente e não para você.
  2. Canal de comunicação instável e / ou "estreito". Baixa velocidade, perda constante. Dor e frustração ao tentar organizar um túnel.
  3. Um canal de comunicação caro, onde literalmente cada megabyte conta. Por exemplo, comunicações via satélite. Além de grandes atrasos e uma faixa "estreita".
  4. A situação em que você precisa "manipular" um grande número de roteadores pequenos, nos quais, por um lado, o OpenWrt / Lede está instalado para expandir os recursos e, por outro lado, os recursos (memória) do roteador estão longe de serem suficientes.

Anote o número de vezes
E o que impede a instalação de um dispositivo USB do roteador e a expansão da memória do roteador?

Na maioria das vezes, os requisitos para o custo da solução como um todo, mas às vezes o fator de forma também desempenha um papel fundamental. Por exemplo, o TP-Link ML3020 está no objeto, sua única porta USB é usada para um modem 2G / 3G, tudo isso é enrolado em um fio com uma pequena caixa de plástico e colocado em algum lugar alto, alto (no mastro), longe, longe (em a 30 km da estação base mais próxima de uma operadora de celular). Sim, você pode conectar um hub USB e expandir o número de portas, mas a experiência demonstrou que é complicado e não confiável.

Então, tentei descrever para você minha situação típica: “em algum lugar muito, muito longe, há um roteador muito importante, solitário e pequeno, executando o Linux. É importante saber pelo menos uma vez por dia que ele está "vivo" e, se necessário, foram enviados comandos a ele, por exemplo, "sol, reinicie!"

Vamos seguir para a implementação:

1) No lado do roteador, cron a cada 5/10/1440 minutos, ou sempre que precisar enviar uma solicitação http para o servidor usando wget, salve o resultado da solicitação em um arquivo, torne o arquivo executável e execute-o.

Minha linha no cron é mais ou menos assim:

Arquivo / etc / crontabs / root:

*/5 * * * * wget "http://xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai/a.php?u=user&p=password" -O /tmp/wa.sh && chmod 777 /tmp/wa.sh && /tmp/wa.sh 

onde:
xn - 80abgfbdwanb2akugdrd3a2e5gsbj.xn - p1ai - o domínio do meu servidor. Observarei imediatamente: sim, você também pode especificar um endereço IP de servidor específico, já fizemos isso antes, enquanto nosso estado, em uma explosão justa de luta, não me parecia mais - não bloqueou o acesso à maior parte das "nuvens" da DigitalOcean e Amazon. No caso de usar um domínio simbólico, quando esse incidente ocorre, você pode aumentar a nuvem de backup com calma, redirecionar o domínio para ele e restaurar o monitoramento do dispositivo.

a.php - o nome do script no lado do servidor. Sim, eu sei que é errado nomear variáveis ​​e nomes de arquivos com uma letra ... Sugiro que salvemos alguns bytes ao enviar uma solicitação :)
u - nome de usuário, login de hardware
p - senha
"-O /tmp/wa.sh" é o arquivo no roteador remoto em que a resposta do servidor será salva, por exemplo, o comando reboot.

Nota número dois:
Ahhh, por que usamos wget, não curl, porque através do curl você pode enviar solicitações https e não GET, mas POST? Ahhh, porque, como na velha piada, “NE entra na cabana!”. O Curl inclui bibliotecas de criptografia com cerca de 2 MB de tamanho e, em virtude disso, você poderá montar uma imagem para um pequeno TP-LINK ML3020, por exemplo. E com o wget, por favor.

2) No lado do servidor (eu tenho o Ubuntu), usaremos o Zabbix. Motivo: quero que seja bonito (com gráficos) e conveniente (envie comandos pelo menu de contexto). O Zabbix tem uma coisa adorável como um agente do zabbix. Por meio do agente, chamaremos o script php no servidor, que retornará informações sobre se nosso roteador foi registrado no período de tempo necessário. Para armazenar informações sobre o tempo de registro, comandos para dispositivos, eu uso o MySQL, uma tabela de usuários separada com aproximadamente os seguintes campos:

  CREATE TABLE `users` ( `id` varchar(25) NOT NULL, `passwd` varchar(25) NOT NULL, `description` varchar(150) NOT NULL, `category` varchar(30) NOT NULL, `status` varchar(10) NOT NULL, `last_time` varchar(20) NOT NULL, //    `last_ip` varchar(20) NOT NULL, // IP   `last_port` int(11) NOT NULL, //    `task` text NOT NULL, //     `reg_task` varchar(150) NOT NULL, // "" ,          `last_task` text NOT NULL, //   `response` text NOT NULL, //     `seq` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

Todas as fontes podem ser obtidas no repositório Git em: https://github.com/BazDen/iotnet.online.git
Agora, os scripts PHP hospedados no servidor (por conveniência, você pode colocá-los na pasta / usr / share / zabbix /):

Arquivo A.php:

 <?php //   :  ,       //   message ?    ,         $user=$_REQUEST['u']; $password=$_REQUEST['p']; $message=$_REQUEST['m']; //      (MySQL) $conn=new mysqli("localhost","db_login","db_password","DB_name"); if (mysqli_connect_errno()) { exit(); } $conn->set_charset("utf8"); //         $sql_users=$conn->prepare("SELECT task, reg_task, response, last_time FROM users WHERE id=? AND passwd=? AND status='active';"); $sql_users->bind_param('ss', $user, $password); $sql_users->bind_result($task, $reg_task, $response, $last_time); $sql_users->execute(); $sql_users->store_result(); if (($sql_users->num_rows)==1){ $sql_users->fetch(); //       echo $task; echo "\n"; echo $reg_task; //           $response_history="[".date("Ymd H:i")."] ".$message; //  ,    ,     ,  -   $last_ip=$_SERVER["REMOTE_ADDR"]; $last_port=$_SERVER["REMOTE_PORT"]; $ts_last_conn_time=$last_time; $sql_users=$conn->prepare("UPDATE users SET task='', seq=1 WHERE (id=?);"); $sql_users->bind_param('s', $user); $sql_users->execute(); if (strlen($message)>1){ $sql_users=$conn->prepare("UPDATE users SET response=?, seq=1 WHERE (id=?);"); $sql_users->bind_param('ss', $response_history, $user); $sql_users->execute(); } //      ,      .    $ts_now=time(); $sql_users=$conn->prepare("UPDATE users SET last_time=?, last_ip=?, last_port=? WHERE (id=?);"); $sql_users->bind_param('ssss', $ts_now, $last_ip, $last_port, $user); $sql_users->execute(); } //         ,    "",   ...    reboot.... //    ?     ,      " ". else { echo "reboot"; } $sql_users->close(); ?> 

Arquivo Agent.php (este é o script do agente zabbix chamado):

 <?php //   Zabbix.      users   "1"        // user  password -    $user = $argv[1]; $password = $argv[2]; //      $conn=new mysqli("localhost","db_user","db_password","db_name"); if (mysqli_connect_errno()) { exit(); } $conn->set_charset("utf8"); $sql_users=$conn->prepare("SELECT seq FROM users WHERE id=? AND passwd=? AND status='active';"); $sql_users->bind_param('ss', $user, $password); $sql_users->bind_result($seq); $sql_users->execute(); $sql_users->store_result(); //      seq.        "1" if (($sql_users->num_rows)==1){ $sql_users->fetch(); echo $seq; } //  $seq. $sql_users=$conn->prepare("UPDATE users SET seq=0 WHERE id=? AND passwd=? AND status='active';"); $sql_users->bind_param('ss', $user, $password); $sql_users->execute(); $sql_users->close(); ?> 

Bem, a etapa final: prescrever um agente e adicionar agendas.

Se você ainda não instalou o agente zabbix, então:

 apt-get install zabbix-agent 

Editando o arquivo /etc/zabbix/zabbix_agentd.conf.

Adicione a linha:

 UserParameter=test,php /usr/share/zabbix/agent.php user password 

onde:
teste é o nome do nosso agente
"Php /usr/share/zabbix/agent.php senha do usuário" - o script chamado com os dados de registro do dispositivo.

Adicionando gráficos: abra a interface da web do zabbix, selecione no menu:
Configurações -> Hosts -> Criar host. Basta especificar o nome do host, seu grupo, a interface do agente padrão:



Agora precisamos adicionar um elemento de dados para este host. Preste atenção em dois campos: a "chave" é exatamente o parâmetro que especificamos no arquivo /etc/zabbix/zabbix_agentd.conf (no nosso caso, é test), e o "intervalo de atualização" - configurei 5 minutos, porque e o equipamento é registrado no servidor uma vez a cada cinco minutos.



Bem, adicione a programação. Eu recomendo escolher "Preencher" como o estilo do desenho.



A saída é algo muito conciso, por exemplo:



À pergunta razoável: “Valeu a pena?”, Responderei: bem, é claro, veja as “razões para criar uma bicicleta” no início do artigo.

Se minha primeira experiência grafo-maníaca despertar o interesse dos leitores, nos artigos a seguir quero descrever como enviar comandos para equipamentos remotos. Também foi possível implementar todo o esquema para dispositivos baseados no RouterOS (Mikrotiks).

Source: https://habr.com/ru/post/pt445568/


All Articles