Afstandmonitering en beheer van Lunix/OpenWrt/Lede-gebaseerde toestelle via poort 80...

Hallo almal, dit is my eerste ervaring op Habré. Ek wil skryf oor hoe om netwerktoerusting op 'n eksterne netwerk op 'n nie-standaard manier te bestuur. Wat beteken nie-standaard: in die meeste gevalle benodig jy om toerusting op 'n eksterne netwerk te bestuur:

  • Openbare IP-adres. Wel, of as die toerusting agter iemand se NAT is, dan 'n openbare IP en 'n "aangestuurde" poort.
  • Tonnel (PPTP/OpenVPN/L2TP+IPSec, ens.) na die sentrale nodus waardeur dit toeganklik sou wees.

Daarom sal jy "my fiets" nodig hê wanneer standaardmetodes jou nie pas nie, byvoorbeeld:

  1. Die toerusting is agter NAT geleë en, behalwe vir die gewone http (poort 80), is alles toe. Dit is 'n heeltemal normale situasie vir groot federale korporatiewe netwerke. Hulle kan poorte registreer, maar nie dadelik nie, nie vinnig nie, en nie vir jou nie.
  2. Onstabiele en/of "smal" kommunikasiekanaal. Lae spoed, konstante verliese. Pyn en frustrasie wanneer jy probeer om 'n tonnel te organiseer.
  3. ’n Duur kommunikasiekanaal, waar letterlik elke megagreep tel. Byvoorbeeld, satellietkommunikasie. Plus lang vertragings en 'n "smal" band.
  4. 'n Situasie wanneer jy 'n groot aantal klein routers moet "jongleer", waarop, aan die een kant, OpenWrt/Lede geïnstalleer is om vermoëns uit te brei, en aan die ander kant, die hulpbronne (geheue) van die router is nie genoeg nie vir alles.

Let op aantal kere Wat verhoed jou om 'n flash drive in die roeteerder se USB-poort te installeer en die roeteerder se geheue uit te brei?

Meestal is die vereistes vir die koste van die oplossing as geheel, maar soms speel die vormfaktor ook 'n sleutelrol. Byvoorbeeld, daar is 'n TP-Link ML3020 op die terrein, sy enigste USB-poort word gebruik vir 'n 2G/3G-modem, dit alles is in 'n soort klein plastiekhouer toegedraai en iewers hoog, hoog (op die mas) geplaas, ver, ver weg (in die veld, 30 km vanaf die naaste selfoonoperateurbasisstasie). Ja, jy kan 'n USB-hub inprop en die aantal poorte uitbrei, maar ervaring wys dat dit omslagtig en onbetroubaar is.

So, ek het probeer om my tipiese situasie vir jou te beskryf: "iewers ver, ver weg, is daar 'n baie belangrike, eensame en klein router wat Linux bestuur. Dit is belangrik om ten minste een keer per dag te weet dat hy "lewend" is en, indien nodig, word opdragte aan hom gestuur, byvoorbeeld, "Liefie, herlaai!"

Kom ons gaan aan na die implementering:

1) Aan die routerkant, via cron, elke 5/10/1440 minute, of wanneer jy wil, moet jy 'n http-versoek na die bediener stuur met behulp van wget, stoor die resultaat van die versoek in 'n lêer, maak die lêer uitvoerbaar , en voer dit uit.

My cron-lyn lyk so:

Lêer /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

waar:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai is die domein van my bediener. Laat ek dadelik daarop let: ja, jy kan 'n spesifieke IP-adres van die bediener spesifiseer, ons het dit vroeër gedoen totdat ons staat, in 'n regverdige impuls van stryd, ek sal sê, ek weet nie, toegang tot die leeu se deel van die DigitalOcean en Amazon "wolke". As jy 'n simboliese domein gebruik, as so 'n voorval plaasvind, kan jy maklik 'n rugsteunwolk oprig, die domein na dit herlei en toestelmonitering herstel.

a.php is die naam van die bedienerkant-skrip. Ja, ek weet dat dit verkeerd is om veranderlikes en lêername met dieselfde letter te noem... Ek stel voor dat ons so 'n paar grepe spaar wanneer ons 'n versoek stuur :)
u - gebruikersnaam, hardeware-aanmelding
p - wagwoord
“-O /tmp/wa.sh” is 'n lêer op die afgeleë router waar die bedienerantwoord, byvoorbeeld die herlaai-opdrag, gestoor sal word.

Nota nommer twee: Ahhh, hoekom gebruik ons ​​wget en nie curl nie, want via curl kan jy https-versoeke stuur nie met GET nie, maar met POST? Ahhh want, soos in die ou grappie "NE klim in die pot!" curl bevat enkripsiebiblioteke van ongeveer 2MB groot en daarom is dit onwaarskynlik dat jy byvoorbeeld 'n prent vir 'n klein TP-LINK ML3020 sal kan saamstel. En met wget - asseblief.

2) Aan die bedienerkant (ek het Ubuntu) sal ons Zabbix gebruik. Hoekom: Ek wil hê dit moet pragtig wees (met grafieke) en gerieflik (stuur opdragte via die kontekskieslys). Zabbix het so 'n wonderlike ding soos die zabbix-agent. Deur die agent sal ons 'n PHP-skrip op die bediener oproep, wat inligting sal gee oor of ons router gedurende die vereiste tydperk geregistreer is. Om inligting oor registrasietyd, opdragte vir toestelle te stoor, gebruik ek MySQL, 'n aparte tabelgebruikers met ongeveer die volgende velde:

		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;

Alle bronne kan van die Git-bewaarplek afgelaai word by: https://github.com/BazDen/iotnet.online.git
Nou word PHP-skrifte aan die bedienerkant geplaas (geriefshalwe kan dit in die /usr/share/zabbix/-lêergids geplaas word):

a.php lêer:

<?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 lêer (dit is die script van die zabbix agent genoem):

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

Wel, die finale stadium: registrasie van 'n agent en byvoeging van skedules.

As jy nog nie die zabbix-agent geïnstalleer het nie, dan:

apt-get install zabbix-agent

Wysig die lêer /etc/zabbix/zabbix_agentd.conf.

Voeg die reël by:

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

waar:
toets is die naam van ons agent
"php /usr/share/zabbix/agent.php gebruikerswagwoord" - 'n opgeroep skrip wat die toestelregistrasiedata aandui.

Voeg kaarte by: maak die zabbix-webkoppelvlak oop, kies uit die spyskaart:
Instellings -> Netwerknodes -> Skep 'n netwerknodus. Hier is dit genoeg om die naam van die netwerkgasheer, sy groep en die verstekagentkoppelvlak te spesifiseer:

Afstandmonitering en beheer van Lunix/OpenWrt/Lede-gebaseerde toestelle via poort 80...

Nou moet ons 'n data-element vir hierdie netwerknodus byvoeg. Gee aandag aan twee velde: "sleutel" - dit is presies die parameter wat ons in die /etc/zabbix/zabbix_agentd.conf-lêer geskryf het (in ons geval is dit toets), en "opdateringsinterval" - ek stel dit op 5 minute , want en die toerusting word ook een keer elke vyf minute op die bediener geregistreer.

Afstandmonitering en beheer van Lunix/OpenWrt/Lede-gebaseerde toestelle via poort 80...

Wel, kom ons voeg 'n grafiek by. Ek beveel aan om "Vul" as die weergawestyl te kies.

Afstandmonitering en beheer van Lunix/OpenWrt/Lede-gebaseerde toestelle via poort 80...

Die uitset is iets baie lakonies, byvoorbeeld soos volg:

Afstandmonitering en beheer van Lunix/OpenWrt/Lede-gebaseerde toestelle via poort 80...

Op die redelike vraag: "was dit die moeite werd?", sal ek antwoord: wel, natuurlik, sien "redes om 'n fiets te skep" aan die begin van die artikel.

As my eerste grafomaniese ervaring die belangstelling van lesers wek, dan wil ek in die volgende artikels beskryf hoe om opdragte na afgeleë toerusting te stuur. Ons het ook daarin geslaag om die hele skema vir toestelle gebaseer op RouterOS (Mikrotik) te implementeer.

Bron: will.com

Voeg 'n opmerking