Monitoraghju remotu è cuntrollu di i dispositi basati Lunix / OpenWrt / Lede via u portu 80 ...

Salute à tutti, questa hè a mo prima sperienza nantu à Habré. Vogliu scrive nantu à cumu gestisce l'equipaggiu di rete in una reta esterna in una manera micca standard. Ciò chì significa micca standard: in a maiò parte di i casi, per gestisce l'equipaggiu nantu à una reta esterna avete bisognu:

  • Indirizzu IP publicu. Eppo, o se l'equipaggiu hè daretu à u NAT di qualcunu, allora una IP publica è un portu "inviatu".
  • Tunnel (PPTP / OpenVPN / L2TP + IPSec, etc.) à u node cintrali attraversu quale saria accessibile.

Dunque, avete bisognu di "a mo bicicletta" quandu i metudi standard ùn vi cunvene micca, per esempiu:

  1. L'equipaggiu hè situatu daretu à NAT è, fora di u solitu http (port 80), tuttu hè chjusu. Questa hè una situazione cumpletamente normale per e grande rete corporativa federale. Puderanu registrà porti, ma micca subitu, micca rapidamente, è micca per voi.
  2. Canale di cumunicazione instabile è/o "strettu". Bassa velocità, perdite custanti. Dolore è frustrazione quandu pruvate d'urganizà un tunnel.
  3. Un canali di cumunicazione caru, induve literalmente ogni megabyte conta. Per esempiu, cumunicazioni satellitari. Plus ritardi longu è una banda "stretta".
  4. Una situazione quandu avete bisognu di "juggle" un gran numaru di picculi routers, nantu à quale, da una banda, OpenWrt / Lede hè stallatu per espansione e capacità, è da l'altra banda, e risorse (memoria) di u router ùn sò micca abbastanza. per tuttu.

Nota numeri volte Ciò chì impedisce di installà una unità flash in u portu USB di u router è espansione a memoria di u router?

A maiò spessu, i requisiti sò per u costu di a suluzione in generale, ma qualchì volta u fattore di forma ghjoca ancu un rolu chjave. Per esempiu, ci hè un TP-Link ML3020 in u situ, u so unicu portu USB hè utilizatu per un modem 2G / 3G, tuttu questu hè impannillatu in qualchì tipu di casu di plastica chjuca è pusatu in un locu altu, altu (nantu à u mastru). luntanu, luntanu (in campu, 30 km da a stazione di basa di l'operatore mobile più vicinu). Iè, pudete inserisce un hub USB è espansione u numeru di porti, ma l'esperienza mostra chì questu hè ingombrante è inaffidabile.

Allora, aghju pruvatu à descriverà a mo situazione tipica: "in un locu luntanu, luntanu, ci hè un router assai impurtante, solitario è chjucu chì corre Linux. Hè impurtante di sapè almenu una volta à ghjornu chì ellu hè "vivu" è, se ne necessariu, i cumandamenti sò mandati à ellu, per esempiu, "meli, reboot!"

Passemu à l'implementazione:

1) Da u latu di u router, via cron, ogni 5/10/1440 minuti, o quandu vulete, avete bisognu di mandà una dumanda http à u servitore cù wget, salvà u risultatu di a dumanda in un schedariu, rende u schedariu eseguibile. , è eseguite.

A mo cron line pare qualcosa cusì:

File /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

, induve:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai hè u duminiu di u mo servitore. Lasciami nutà subitu: iè, pudete specificà un indirizzu IP specificu di u servitore, avemu usatu per fà questu finu à u nostru statu, in un impulsu ghjustu di lotta, diceraghju, ùn sò micca, bluccatu l'accessu à u leone. parte di i "nuvuli" di DigitalOcean è Amazon. Sè vo aduprate un duminiu simbolicu, se un tali incidente succedi, vi ponu facirmenti risaltà un nuvola di salvezza, redirige u duminiu à lu è restaurà u surviglianza dispusitivu.

a.php hè u nome di u script di u servitore. Iè, sò chì hè sbagliatu per nome di variabili è nomi di schedari cù a listessa lettera... Suggeriu chì cusì salvemu uni pochi di byte quandu mandemu una dumanda :)
u - nome d'utilizatore, login hardware
p - password
"-O /tmp/wa.sh" hè un schedariu nantu à u router remoto induve a risposta di u servitore, per esempiu, u cumandamentu di reboot, serà salvatu.

Nota numeru dui: Ahhh, perchè usemu wget è micca curl, perchè via curl pudete mandà https richieste micca cù GET, ma cù POST? Ahhh perchè, cum'è in u vechju scherzu "NE cullà in u vasu!" curl include librerie di criptografia di circa 2MB in grandezza è per quessa hè improbabile chì puderete assemble una maghjina per un picculu TP-LINK ML3020, per esempiu. È cù wget - per piacè.

2) Da u latu di u servitore (aghju Ubuntu) useremu Zabbix. Perchè: Vogliu chì sia bella (cù grafici) è cunvene (invià cumandamenti via u menù di cuntestu). Zabbix hà una cosa cusì maravigliosa cum'è l'agente zabbix. Per mezu di l'agente, chjameremu un script PHP in u servitore, chì restituverà infurmazioni nantu à se u nostru router hà registratu durante u periodu di tempu necessariu. Per almacenà l'infurmazioni nantu à u tempu di registrazione, i cumandamenti per i dispositi, aghju utilizatu MySQL, una tabella separata d'utilizatori cù apprussimatamente i seguenti campi:

		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;

Tutte e fonti ponu esse scaricate da u repository Git à: https://github.com/BazDen/iotnet.online.git
Avà script PHP posti nantu à u latu di u servitore (per comodità, ponu esse posti in u cartulare /usr/share/zabbix/):

a.php file:

<?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("Y-m-d 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();
	?>

File Agent.php (questu hè u script di l'agente zabbix chjamatu):

<?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();
?>		

Ebbè, l'ultima tappa: registrà un agentu è aghjunghje scheduli.

Se ùn avete micca installatu l'agente zabbix, allora:

apt-get install zabbix-agent

Edite u schedariu /etc/zabbix/zabbix_agentd.conf.

Aghjunghjite a linea:

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

, induve:
test hè u nome di u nostru agente
"php /usr/share/zabbix/agent.php password d'utilizatore" - un script chjamatu chì indica i dati di registrazione di u dispositivu.

Adding charts: apre l'interfaccia web zabbix, selezziunate da u menù:
Settings -> Network Nodes -> Crea un node di rete. Quì hè abbastanza per specificà u nome di l'ospite di a rete, u so gruppu, è l'interfaccia di l'agente predeterminata:

Monitoraghju remotu è cuntrollu di i dispositi basati Lunix / OpenWrt / Lede via u portu 80 ...

Avà avemu bisognu di aghjunghje un elementu di dati per questu node di rete. Prestate attenzione à dui campi: "chiave" - ​​questu hè esattamente u paràmetru chì avemu scrittu in u schedariu /etc/zabbix/zabbix_agentd.conf (in u nostru casu hè una prova), è "intervallu d'aghjurnamentu" - aghju stabilitu à 5 minuti. , perchè è l'equipaggiu hè ancu registratu nantu à u servitore una volta ogni cinque minuti.

Monitoraghju remotu è cuntrollu di i dispositi basati Lunix / OpenWrt / Lede via u portu 80 ...

Ebbè, aghjustemu un graficu. Vi cunsigliu di sceglie "Fill" cum'è u stilu di rendering.

Monitoraghju remotu è cuntrollu di i dispositi basati Lunix / OpenWrt / Lede via u portu 80 ...

L'output hè una cosa assai laconica, per esempiu, cusì:

Monitoraghju remotu è cuntrollu di i dispositi basati Lunix / OpenWrt / Lede via u portu 80 ...

À a quistione raghjunata: "vale a pena?", risponderaghju: bè, sicuru, vede "ragiuni per creà una bicicletta" à u principiu di l'articulu.

Se a mo prima spirienza graphomaniac suscita l'interessu di i lettori, allora in l'articuli seguenti vogliu discrive cumu mandà cumandamenti à l'equipaggiu remotu. Avemu ancu riesciutu à implementà tuttu u schema per i dispositi basati in RouterOS (Mikrotik).

Source: www.habr.com

Add a comment