Daljinsko praćenje i kontrola Lunix/OpenWrt/Lede uređaja preko porta 80…

Pozdrav svima, ovo je moje prvo iskustvo na Habréu. Želim pisati o tome kako upravljati mrežnom opremom na vanjskoj mreži na nestandardan način. Šta znači nestandardno: u većini slučajeva za upravljanje opremom na vanjskoj mreži potrebno vam je:

  • Javna IP adresa. Pa, ili ako oprema stoji iza nečijeg NAT-a, onda javni IP i "proslijeđeni" port.
  • Tunel (PPTP/OpenVPN/L2TP+IPSec, itd.) do centralnog čvora kroz koji bi mu se moglo pristupiti.

Stoga će vam trebati "moj bicikl" kada vam standardne metode ne odgovaraju, na primjer:

  1. Oprema se nalazi iza NAT-a i osim uobičajenog http (port 80) sve je zatvoreno. Ovo je sasvim normalna situacija za velike federalne korporativne mreže. Oni mogu registrovati portove, ali ne odmah, ne brzo i ne za vas.
  2. Nestabilan i/ili “uzak” kanal komunikacije. Mala brzina, konstantni gubici. Bol i frustracija pri pokušaju organiziranja tunela.
  3. Skup komunikacijski kanal, gdje je bukvalno svaki megabajt bitan. Na primjer, satelitske komunikacije. Plus duga kašnjenja i "uski" opseg.
  4. Situacija kada je potrebno "žonglirati" velikim brojem malih rutera, na kojima je, s jedne strane, instaliran OpenWrt/Lede radi proširenja mogućnosti, a s druge strane resursi (memorija) rutera nisu dovoljni za sve.

Zabilježite broj puta Šta vas sprečava da instalirate fleš disk u USB port rutera i proširite memoriju rutera?

Najčešće su zahtjevi za cijenu rješenja u cjelini, ali ponekad i faktor oblika igra ključnu ulogu. Na primjer, na lokaciji se nalazi TP-Link ML3020, njegov jedini USB port se koristi za 2G/3G modem, sve je to umotano u nekakvu malu plastičnu kutiju i postavljeno negdje visoko, visoko (na jarbol), daleko, daleko (na terenu, 30 km od bazne stanice najbližeg mobilnog operatera). Da, možete priključiti USB čvorište i proširiti broj portova, ali iskustvo pokazuje da je to glomazno i ​​nepouzdano.

Dakle, pokušao sam da vam opišem svoju tipičnu situaciju: „negdje daleko, daleko, postoji vrlo važan, usamljen i mali ruter na kojem radi Linux. Važno je barem jednom dnevno znati da je "živ" i, ako je potrebno, šalju mu se komande, na primjer, "dušo, ponovno pokreni!"

Pređimo na implementaciju:

1) Na strani rutera, preko cron-a, svakih 5/10/1440 minuta, ili kad god želite, trebate poslati http zahtjev serveru koristeći wget, sačuvati rezultat zahtjeva u datoteku, učiniti datoteku izvršnom , i izvršite ga.

Moja cron linija izgleda otprilike ovako:

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

gdje:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai je domen mog servera. Odmah da napomenem: da, možete odrediti određenu IP adresu servera, to smo radili sve dok naša država, u pravednom nagonu borbe, reći ću, ne znam, nije blokirala pristup lavovskom udio DigitalOcean i Amazon “oblaka”. Ako koristite simboličku domenu, ako dođe do takvog incidenta, lako možete podići backup oblak, preusmjeriti domenu na njega i vratiti praćenje uređaja.

a.php je ime skripte na strani servera. Da, znam da je pogrešno imenovati varijable i nazive fajlova istim slovom... Predlažem da na ovaj način uštedimo nekoliko bajtova prilikom slanja zahteva :)
u - korisničko ime, hardverska prijava
p - lozinka
“-O /tmp/wa.sh” je datoteka na udaljenom ruteru gdje će se pohraniti odgovor servera, na primjer naredba za ponovno pokretanje.

Napomena broj dva: Ahhh, zašto koristimo wget, a ne curl, jer preko curl-a možete slati https zahtjeve ne sa GET-om, već sa POST-om? Ahhh jer, kao u starom vicu "NE se penje u teglu!" curl uključuje biblioteke za enkripciju veličine oko 2MB i zbog toga je malo vjerovatno da ćete moći sastaviti sliku za mali TP-LINK ML3020, na primjer. A sa wgetom - molim.

2) Na strani servera (imam Ubuntu) koristićemo Zabbix. Zašto: želim da bude prelepo (sa grafikonima) i praktično (šalji komande preko kontekstnog menija). Zabbix ima tako divnu stvar kao što je zabbix agent. Preko agenta ćemo na serveru pozvati PHP skriptu koja će vratiti informaciju o tome da li se naš ruter registrovao u potrebnom vremenskom periodu. Za pohranjivanje informacija o vremenu registracije, komandama za uređaje koristim MySQL, zasebnu tabelu korisnika sa otprilike sljedećim poljima:

		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;

Svi izvori se mogu preuzeti iz Git repozitorija na: https://github.com/BazDen/iotnet.online.git
Sada su PHP skripte postavljene na strani servera (radi pogodnosti, mogu se postaviti u /usr/share/zabbix/ folder):

a.php fajl:

<?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 fajl (ovo je skripta zabbix agenta):

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

Pa, zadnja faza: registracija agenta i dodavanje rasporeda.

Ako još niste instalirali zabbix agenta, tada:

apt-get install zabbix-agent

Uredite datoteku /etc/zabbix/zabbix_agentd.conf.

Dodajte liniju:

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

gdje:
test je ime našeg agenta
“php /usr/share/zabbix/agent.php korisnička lozinka” - pozvana skripta koja označava podatke o registraciji uređaja.

Dodavanje grafikona: otvorite zabbix web sučelje, odaberite iz menija:
Postavke -> Mrežni čvorovi -> Kreiraj mrežni čvor. Ovdje je dovoljno navesti ime mrežnog hosta, njegovu grupu i zadani interfejs agenta:

Daljinsko praćenje i kontrola Lunix/OpenWrt/Lede uređaja preko porta 80…

Sada moramo dodati element podataka za ovaj mrežni čvor. Obratite pažnju na dva polja: "ključ" - to je upravo parametar koji smo napisali u /etc/zabbix/zabbix_agentd.conf fajl (u našem slučaju to je test), i "interval ažuriranja" - postavio sam ga na 5 minuta , jer se i oprema registruje na serveru svakih pet minuta.

Daljinsko praćenje i kontrola Lunix/OpenWrt/Lede uređaja preko porta 80…

Pa, dodajmo graf. Preporučujem da odaberete "Fill" kao stil prikazivanja.

Daljinsko praćenje i kontrola Lunix/OpenWrt/Lede uređaja preko porta 80…

Izlaz je nešto vrlo lakonski, na primjer ovako:

Daljinsko praćenje i kontrola Lunix/OpenWrt/Lede uređaja preko porta 80…

Na razumno pitanje: "je li se isplatilo?", odgovorit ću: pa, naravno, pogledajte "razloge za stvaranje bicikla" na početku članka.

Ako moje prvo grafomansko iskustvo izazove zanimanje čitatelja, onda u sljedećim člancima želim opisati kako slati komande udaljenoj opremi. Također smo uspjeli implementirati cijelu shemu za uređaje bazirane na RouterOS-u (Mikrotik).

izvor: www.habr.com

Dodajte komentar