Nuotolinis Lunix/OpenWrt/Lede įrenginių stebėjimas ir valdymas per 80 prievadą…

Sveiki visi, tai mano pirmoji patirtis su Habré. Noriu parašyti apie tai, kaip nestandartiniu būdu valdyti tinklo įrangą išoriniame tinkle. Ką reiškia nestandartinis: daugeliu atvejų norint valdyti įrangą išoriniame tinkle reikia:

  • Viešas IP adresas. Na, arba jei įranga yra už kažkieno NAT, tada viešas IP ir "persiunčiamas" prievadas.
  • Tunelis (PPTP/OpenVPN/L2TP+IPSec ir kt.) į centrinį mazgą, per kurį jis būtų pasiekiamas.

Todėl jums prireiks „mano dviračio“, kai standartiniai metodai jums netinka, pavyzdžiui:

  1. Įranga yra už NAT ir, išskyrus įprastą http (80 prievadas), viskas uždaryta. Tai visiškai įprasta didelių federalinių įmonių tinklų situacija. Jie gali registruoti prievadus, bet ne iš karto, ne greitai ir ne jums.
  2. Nestabilus ir (arba) „siauras“ ryšio kanalas. Mažas greitis, nuolatiniai nuostoliai. Skausmas ir nusivylimas bandant organizuoti tunelį.
  3. Brangus ryšio kanalas, kuriame svarbus kiekvienas megabaitas. Pavyzdžiui, palydovinis ryšys. Be to, ilgas vėlavimas ir „siaura“ juosta.
  4. Situacija, kai reikia „žongliruoti“ daugybe mažų maršrutizatorių, kuriuose, viena vertus, yra įdiegtas OpenWrt/Lede, siekiant išplėsti galimybes, o kita vertus, maršrutizatoriaus resursų (atminties) nepakanka. už viską.

Atkreipkite dėmesį į skaičių kartų Kas neleidžia įdiegti „flash drive“ į maršrutizatoriaus USB prievadą ir išplėsti maršrutizatoriaus atmintį?

Dažniausiai reikalavimai keliami viso sprendimo kainai, tačiau kartais pagrindinį vaidmenį atlieka ir formos faktorius. Pavyzdžiui, svetainėje yra TP-Link ML3020, vienintelis jo USB prievadas naudojamas 2G/3G modemui, visa tai suvyniota į kažkokį mažą plastikinį dėklą ir padėta kažkur aukštai, aukštai (ant stiebo), toli, toli (lauke, 30 km nuo artimiausios mobiliojo ryšio operatoriaus bazinės stoties). Taip, galite prijungti USB šakotuvą ir išplėsti prievadų skaičių, tačiau patirtis rodo, kad tai sudėtinga ir nepatikima.

Taigi, pabandžiau apibūdinti jums savo tipišką situaciją: „kažkur toli, toli, yra labai svarbus, vienišas ir mažas maršrutizatorius, kuriame veikia Linux. Svarbu bent kartą per dieną žinoti, kad jis „gyvas“ ir, jei reikia, jam siunčiamos komandos, pavyzdžiui, „mieloji, perkraukite!

Pereikime prie įgyvendinimo:

1) Maršrutizatoriaus pusėje, per cron, kas 5/10/1440 minučių arba kada norite, turite nusiųsti http užklausą į serverį naudodami wget, išsaugoti užklausos rezultatą faile, padaryti failą vykdomą , ir įvykdykite.

Mano cron linija atrodo maždaug taip:

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

kur:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai yra mano serverio domenas. Iš karto atkreipiu dėmesį: taip, galite nurodyti konkretų serverio IP adresą, mes tai darydavome iki tol, kol mūsų valstybė, teisingu kovos impulsu, pasakysiu, nežinau, užblokavo prieigą prie liūto „DigitalOcean“ ir „Amazon“ „debesų“ dalis. Jei naudojate simbolinį domeną, jei toks incidentas įvyksta, galite lengvai sukurti atsarginį debesį, nukreipti domeną į jį ir atkurti įrenginio stebėjimą.

a.php yra serverio scenarijaus pavadinimas. Taip, žinau, kad negerai kintamuosius ir failų pavadinimus pavadinti ta pačia raide... Siūlau taip sutaupyti kelis baitus siunčiant užklausą :)
u - vartotojo vardas, aparatinės įrangos prisijungimas
p - slaptažodis
„-O /tmp/wa.sh“ yra failas nuotoliniame maršrutizatoriuje, kuriame bus išsaugotas serverio atsakymas, pavyzdžiui, perkrovimo komanda.

Pastaba numeris du: Ahhh, kodėl mes naudojame wget, o ne curl, nes per curl galite siųsti https užklausas ne su GET, o su POST? Ahhh, nes, kaip sename pokšte „NE lipa į stiklainį! curl apima maždaug 2 MB dydžio šifravimo bibliotekas ir dėl to mažai tikėtina, kad galėsite surinkti vaizdą, pavyzdžiui, mažam TP-LINK ML3020. Ir su wget - prašau.

2) Serverio pusėje (turiu Ubuntu) naudosime Zabbix. Kodėl: noriu, kad jis būtų gražus (su grafikais) ir patogus (siųskite komandas per kontekstinį meniu). „Zabbix“ turi tokį nuostabų dalyką kaip „zabbix“ agentas. Per agentą serveryje iškviesime PHP scenarijų, kuris grąžins informaciją apie tai, ar mūsų maršrutizatorius užsiregistravo per reikiamą laikotarpį. Informacijai apie registracijos laiką, įrenginių komandas saugoti naudoju MySQL, atskirą vartotojų lentelę su maždaug tokiais laukais:

		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;

Visus šaltinius galima atsisiųsti iš „Git“ saugyklos adresu: https://github.com/BazDen/iotnet.online.git
Dabar serverio pusėje patalpinti PHP scenarijai (patogumui juos galima įdėti į /usr/share/zabbix/ aplanką):

a.php failas:

<?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 failas (tai yra zabbix agento scenarijus):

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

Na, paskutinis etapas: agento registravimas ir tvarkaraščių pridėjimas.

Jei dar neįdiegėte „zabbix“ agento, tada:

apt-get install zabbix-agent

Redaguokite failą /etc/zabbix/zabbix_agentd.conf.

Pridėkite eilutę:

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

kur:
testas yra mūsų agento vardas
„php /usr/share/zabbix/agent.php vartotojo slaptažodis“ – iškviestas scenarijus, nurodantis įrenginio registracijos duomenis.

Diagramų pridėjimas: atidarykite zabbix žiniatinklio sąsają, meniu pasirinkite:
Nustatymai -> Tinklo mazgai -> Sukurti tinklo mazgą. Čia pakanka nurodyti tinklo pagrindinio kompiuterio pavadinimą, jo grupę ir numatytąją agento sąsają:

Nuotolinis Lunix/OpenWrt/Lede įrenginių stebėjimas ir valdymas per 80 prievadą…

Dabar turime pridėti šio tinklo mazgo duomenų elementą. Atkreipkite dėmesį į du laukus: „raktas“ - būtent tai yra parametras, kurį įrašėme faile /etc/zabbix/zabbix_agentd.conf (mūsų atveju tai yra testas), ir „atnaujinimo intervalas“ - nustatau jį į 5 minutes. , nes ir įranga taip pat registruojama serveryje kartą per penkias minutes.

Nuotolinis Lunix/OpenWrt/Lede įrenginių stebėjimas ir valdymas per 80 prievadą…

Na, pridėkime grafiką. Rekomenduoju kaip atvaizdavimo stilių pasirinkti „Užpildyti“.

Nuotolinis Lunix/OpenWrt/Lede įrenginių stebėjimas ir valdymas per 80 prievadą…

Išvestis yra kažkas labai lakoniško, pavyzdžiui:

Nuotolinis Lunix/OpenWrt/Lede įrenginių stebėjimas ir valdymas per 80 prievadą…

Į pagrįstą klausimą: „ar buvo verta?“, atsakysiu: na, žinoma, žiūrėkite straipsnio pradžioje „dviračio sukūrimo priežastis“.

Jei mano pirmoji grafomaniška patirtis sukelia skaitytojų susidomėjimą, tai tolesniuose straipsniuose noriu aprašyti, kaip siųsti komandas į nuotolinę įrangą. Mums taip pat pavyko įdiegti visą schemą įrenginiams, pagrįstiems „RouterOS“ („Mikrotik“).

Šaltinis: www.habr.com

Добавить комментарий