Oddaljeno spremljanje in upravljanje naprav, ki temeljijo na Lunix/OpenWrt/Lede preko porta 80…

Pozdravljeni vsi, to je moja prva izkušnja s Habréjem. Želim pisati o tem, kako upravljati omrežno opremo v zunanjem omrežju na nestandarden način. Kaj pomeni nestandardno: v večini primerov za upravljanje opreme v zunanjem omrežju potrebujete:

  • Javni naslov IP. No, ali če je oprema za nečijim NAT, potem javni IP in "posredovana" vrata.
  • Tunel (PPTP/OpenVPN/L2TP+IPSec itd.) do centralnega vozlišča, preko katerega bi bil dostopen.

Zato boste potrebovali "moje kolo", ko vam standardne metode ne ustrezajo, na primer:

  1. Oprema se nahaja za NAT in razen običajnega http (vrata 80) je vse zaprto. To je povsem običajna situacija za velika zvezna korporativna omrežja. Lahko registrirajo vrata, vendar ne takoj, ne hitro in ne za vas.
  2. Nestabilen in/ali "ozek" komunikacijski kanal. Nizka hitrost, stalne izgube. Bolečina in razočaranje pri poskusu organiziranja tunela.
  3. Drag komunikacijski kanal, kjer šteje dobesedno vsak megabajt. Na primer, satelitske komunikacije. Plus dolge zamude in "ozek" pas.
  4. Situacija, ko morate "žonglirati" z velikim številom majhnih usmerjevalnikov, na katerih je po eni strani nameščen OpenWrt/Lede za razširitev zmogljivosti, po drugi strani pa viri (pomnilnik) usmerjevalnika niso dovolj. za vse.

Opomba število krat Kaj vam preprečuje namestitev bliskovnega pogona v vrata USB usmerjevalnika in razširitev pomnilnika usmerjevalnika?

Najpogosteje se zahteve nanašajo na ceno rešitve kot celote, včasih pa igra ključno vlogo tudi faktor oblike. Na primer, na mestu je TP-Link ML3020, njegov edini USB priključek se uporablja za 2G/3G modem, vse to je zavito v nekakšno majhno plastično ohišje in postavljeno nekje visoko, visoko (na jambor), daleč, daleč (na terenu, 30 km od najbližje bazne postaje mobilnega operaterja). Da, lahko priključite zvezdišče USB in povečate število vrat, vendar izkušnje kažejo, da je to okorno in nezanesljivo.

Tako sem vam poskušal opisati svojo tipično situacijo: »nekje daleč, daleč stran je zelo pomemben, osamljen in majhen usmerjevalnik, ki poganja Linux. Pomembno je, da vsaj enkrat na dan veste, da je "živ" in po potrebi se mu pošljejo ukazi, na primer "ljubi, znova zaženi!"

Pojdimo k izvedbi:

1) Na strani usmerjevalnika, prek crona, vsakih 5/10/1440 minut ali kadar koli želite, morate poslati http zahtevo strežniku z uporabo wget, shraniti rezultat zahteve v datoteko, narediti datoteko izvršljivo , in ga izvedite.

Moja linija cron je videti nekako takole:

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

, kjer:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai je domena mojega strežnika. Naj takoj opozorim: da, lahko določite določen IP naslov strežnika, to smo počeli, dokler naša država v pravičnem impulzu boja, bom rekel, ne vem, blokirala dostop do levjega delež "oblakov" DigitalOcean in Amazon. Če uporabljate simbolično domeno, lahko v primeru takšnega incidenta preprosto ustvarite rezervni oblak, preusmerite domeno nanj in obnovite nadzor naprave.

a.php je ime skripta na strani strežnika. Ja, vem, da je napačno poimenovati spremenljivke in imena datotek z isto črko... Predlagam, da na ta način prihranimo nekaj bajtov pri pošiljanju povpraševanja :)
u - uporabniško ime, strojna prijava
p - geslo
»-O /tmp/wa.sh« je datoteka na oddaljenem usmerjevalniku, kamor bo shranjen odziv strežnika, na primer ukaz za ponovni zagon.

Opomba številka dve: Ahhh, zakaj uporabljamo wget in ne curl, ker prek curla lahko pošljete https zahteve ne z GET, ampak s POST? Ahhh, ker kot v stari šali "NE zleze v kozarec!" curl vključuje šifrirne knjižnice velikosti približno 2 MB in zaradi tega je malo verjetno, da boste na primer lahko sestavili sliko za majhen TP-LINK ML3020. In z wget - prosim.

2) Na strani strežnika (imam Ubuntu) bomo uporabili Zabbix. Zakaj: želim, da je lepo (z grafi) in priročno (pošiljanje ukazov prek kontekstnega menija). Zabbix ima tako čudovito stvar, kot je agent zabbix. Preko agenta bomo na strežniku priklicali PHP skripto, ki nam bo vrnila informacijo ali se je naš usmerjevalnik registriral v zahtevanem časovnem obdobju. Za shranjevanje informacij o času registracije, ukazih za naprave, uporabljam MySQL, ločeno tabelo uporabnikov s približno naslednjimi polji:

		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;

Vse vire je mogoče prenesti iz repozitorija Git na: https://github.com/BazDen/iotnet.online.git
Zdaj so skripti PHP nameščeni na strani strežnika (za udobje jih lahko postavite v mapo /usr/share/zabbix/):

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

Datoteka Agent.php (to je skript agenta zabbix, imenovan):

<?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, zadnja faza: registracija agenta in dodajanje urnikov.

Če še niste namestili agenta zabbix, potem:

apt-get install zabbix-agent

Uredite datoteko /etc/zabbix/zabbix_agentd.conf.

Dodajte vrstico:

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

, kjer:
test je ime našega agenta
“php /usr/share/zabbix/agent.php uporabniško geslo” - klicani skript, ki označuje podatke o registraciji naprave.

Dodajanje grafikonov: odprite spletni vmesnik zabbix, v meniju izberite:
Nastavitve -> Omrežna vozlišča -> Ustvari omrežno vozlišče. Tukaj je dovolj, da določite ime omrežnega gostitelja, njegovo skupino in privzeti agentski vmesnik:

Oddaljeno spremljanje in upravljanje naprav, ki temeljijo na Lunix/OpenWrt/Lede preko porta 80…

Zdaj moramo dodati podatkovni element za to omrežno vozlišče. Bodite pozorni na dve polji: “key” - to je točno tisti parameter, ki smo ga zapisali v datoteko /etc/zabbix/zabbix_agentd.conf (v našem primeru je test) in “interval posodabljanja” - nastavil sem ga na 5 minut , saj je oprema tudi registrirana na strežniku enkrat na pet minut.

Oddaljeno spremljanje in upravljanje naprav, ki temeljijo na Lunix/OpenWrt/Lede preko porta 80…

No, dodajmo graf. Priporočam, da kot slog upodabljanja izberete »Fill«.

Oddaljeno spremljanje in upravljanje naprav, ki temeljijo na Lunix/OpenWrt/Lede preko porta 80…

Rezultat je nekaj zelo jedrnatega, na primer tako:

Oddaljeno spremljanje in upravljanje naprav, ki temeljijo na Lunix/OpenWrt/Lede preko porta 80…

Na razumno vprašanje: "ali je bilo vredno?" Bom odgovoril: no, seveda, glejte "razloge za ustvarjanje kolesa" na začetku članka.

Če moja prva grafomanska izkušnja vzbudi zanimanje bralcev, potem želim v naslednjih člankih opisati, kako pošiljati ukaze oddaljeni opremi. Celotno shemo smo uspeli implementirati tudi za naprave, ki temeljijo na RouterOS (Mikrotik).

Vir: www.habr.com

Dodaj komentar