Lunix/OpenWrt/Lede alapú eszközök távfelügyelete és vezérlése a 80-as porton keresztül…

Üdv mindenkinek, ez az első élményem a Habréval kapcsolatban. Arról szeretnék írni, hogyan lehet külső hálózaton nem szabványos módon kezelni a hálózati berendezéseket. Mit jelent a nem szabványos: a legtöbb esetben a külső hálózaton lévő berendezések kezeléséhez szüksége van:

  • Nyilvános IP-cím. Nos, vagy ha valaki NAT-ja mögött van a berendezés, akkor egy nyilvános IP és egy "továbbított" port.
  • Alagút (PPTP/OpenVPN/L2TP+IPSec stb.) ahhoz a központi csomóponthoz, amelyen keresztül elérhető lenne.

Ezért szüksége lesz az „én kerékpáromra”, amikor a szokásos módszerek nem felelnek meg Önnek, például:

  1. A berendezés a NAT mögött található, és a szokásos http (80-as port) kivételével minden zárva van. Ez teljesen normális helyzet a nagy szövetségi vállalati hálózatoknál. Regisztrálhatnak portokat, de nem azonnal, nem gyorsan és nem neked.
  2. Instabil és/vagy „szűk” kommunikációs csatorna. Alacsony sebesség, állandó veszteségek. Fájdalom és frusztráció az alagút megszervezése közben.
  3. Drága kommunikációs csatorna, ahol szó szerint minden megabájt számít. Például a műholdas kommunikáció. Plusz hosszú késések és „szűk” sáv.
  4. Olyan helyzet, amikor nagyszámú kis routerrel kell „zsonglőrködni”, amelyekre egyrészt OpenWrt/Lede van telepítve a képességek bővítéséhez, másrészt a router erőforrásai (memóriája) nem elegendőek. mindenért.

Jegyezze fel az idők számát Mi akadályozza meg, hogy flash meghajtót telepítsen az útválasztó USB-portjába, és bővítse a router memóriáját?

Leggyakrabban a megoldás egészének költségére vonatkoznak a követelmények, de néha a formai tényező is kulcsszerepet játszik. Például van a telephelyen egy TP-Link ML3020, ennek egyetlen USB portja 2G/3G modem, mindezt valami kis műanyag tokba csomagolva valahol magasan, magasan (az árbocra) helyezzük, messze, messze (terepen, 30 km-re a legközelebbi mobilszolgáltató bázisállomásától). Igen, csatlakoztathat USB-hubot, és bővítheti a portok számát, de a tapasztalat azt mutatja, hogy ez nehézkes és megbízhatatlan.

Tehát megpróbáltam leírni önnek az én tipikus helyzetemet: „valahol messze, messze van egy nagyon fontos, magányos és kicsi router, amely Linuxot futtat. Fontos, hogy naponta legalább egyszer tudja, hogy „él”, és ha szükséges, parancsokat küldenek neki, például: „Drágám, indítsd újra!”

Térjünk át a megvalósításra:

1) Router oldalon cron-on keresztül 5/10/1440 percenként, vagy amikor akarod, http kérést kell küldeni a szervernek wget segítségével, a kérés eredményét fájlba kell menteni, a fájlt futtathatóvá kell tenni , és hajtsa végre.

A cron sorom valahogy így néz ki:

/etc/crontabs/root fájl:

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

, ahol:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai a szerverem tartománya. Rögtön megjegyzem: igen, megadhat egy konkrét IP-címet a szervernek, ezt addig csináltuk, amíg az állapotunk, egy jogos harci késztetésben, mondom, nem tudom, letiltotta a hozzáférést az oroszlánhoz. részesedése a DigitalOcean és az Amazon „felhőkből”. Ha szimbolikus tartományt használ, ha ilyen incidens történik, könnyen létrehozhat egy biztonsági mentési felhőt, átirányíthatja a tartományt arra, és visszaállíthatja az eszközfigyelést.

az a.php a szerveroldali szkript neve. Igen, tudom, hogy rossz a változókat és a fájlneveket ugyanazzal a betűvel elnevezni... Azt javaslom, hogy így kérés elküldésekor spóroljunk meg pár bájtot :)
u - felhasználónév, hardveres bejelentkezés
p - jelszó
A „-O /tmp/wa.sh” egy fájl a távoli útválasztón, amelybe a szerver válasza, például az újraindítási parancs mentésre kerül.

Második megjegyzés: Ááá, miért használjuk a wget-et és nem a curl-t, mert curl-en keresztül nem GET-tel, hanem POST-tal lehet https kéréseket küldeni? Ahhh, mert ahogy a régi viccben „NE mászik a korsóba!” A curl körülbelül 2 MB méretű titkosítási könyvtárakat tartalmaz, és emiatt nem valószínű, hogy például egy kis TP-LINK ML3020-hoz képes lesz képet összeállítani. És wget-tel – kérem.

2) A szerver oldalon (Ubuntu van) a Zabbix-ot fogjuk használni. Miért? Azt szeretném, hogy szép legyen (grafikonokkal) és kényelmes legyen (parancsok küldése a helyi menün keresztül). A Zabbixnak van egy olyan csodálatos dolga, mint a zabbix ügynök. Az ügynökön keresztül egy PHP-szkriptet fogunk meghívni a szerveren, amely információkat ad vissza arról, hogy a routerünk regisztrált-e a kívánt időtartam alatt. A regisztrációs időre vonatkozó információk, az eszközök parancsaival kapcsolatos információk tárolására a MySQL-t használom, amely egy különálló táblázat a felhasználók számára, körülbelül a következő mezőkkel:

		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;

Az összes forrás letölthető a Git tárházából a következő címen: https://github.com/BazDen/iotnet.online.git
Most a szerver oldalon elhelyezett PHP szkriptek (a kényelem kedvéért a /usr/share/zabbix/ mappába is elhelyezhetők):

a.php fájl:

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

Agent.php fájl (ez a zabbix ügynök szkriptje):

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

Nos, az utolsó szakasz: ügynök regisztrálása és ütemezések hozzáadása.

Ha még nem telepítette a zabbix ügynököt, akkor:

apt-get install zabbix-agent

Szerkessze az /etc/zabbix/zabbix_agentd.conf fájlt.

Add hozzá a sort:

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

, ahol:
test az ügynökünk neve
„php /usr/share/zabbix/agent.php felhasználói jelszó” - egy hívott szkript, amely jelzi az eszköz regisztrációs adatait.

Diagramok hozzáadása: nyissa meg a zabbix webes felületét, válassza ki a menüből:
Beállítások -> Hálózati csomópontok -> Hálózati csomópont létrehozása. Itt elegendő megadni a hálózati gazdagép nevét, csoportját és az alapértelmezett ügynöki felületet:

Lunix/OpenWrt/Lede alapú eszközök távfelügyelete és vezérlése a 80-as porton keresztül…

Most hozzá kell adnunk egy adatelemet ehhez a hálózati csomóponthoz. Ügyeljen két mezőre: „kulcs” - pontosan ezt a paramétert írtuk be az /etc/zabbix/zabbix_agentd.conf fájlba (esetünkben ez teszt), és a „frissítési intervallum” - 5 percre állítottam be. , mert és a berendezés is regisztrálva van a szerveren XNUMX percenként egyszer.

Lunix/OpenWrt/Lede alapú eszközök távfelügyelete és vezérlése a 80-as porton keresztül…

Nos, adjunk hozzá egy grafikont. Azt javaslom, hogy válassza ki a „Kitöltés” ​​megjelenítési stílust.

Lunix/OpenWrt/Lede alapú eszközök távfelügyelete és vezérlése a 80-as porton keresztül…

A kimenet valami nagyon lakonikus, például így:

Lunix/OpenWrt/Lede alapú eszközök távfelügyelete és vezérlése a 80-as porton keresztül…

Az ésszerű kérdésre: „megérte?”, azt válaszolom: hát persze, lásd a „kerékpár létrehozásának okait” a cikk elején.

Ha az első grafomán tapasztalatom felkeltette az olvasók érdeklődését, akkor a következő cikkekben szeretném leírni, hogyan lehet parancsokat küldeni távoli berendezésekre. Sikerült megvalósítanunk a teljes sémát a RouterOS (Mikrotik) alapú eszközökön is.

Forrás: will.com

Hozzászólás