Vzdálené monitorování a ovládání zařízení na bázi Lunix/OpenWrt/Lede přes port 80…

Ahoj všichni, toto je moje první zkušenost s Habré. Chci psát o tom, jak nestandardně spravovat síťové zařízení na externí síti. Co znamená nestandardní: ve většině případů ke správě zařízení v externí síti potřebujete:

  • Veřejná IP adresa. No, nebo pokud je zařízení za něčí NAT, pak veřejnou IP a „předaný“ port.
  • Tunel (PPTP/OpenVPN/L2TP+IPSec atd.) k centrálnímu uzlu, přes který by byl přístupný.

Proto budete potřebovat „moje kolo“, když vám nevyhovují standardní metody, například:

  1. Zařízení je umístěno za NATem a kromě obvyklého http (port 80) je vše uzavřeno. To je zcela normální situace pro velké federální podnikové sítě. Mohou registrovat porty, ale ne hned, ne rychle a ne pro vás.
  2. Nestabilní a/nebo „úzký“ komunikační kanál. Nízká rychlost, konstantní ztráty. Bolest a frustrace při pokusu zorganizovat tunel.
  3. Drahý komunikační kanál, kde se počítá doslova každý megabajt. Například satelitní komunikace. Plus dlouhé zpoždění a „úzké“ pásmo.
  4. Situace, kdy potřebujete „žonglovat“ s velkým množstvím malých routerů, na kterých je na jedné straně nainstalován OpenWrt/Lede pro rozšíření schopností a na druhé straně nestačí prostředky (paměť) routeru za všechno.

Poznamenejte si počet krát Co vám brání nainstalovat flash disk do USB portu routeru a rozšířit tak paměť routeru?

Nejčastěji se jedná o požadavky na cenu řešení jako celku, ale někdy hraje klíčovou roli i faktor tvaru. Na místě je například TP-Link ML3020, jeho jediný USB port slouží pro 2G/3G modem, to vše je zabaleno do jakéhosi malého plastového pouzdra a umístěno někde vysoko, vysoko (na stožáru), daleko, daleko (v poli, 30 km od nejbližší základní stanice mobilního operátora). Ano, můžete zapojit rozbočovač USB a rozšířit počet portů, ale zkušenosti ukazují, že je to těžkopádné a nespolehlivé.

Pokusil jsem se vám tedy popsat svou typickou situaci: „Někde daleko, daleko je velmi důležitý, osamělý a malý router s Linuxem. Je důležité alespoň jednou denně vědět, že je „naživu“ a v případě potřeby jsou mu posílány příkazy, například „zlato, restartuj!“

Pojďme k implementaci:

1) Na straně routeru, přes cron, každých 5/10/1440 minut, nebo kdykoli chcete, musíte poslat http požadavek na server pomocí wget, uložit výsledek požadavku do souboru, udělat soubor spustitelným a provést jej.

Moje cron linka vypadá nějak takto:

Soubor /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ého serveru. Dovolte mi hned poznamenat: ano, můžete zadat konkrétní IP adresu serveru, to jsme dělali, dokud náš stát, ve spravedlivém impulsu boje, řeknu, nevím, zablokoval přístup k lvím podíl „mraků“ DigitalOcean a Amazon. Pokud používáte symbolickou doménu, pokud k takovému incidentu dojde, můžete snadno vytvořit zálohovací cloud, přesměrovat doménu na něj a obnovit monitorování zařízení.

a.php je název skriptu na straně serveru. Ano, vím, že je špatné pojmenovávat proměnné a názvy souborů stejným písmenem... Navrhuji, abychom takto ušetřili pár bajtů při odesílání požadavku :)
u - uživatelské jméno, přihlášení k hardwaru
p - heslo
„-O /tmp/wa.sh“ je soubor na vzdáleném routeru, kam se uloží odpověď serveru, například příkaz reboot.

Poznámka číslo dvě: Aha, proč používáme wget a ne curl, protože přes curl můžete odesílat požadavky https ne pomocí GET, ale pomocí POST? Ahhh, protože jako ve starém vtipu „NE leze do sklenice!“ curl obsahuje šifrovací knihovny o velikosti asi 2 MB, a proto je nepravděpodobné, že budete schopni sestavit obraz například pro malý TP-LINK ML3020. A s wget - prosím.

2) Na straně serveru (mám Ubuntu) použijeme Zabbix. Proč: Chci, aby to bylo krásné (s grafy) a pohodlné (posílání příkazů přes kontextové menu). Zabbix má tak úžasnou věc, jako je agent zabbix. Prostřednictvím agenta zavoláme na server PHP skript, který vrátí informaci o tom, zda se náš router zaregistroval během požadované doby. K ukládání informací o čase registrace, příkazech pro zařízení používám MySQL, samostatnou tabulku uživatelů s přibližně následujícími poli:

		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šechny zdroje lze stáhnout z úložiště Git na adrese: https://github.com/BazDen/iotnet.online.git
Nyní PHP skripty umístěné na straně serveru (pro pohodlí je lze umístit do složky /usr/share/zabbix/):

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

Soubor Agent.php (toto je skript nazývaný agent 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áze: registrace agenta a přidání rozvrhů.

Pokud jste ještě nenainstalovali agenta zabbix, pak:

apt-get install zabbix-agent

Upravte soubor /etc/zabbix/zabbix_agentd.conf.

Přidejte řádek:

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

, kde:
test je jméno našeho agenta
“php /usr/share/zabbix/agent.php uživatelské heslo” – volaný skript indikující registrační data zařízení.

Přidání grafů: otevřete webové rozhraní zabbix, vyberte z nabídky:
Nastavení -> Síťové uzly -> Vytvořit síťový uzel. Zde stačí zadat název síťového hostitele, jeho skupinu a výchozí rozhraní agenta:

Vzdálené monitorování a ovládání zařízení na bázi Lunix/OpenWrt/Lede přes port 80…

Nyní musíme přidat datový prvek pro tento síťový uzel. Věnujte pozornost dvěma polím: „key“ - to je přesně ten parametr, který jsme napsali do souboru /etc/zabbix/zabbix_agentd.conf (v našem případě je to test), a „interval aktualizace“ - nastavil jsem ho na 5 minut , protože a zařízení je také registrováno na serveru jednou za pět minut.

Vzdálené monitorování a ovládání zařízení na bázi Lunix/OpenWrt/Lede přes port 80…

No, přidáme graf. Jako styl vykreslení doporučuji zvolit „Vyplnit“.

Vzdálené monitorování a ovládání zařízení na bázi Lunix/OpenWrt/Lede přes port 80…

Výstup je něco velmi lakonického, například takto:

Vzdálené monitorování a ovládání zařízení na bázi Lunix/OpenWrt/Lede přes port 80…

Na rozumnou otázku: „stálo to za to?“, odpovím: no, samozřejmě, viz „důvody pro vytvoření kola“ na začátku článku.

Pokud moje první grafomanská zkušenost vzbudí zájem čtenářů, pak chci v následujících článcích popsat, jak posílat příkazy vzdáleným zařízením. Podařilo se také implementovat celé schéma pro zařízení na bázi RouterOS (Mikrotik).

Zdroj: www.habr.com

Přidat komentář