Diaľkové monitorovanie a ovládanie zariadení na báze Lunix/OpenWrt/Lede cez port 80…

Ahojte všetci, toto je moja prvá skúsenosť s Habré. Chcem písať o tom, ako spravovať sieťové zariadenia na externej sieti neštandardným spôsobom. Čo znamená neštandardné: vo väčšine prípadov na správu zariadení v externej sieti potrebujete:

  • Verejná IP adresa. No, alebo ak je zariadenie za niečím NAT, potom verejná IP a „preposlaný“ port.
  • Tunel (PPTP/OpenVPN/L2TP+IPSec atď.) do centrálneho uzla, cez ktorý by bol prístupný.

Preto budete potrebovať „môj bicykel“, keď vám nevyhovujú štandardné metódy, napríklad:

  1. Zariadenie je umiestnené za NAT a okrem bežného http (port 80) je všetko uzavreté. Toto je úplne bežná situácia pre veľké federálne podnikové siete. Môžu zaregistrovať porty, ale nie hneď, nie rýchlo a nie pre vás.
  2. Nestabilný a/alebo „úzky“ komunikačný kanál. Nízka rýchlosť, konštantné straty. Bolesť a frustrácia pri pokuse zorganizovať tunel.
  3. Drahý komunikačný kanál, kde sa počíta doslova každý megabajt. Napríklad satelitná komunikácia. Plus dlhé meškania a „úzke“ pásmo.
  4. Situácia, keď potrebujete „žonglovať“ s veľkým počtom malých smerovačov, na ktorých je na jednej strane nainštalovaný OpenWrt/Lede na rozšírenie možností a na druhej strane zdroje (pamäť) smerovača nestačia za všetko.

Všimnite si počet krát Čo vám bráni nainštalovať flash disk do USB portu smerovača a rozšíriť pamäť smerovača?

Požiadavky sa najčastejšie týkajú nákladov na riešenie ako celok, no niekedy hrá kľúčovú úlohu aj faktor tvaru. Na mieste je napríklad TP-Link ML3020, jeho jediný USB port slúži pre 2G/3G modem, to všetko je zabalené v akomsi malom plastovom obale a umiestnené niekde vysoko, vysoko (na stožiari), ďaleko, ďaleko (v poli, 30 km od najbližšej základňovej stanice mobilného operátora). Áno, môžete zapojiť rozbočovač USB a rozšíriť počet portov, ale skúsenosti ukazujú, že je to ťažkopádne a nespoľahlivé.

Pokúsil som sa vám teda opísať moju typickú situáciu: „niekde ďaleko, ďaleko je veľmi dôležitý, osamelý a malý router so systémom Linux. Je dôležité aspoň raz denne vedieť, že je „nažive“ a v prípade potreby sa mu posielajú príkazy, napríklad „zlato, reštartuj!

Prejdime k implementácii:

1) Na strane smerovača, cez cron, každých 5/10/1440 minút, alebo kedykoľvek chcete, musíte poslať http požiadavku na server pomocou wget, uložiť výsledok požiadavky do súboru, urobiť súbor spustiteľným a vykonajte ho.

Môj cron riadok vyzerá asi takto:

Súbor /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

, kde:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai je doména môjho servera. Dovoľte mi hneď poznamenať: áno, môžete zadať konkrétnu IP adresu servera, robili sme to, kým náš štát v spravodlivom impulze boja, poviem, neviem, zablokoval prístup k levovi. podiel „oblakov“ DigitalOcean a Amazon. Ak používate symbolickú doménu, ak k takémuto incidentu dôjde, môžete jednoducho vytvoriť záložný cloud, presmerovať doménu naň a obnoviť monitorovanie zariadenia.

a.php je názov skriptu na strane servera. Áno, viem, že je nesprávne pomenovať premenné a názvy súborov rovnakým písmenom... Navrhujem, aby sme takto ušetrili pár bajtov pri odosielaní požiadavky :)
u - používateľské meno, hardvérové ​​prihlásenie
p - heslo
„-O /tmp/wa.sh“ je súbor na vzdialenom smerovači, do ktorého sa uloží odpoveď servera, napríklad príkaz reboot.

Poznámka číslo dva: Aha, prečo používame wget a nie curl, pretože cez curl môžete posielať https požiadavky nie pomocou GET, ale pomocou POST? Ahhh, pretože ako v starom vtipe „NE lezie do pohára!“ curl obsahuje šifrovacie knižnice s veľkosťou približne 2 MB a preto je nepravdepodobné, že budete môcť zostaviť obrázok napríklad pre malý TP-LINK ML3020. A s wget - prosím.

2) Na strane servera (mám Ubuntu) použijeme Zabbix. Prečo: Chcem, aby to bolo krásne (s grafmi) a pohodlné (odosielanie príkazov cez kontextové menu). Zabbix má takú úžasnú vec, ako je agent zabbix. Cez agenta zavoláme na server PHP skript, ktorý nám vráti informáciu o tom, či sa náš router zaregistroval v požadovanom čase. Na ukladanie informácií o čase registrácie, príkazoch pre zariadenia používam MySQL, samostatnú tabuľku používateľov s približne nasledujúcimi poľami:

		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;

Všetky zdroje si môžete stiahnuť z úložiska Git na adrese: https://github.com/BazDen/iotnet.online.git
Teraz sú skripty PHP umiestnené na strane servera (pre pohodlie ich možno umiestniť do priečinka /usr/share/zabbix/):

súbor 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("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();
	?>

Súbor Agent.php (toto je skript nazývaného agenta zabbix):

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

No, posledná fáza: registrácia agenta a pridanie plánov.

Ak ste ešte nenainštalovali agenta zabbix, potom:

apt-get install zabbix-agent

Upravte súbor /etc/zabbix/zabbix_agentd.conf.

Pridajte riadok:

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

, kde:
test je meno nášho agenta
“php /usr/share/zabbix/agent.php užívateľské heslo” – volaný skript označujúci registračné údaje zariadenia.

Pridávanie grafov: otvorte webové rozhranie zabbix, vyberte z ponuky:
Nastavenia -> Sieťové uzly -> Vytvoriť sieťový uzol. Tu stačí zadať názov hostiteľa siete, jeho skupinu a predvolené rozhranie agenta:

Diaľkové monitorovanie a ovládanie zariadení na báze Lunix/OpenWrt/Lede cez port 80…

Teraz musíme pridať dátový prvok pre tento sieťový uzol. Venujte pozornosť dvom poliam: „key“ - to je presne ten parameter, ktorý sme napísali do súboru /etc/zabbix/zabbix_agentd.conf (v našom prípade je to test) a „interval aktualizácie“ - nastavil som ho na 5 minút , pretože a zariadenie je tiež zaregistrované na serveri raz za päť minút.

Diaľkové monitorovanie a ovládanie zariadení na báze Lunix/OpenWrt/Lede cez port 80…

Nuž, pridajme graf. Ako štýl vykreslenia odporúčam zvoliť „Vyplniť“.

Diaľkové monitorovanie a ovládanie zariadení na báze Lunix/OpenWrt/Lede cez port 80…

Výstup je niečo veľmi lakonické, napríklad takto:

Diaľkové monitorovanie a ovládanie zariadení na báze Lunix/OpenWrt/Lede cez port 80…

Na rozumnú otázku: „stálo to za to?“ odpoviem: no, samozrejme, pozri „dôvody vytvorenia bicykla“ na začiatku článku.

Ak moja prvá grafomanská skúsenosť vzbudí záujem čitateľov, tak v nasledujúcich článkoch chcem popísať, ako posielať príkazy vzdialenému zariadeniu. Podarilo sa nám implementovať celú schému aj pre zariadenia na báze RouterOS (Mikrotik).

Zdroj: hab.com

Pridať komentár