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

Olá a todos, este é meu primeiro experimento no Habr. Quero escrever sobre como gerenciar equipamentos de rede em uma rede externa de maneira não convencional. O que significa não convencional: na maioria dos casos, para gerenciar equipamentos na rede externa, você precisa:

  • Um endereço IP público. Ou, se o equipamento estiver atrás de um NAT, um IP público e uma porta ‘redirecionada’.
  • Um túnel (PPTP/OpenVPN/L2TP+IPSec, etc.) até o nó central, pelo qual seria acessível.

Portanto, ‘minha bicicleta’ será necessária quando os métodos padrão não funcionarem, por exemplo:

  1. O equipamento está atrás de um NAT e além do http normal (porta 80) — tudo está fechado. Uma situação bastante comum em grandes redes corporativas federais. Eles podem abrir portas — mas não imediatamente, não rapidamente e não para você.
  2. Canal de comunicação instável e/ou ‘estreito’. Velocidade baixa, perdas constantes. Dor e decepção ao tentar estabelecer um túnel.
  3. Canal de comunicação caro, onde literalmente cada megabyte conta. Por exemplo, comunicação via satélite. Além disso, grandes latências e largura de banda ‘estreita’.
  4. Situação em que você precisa ‘jonglar’ com um grande número de pequenos roteadores, onde de um lado está instalado OpenWrt/Lede para expandir as capacidades, e do outro lado os recursos (memória) do roteador não são suficientes para tudo.

Nota número um E o que impede de instalar uma ‘flash drive’ na porta USB do roteador para aumentar a memória do roteador?

Mais frequentemente, as exigências em relação ao custo da solução como um todo, mas às vezes o fator de forma também desempenha um papel crucial. Por exemplo, em uma instalação está um TP-Link ML3020, sua única porta USB é usada para um modem 2G/3G, tudo isso está dentro de algum pequeno gabinete plástico e colocado em algum lugar muito alto (na torre), desnecessariamente longe (no campo, a 30 km da estação base móvel mais próxima). Sim, você pode conectar um hub USB e aumentar o número de portas, mas a experiência mostra que isso é volumoso e pouco confiável.

Assim, tentei descrever minha situação típica: ‘em algum lugar muito longe, há um roteador muito importante, solitário e pequeno, rodando Linux. É importante saber pelo menos uma vez ao dia, que ele está “vivo” e, se necessário, enviar comandos para ele, por exemplo, ‘solzinho, reinicie!’

Vamos passar para a implementação:

1) No lado do roteador, a cada 5/10/1440 minutos, ou quando necessário, deve-se enviar uma solicitação http ao servidor usando wget, salvando o resultado em um arquivo, tornando o arquivo executável e executando-o.

Minha linha no cron se parece com isso:

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. Devo mencionar que sim, é possível usar um endereço IP específico do servidor, fizemos isso antes, até que nosso governo, em um impulso justo de luta contra não sei o quê — fechou o acesso à grande maioria das "nuvens" da DigitalOcean e da Amazon. No caso de usar um domínio simbólico, caso ocorra um incidente parecido, você poderá levantar uma nuvem reserva, redirecionar o domínio para ela e restaurar o monitoramento dos dispositivos.

a.php — é o nome do script no lado do servidor. Sim, eu sei que é incorreto nomear variáveis e nomes de arquivos com uma única letra… vamos considerar que assim economizamos alguns bytes ao enviar a solicitação 🙂
u — nome de usuário, login do dispositivo
p — senha
"-O /tmp/wa.sh" — é o arquivo no roteador remoto onde a resposta do servidor será salva, por exemplo, o comando reboot.

Nota número dois: Aaaa, por que usamos wget e não curl, já que através do curl é possível enviar solicitações https e não apenas GET, mas também POST? Aaaa porque, como no velho anedoto, "Não cabe na bilha!". O curl inclui bibliotecas de criptografia de cerca de 2MB e, por causa disso, é improvável que você consiga montar uma imagem para um pequeno TP-LINK ML3020, por exemplo. Mas com wget — é tranquilo.

2) No lado do servidor (aqui estou usando Ubuntu) usaremos o Zabbix. Por quê: quero que seja bonito (com gráficos) e conveniente (enviar comandos através do menu de contexto). O Zabbix possui uma funcionalidade incrível chamada zabbix-agent. Através do agente, chamaremos um script php em servidor, que retornará informações sobre se nosso roteador foi registrado no período de tempo requerido. Para armazenar informações sobre o tempo de registro e os comandos dos dispositivos, estou usando MySQL, uma tabela separada users com aproximadamente os seguintes campos:

		CRIE A TABELA `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, 
		  `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;

Todos os códigos-fonte podem ser obtidos no repositório Git, no endereço: https://github.com/BazDen/iotnet.online.git
Agora os scripts PHP, que são colocados no lado do servidor (para facilitar, podem ser colocados na pasta /usr/share/zabbix/):

O arquivo a.php:

set_charset("utf8");
	// Aqui pesquisamos nosso roteador na tabela do banco de dados
	$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();
		// Aqui enviamos as tarefas para o roteador
		echo $task;
		echo "n";
		echo $reg_task;
		// Aqui escrevemos o tempo de resposta e a própria resposta do roteador
		$response_history="[".date("Y-m-d H:i")."] ".$message;
		// Tarefa enviada, agora precisamos deletá-la, e após a deleção, marcar nos logs que tal tarefa foi concluída
		$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();
		}
		// Agora precisamos salvar o tempo de registro do usuário, seu IP e mensagem dele. Por enquanto, apenas a mensagem
		$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();
	}
	// Se não encontramos o roteador em nosso banco de dados, ou seu status é "inativo", então será ... enviada o comando reboot....
	// Por que tão severo? Porque os roteadores às vezes desaparecem, e essa é uma pequena maneira de ensinar uma lição a "novos proprietários". 
	else
	{
	echo "reboot";
	}
	$sql_users->close();
?>

O arquivo agent.php (este é o script do agente Zabbix chamado):

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();
	// a troca de dados ocorre através do campo seq. Ao registrar, o dispositivo define este campo como "1"
	if (($sql_users->num_rows)==1){
		$sql_users->fetch();
		echo $seq;
	}
		
	// zerando $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();
?>		

E a etapa final: configuração do agente e adição de gráficos.

Se você ainda não instalou o agente Zabbix, faça:

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:
test — o nome do nosso agente
„php /usr/share/zabbix/agent.php user password“ — o script chamado com as credenciais de registro do dispositivo.

Adicionando gráficos: abra a interface da web do Zabbix, no menu escolha:
Configuração -> Nós da rede -> Criar nó da rede. Aqui, basta informar o nome do nó da rede, seu grupo e a interface do agente padrão:

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

Agora, para este nó da rede, precisamos adicionar um item de dados. Observe dois campos: "chave" — este é o parâmetro que definimos no arquivo /etc/zabbix/zabbix_agentd.conf (neste caso, é test), e "intervalo de atualização" — eu coloco 5 minutos, pois o equipamento se registra no servidor também uma vez a cada cinco minutos.

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

E então adicionamos o gráfico. Recomendo escolher "Preenchimento" como estilo de renderização.

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

No resultado, obtemos algo muito sucinto, por exemplo assim:

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

Para a pergunta razoável: "valeu a pena?", respondo: claro, veja "razões para criar uma bicicleta" no início do artigo.

Se minha primeira experiência de grafomania despertar o interesse dos leitores, nas próximas matérias quero descrever como enviar comandos para equipamentos remotos. Também consegui implementar toda a estrutura para dispositivos baseados no RouterOS (Mikrotik).

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster