Fjernovervågning og styring af enheder baseret på Lunix/OpenWrt/Lede gennem port 80…

Hej alle, dette er min første oplevelse på Habr. Jeg vil skrive om, hvordan man ikke-standardmæssigt styrer netværksudstyr i et eksternt netværk. Hvad betyder ikke-standardmæssigt: i de fleste tilfælde, for at styre udstyret i et eksternt netværk, skal du:

  • En offentlig IP-adresse. Eller hvis udstyret er bag en NAT, så en offentlig IP og en "åbnet" port.
  • En tunnel (PPTP/OpenVPN/L2TP+IPSec osv.) til et centralt knudepunkt, som ville være tilgængeligt.

Så derfor vil "min cykel" være nødvendig for dig, når standardmetoderne ikke passer til dig, for eksempel:

  1. Udstyret er bag en NAT, og udover almindelig http (port 80) er alt lukket. En helt normal situation for store nationale virksomhedsnetværk. At åbne porte - kan de, men ikke straks, ikke hurtigt og ikke for dig.
  2. En ustabil og/eller "snæver" kommunikationskanal. Lav hastighed, konstante tab. Smerte og frustration ved forsøg på at organisere en tunnel.
  3. En dyr kommunikationskanal, hvor hver megabyte tæller. For eksempel satellitkommunikation. Plus store forsinkelser og en "snæver" båndbredde.
  4. En situation, hvor du skal "jonglere" med et stort antal små routere, hvor den ene side har OpenWrt/Lede installeret for at udvide mulighederne, mens ressourcerne (hukommelsen) i routeren slet ikke er nok til det hele.

Bemærkning nummer et Men hvad forhindrer dig i at indsætte et "flash-drev" i USB-porten på routeren for at udvide routerens hukommelse?

Ofte er kravene til omkostningerne ved løsningen generelt, men nogle gange spiller formfaktoren også en nøgle rolle. For eksempel, på stedet er der en TP-Link ML3020, dens eneste USB-port bruges til et 2G/3G modem, alt dette er pakket ind i et lille plastikhus og placeret et sted højt oppe (på masten), langt væk (i marken, 30 km fra den nærmeste mobiloperatørs basestation). Ja, du kan sætte et USB-hub i og øge antallet af porte, men erfaringen viser, at det er klodset og usikkert.

Så jeg har forsøgt at beskrive min typiske situation for dig: "et eller andet sted langt væk står der en meget vigtig, ensom og lille router drevet af Linux. Det er vigtigt at vide, at den er "i live" mindst én gang om dagen, og om nødvendigt sende den kommandoer, for eksempel "sol, genstart dig selv!"

Lad os gå videre til implementeringen:

1) På routerens side skal der hvert 5/10/1440 minut eller når som helst sendes en http-anmodning til serveren ved hjælp af wget, resultatet af anmodningen skal gemmes i en fil, filen skal gøres eksekverbar, og derefter skal den eksekveres.

Min cron-linje ser cirka sådan ud:

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

, hvor:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai er domænet for min server. Jeg bemærker straks: ja, man kan også angive en konkret IP-adresse til serveren, det gjorde vi før, indtil vores stat, i sin retfærdige kamp mod noget, jeg ikke ved, lukket for adgangen til størstedelen af "skyderne" DigitalOcean og Amazon. Ved brug af et symbolsk domæne kan du, i tilfælde af et sådant problem, nemt oprette en reserve-sky, omdirigere domænet til det og genoprette overvågning af enheder.

a.php er navnet på scriptet på serverens side. Ja, jeg ved, at det er forkert at navngive variabler og filnavne med en enkelt bogstav... lad os antage, at vi sparer nogle bytes ved at sende anmodningen 🙂
u er brugernavnet, login til enheden
p er adgangskoden
"-O /tmp/wa.sh" er filen på den fjernrouter, hvor serverens svar vil blive gemt, for eksempel kommandoen reboot.

Notat nummer to: Åååh, hvorfor bruger vi wget og ikke curl, da vi med curl kan sende https-anmodninger og ikke kun GET, men også POST? Åååh, fordi som i den gamle anekdote "I krukken går det ikke!". curl indeholder krypteringsbiblioteker på omkring 2 MB, og derfor vil det næppe være muligt for dig at samle et billede til en lille TP-LINK ML3020 for eksempel. Men med wget — ingen problemer.

2) På serverens side (jeg bruger Ubuntu) vil vi bruge Zabbix. Hvorfor: Jeg vil have det til at se flot ud (med grafer) og være praktisk (at sende kommandoer via kontekstmenuen). Zabbix har en så dejlig funktion som zabbix-agent. Gennem agenten vil vi kalde php-scriptet på serveren, som vil returnere information om, hvorvidt vores router har registreret sig i den krævede tidsperiode. For at gemme information om registreringstidspunktet og kommandoer til enheder bruger jeg MySQL, en separat tabel kaldet users med omtrent følgende felter:

		OPRET TABEL `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, // tid for sidste forbindelse
		  `last_ip` varchar(20) NOT NULL, // IP for sidste forbindelse 
		  `last_port` int(11) NOT NULL, // port for sidste forbindelse
		  `task` text NOT NULL, // opgaven routeren modtager
		  `reg_task` varchar(150) NOT NULL, // "regelmæssig" opgave, hvis vi ønsker at opgaven altid udføres ved registrering
		  `last_task` text NOT NULL, // log over opgaver
		  `response` text NOT NULL, // her skrives enhedens svar
		  `seq` int(11) NOT NULL
		) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Alle kilder kan hentes fra Git-repositoriet på adressen: https://github.com/BazDen/iotnet.online.git
Nu php-scripts, der placeres på serversiden (for nemhed kan de placeres i mappen /usr/share/zabbix/):

Fil a.php:

set_charset("utf8");
	// her søger vi efter vores router i databasen
	$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();
		// her sender vi opgaverne til routeren
		echo $task;
		echo "n";
		echo $reg_task;
		// her skriver vi besvarelsestidspunktet og selve routerens svar
		$response_history="[".date("Y-m-d H:i")."] ".$message;
		// opgaven blev sendt, nu skal den slettes, og efter sletning skal vi markere i loggen, at denne opgave er udført
		$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();
		}
		// nu skal vi gemme brugerens registreringstid, hans ip og besked fra ham. Indtil videre kun besked
		$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();
	}
	// hvis vi ikke fandt routeren i vores database, eller dens status er "inaktiv", så vil den ... få sendt kommandoen reboot....
	// Hvorfor så hårdt? Fordi routere nogle gange forsvinder, og det er en lille måde at straffe "de nye ejere" på.
	else
	{
	echo "reboot";
	}
	$sql_users->close();
	?>

Filen agent.php (dette er scriptet for den kaldte zabbix-agent):

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();
	// data exchange occurs through the seq field. When registering, the device sets this field to "1"
	if (($sql_users->num_rows)==1){
		$sql_users->fetch();
		echo $seq;
	}
		
	// resetting $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();
?>		

Og den sidste fase: opskrivning af agenten og tilføjelse af diagrammer.

Hvis du endnu ikke har installeret zabbix-agenten, så:

apt-get install zabbix-agent

Redigerer filen /etc/zabbix/zabbix_agentd.conf.

Tilføjer linjen:

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

, hvor:
test — navnet på vores agent
„php /usr/share/zabbix/agent.php user password“ — det kaldte script med angivelse af enhedens registreringsoplysninger.

Tilføjelse af diagrammer: åbner webgrænsefladen af zabbix, i menuen vælger vi:
Konfiguration -> Netværksnoder -> Opret netværksnode. Her er det tilstrækkeligt at angive navnet på netværksnodet, dens gruppe, standard agent interface:

Fjernovervågning og styring af enheder baseret på Lunix/OpenWrt/Lede gennem port 80…

Nu skal vi for denne netværksnode tilføje et datavar. Bemærk de to felter: „nøgle“ — det er netop den parameter, vi har angivet i filen /etc/zabbix/zabbix_agentd.conf (i vores tilfælde test), og „opdateringsinterval“ — jeg sætter det til 5 minutter, da udstyret også registreres på serveren hver femte minut.

Fjernovervågning og styring af enheder baseret på Lunix/OpenWrt/Lede gennem port 80…

Og så tilføjer vi diagrammet. Jeg anbefaler at vælge „Fyld“ som stil for visualiseringen.

Fjernovervågning og styring af enheder baseret på Lunix/OpenWrt/Lede gennem port 80…

Resultatet bliver noget meget elegant, for eksempel sådan her:

Fjernovervågning og styring af enheder baseret på Lunix/OpenWrt/Lede gennem port 80…

Til det berettigede spørgsmål: „var det værd?“, vil jeg svare: selvfølgelig, se „årsagerne til at skabe cyklen“ i begyndelsen af artiklen.

Hvis min første grafomanske oplevelse vækker interessen hos læserne, ønsker jeg i kommende artikler at beskrive, hvordan man sender kommandoer til fjernudstyr. Jeg har også formået at implementere hele ordningen for enheder baseret på RouterOS (Mikrotik-enheder).

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster