Fora monitorado kaj kontrolo de aparatoj bazitaj sur Lunix/OpenWrt/Lede per haveno 80...

Saluton al ĉiuj, ĉi tio estas mia unua sperto ĉe Habré. Mi volas skribi pri kiel administri retajn ekipaĵojn en ekstera reto en nenorma maniero. Kion signifas ne-norma: plejofte, por administri ekipaĵon en ekstera reto vi bezonas:

  • Publika IP-adreso. Nu, aŭ se la ekipaĵo estas malantaŭ ies NAT, tiam publika IP kaj "plusendita" haveno.
  • Tunelo (PPTP/OpenVPN/L2TP+IPSec, ktp.) al la centra nodo tra kiu ĝi estus alirebla.

Tial vi bezonos "mia biciklo" kiam normaj metodoj ne konvenas al vi, ekzemple:

  1. La ekipaĵo situas malantaŭ NAT kaj, krom la kutima http (haveno 80), ĉio estas fermita. Ĉi tio estas tute normala situacio por grandaj federaciaj kompaniaj retoj. Ili povas registri havenojn, sed ne tuj, ne rapide, kaj ne por vi.
  2. Malstabila kaj/aŭ "mallarĝa" komunika kanalo. Malalta rapido, konstantaj perdoj. Doloro kaj frustriĝo kiam vi provas organizi tunelon.
  3. Multkosta komunika kanalo, kie laŭvorte ĉiu megabajto kalkulas. Ekzemple, satelitaj komunikadoj. Plus longaj prokrastoj kaj "mallarĝa" bando.
  4. Situacio, kiam vi bezonas "ĵongligi" grandan nombron da malgrandaj enkursigiloj, sur kiuj, unuflanke, OpenWrt/Lede estas instalita por pligrandigi kapablojn, kaj aliflanke, la rimedoj (memoro) de la enkursigilo ne sufiĉas. por ĉio.

Notu nombron fojojn Kio malhelpas vin instali poŝmemorilon en la USB-havenon de la enkursigilo kaj vastigi la memoron de la enkursigilo?

Plej ofte, la postuloj estas por la kosto de la solvo entute, sed foje la formo-faktoro ankaŭ ludas ŝlosilan rolon. Ekzemple, estas TP-Link ML3020 ĉe la retejo, ĝia nura USB-haveno estas uzata por modemo 2G/3G, ĉio ĉi estas envolvita en ia malgranda plasta ujo kaj metita ie alte, alte (sur la masto), malproksime, malproksime (en kampo, 30 km de la plej proksima poŝtelefona bazstacio). Jes, vi povas enŝovi USB-nabon kaj pligrandigi la nombron da havenoj, sed sperto montras, ke ĉi tio estas maloportuna kaj nefidinda.

Do, mi provis priskribi al vi mian tipan situacion: “ie malproksime, malproksime, estas tre grava, soleca kaj malgranda enkursigilo, kiu funkcias Linukso. Gravas scii almenaŭ unufoje tage, ke li estas "viva" kaj, se necese, ordonoj estas senditaj al li, ekzemple "kara, rekomencu!"

Ni transiru al la efektivigo:

1) Ĉe la enkursigilo, per cron, ĉiujn 5/10/1440 minutojn, aŭ kiam ajn vi volas, vi devas sendi http-peton al la servilo uzante wget, konservi la rezulton de la peto al dosiero, fari la dosieron plenumebla. , kaj ekzekuti ĝin.

Mia cron-linio aspektas kiel ĉi tio:

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

, kie:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai estas la domajno de mia servilo. Mi tuj rimarku: jes, vi povas specifi specifan IP-adreson de la servilo, ni kutimis fari tion ĝis nia stato, en justa impulso de lukto, mi diros, mi ne scias, blokis aliron al la leona. parto de la DigitalOcean kaj Amazon "nuboj". Se vi uzas simbolan domajnon, se tia okazaĵo okazas, vi povas facile levi rezervan nubon, redirekti la domajnon al ĝi kaj restarigi aparaton.

a.php estas la nomo de la servilflanka skripto. Jes, mi scias, ke estas malĝuste nomi variablojn kaj dosiernomojn per la sama litero... Mi sugestas, ke tiel ni ŝparu kelkajn bajtojn dum sendo de peto :)
u - uzantnomo, aparataro ensaluto
p - pasvorto
"-O /tmp/wa.sh" estas dosiero sur la fora enkursigilo, kie la servila respondo, ekzemple la rekomenca komando, estos konservita.

Noto numero du: Ahhh, kial ni uzas wget kaj ne curl, ĉar per curl oni povas sendi https-petojn ne per GET, sed per POST? Ahhh ĉar, kiel en la malnova ŝerco "NE grimpas en la kruĉon!" buklo inkluzivas ĉifrajn bibliotekojn de ĉirkaŭ 2MB en grandeco, kaj pro tio estas neverŝajne ke vi povos kunmeti bildon por malgranda TP-LINK ML3020, ekzemple. Kaj kun wget - mi petas.

2) Ĉe la servilo (mi havas Ubuntu) ni uzos Zabbix. Kial: Mi volas, ke ĝi estu bela (kun grafikaĵoj) kaj oportuna (sendu komandojn per la kunteksta menuo). Zabbix havas tian mirindan aferon kiel la zabbix-agento. Per la agento, ni vokos PHP-skripton sur la servilo, kiu resendos informojn pri ĉu nia enkursigilo registriĝis dum la bezonata tempodaŭro. Por konservi informojn pri registra tempo, komandojn por aparatoj, mi uzas MySQL, apartan tabelon de uzantoj kun proksimume la sekvaj kampoj:

		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;

Ĉiuj fontoj povas esti elŝutitaj de la Git-deponejo ĉe: https://github.com/BazDen/iotnet.online.git
Nun PHP-skriptoj estas metitaj ĉe la servilo (por komforto, ili povas esti metitaj en la dosierujon /usr/share/zabbix/):

a.php dosiero:

<?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-dosiero (ĉi tio estas la skripto de la zabbix-agento nomata):

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

Nu, la fina etapo: registri agenton kaj aldoni horarojn.

Se vi ankoraŭ ne instalis la zabbix-agenton, tiam:

apt-get install zabbix-agent

Redaktu la dosieron /etc/zabbix/zabbix_agentd.conf.

Aldonu la linion:

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

, kie:
testo estas la nomo de nia agento
"php /usr/share/zabbix/agent.php uzantpasvorto" - nomita skripto indikanta la registraddatenojn de la aparato.

Aldonante leterojn: malfermu la retan interfacon zabbix, elektu el la menuo:
Agordoj -> Retaj nodoj -> Krei retan nodon. Ĉi tie sufiĉas specifi la nomon de la retgastiganto, ĝia grupo kaj la defaŭlta agentinterfaco:

Fora monitorado kaj kontrolo de aparatoj bazitaj sur Lunix/OpenWrt/Lede per haveno 80...

Nun ni devas aldoni datuman elementon por ĉi tiu retnodo. Atentu du kampojn: "ŝlosilo" - ĉi tio estas ĝuste la parametro, kiun ni skribis en la dosiero /etc/zabbix/zabbix_agentd.conf (en nia kazo ĝi estas testo), kaj "ĝisdatiga intervalo" - mi fiksis ĝin al 5 minutoj. , ĉar kaj la ekipaĵo ankaŭ estas registrita sur la servilo unufoje ĉiujn kvin minutojn.

Fora monitorado kaj kontrolo de aparatoj bazitaj sur Lunix/OpenWrt/Lede per haveno 80...

Nu, ni aldonu grafeon. Mi rekomendas elekti "Plenigu" kiel bildigan stilon.

Fora monitorado kaj kontrolo de aparatoj bazitaj sur Lunix/OpenWrt/Lede per haveno 80...

La eligo estas io tre lakona, ekzemple kiel ĉi tio:

Fora monitorado kaj kontrolo de aparatoj bazitaj sur Lunix/OpenWrt/Lede per haveno 80...

Al la racia demando: "ĉu valoris?", mi respondos: nu, kompreneble, vidu "kialoj por krei biciklon" komence de la artikolo.

Se mia unua grafomania sperto vekas la intereson de legantoj, tiam en la sekvaj artikoloj mi volas priskribi kiel sendi komandojn al malproksimaj ekipaĵoj. Ni ankaŭ sukcesis efektivigi la tutan skemon por aparatoj bazitaj sur RouterOS (Mikrotik).

fonto: www.habr.com

Aldoni komenton