Fernmonitoring und -verwaltung von GerĂ€ten auf Basis von Lunix/OpenWrt/Lede ĂŒber Port 80


Hallo zusammen, das ist meine erste Erfahrung auf HabrĂ©. Ich möchte darĂŒber schreiben, wie man NetzwerkgerĂ€te im externen Netzwerk unkonventionell verwaltet. Was unkonventionell bedeutet: In den meisten FĂ€llen benötigen Sie zur Verwaltung von GerĂ€ten im externen Netzwerk:

  • Eine öffentliche IP-Adresse. Oder, wenn das GerĂ€t hinter einem NAT steht, dann die öffentliche IP und der 'durchgereichte' Port.
  • Einen Tunnel (PPTP/OpenVPN/L2TP+IPSec usw.) zum zentralen Knoten, ĂŒber den der Zugriff möglich wĂ€re.

Deshalb wird 'mein Fahrrad' benötigt, wenn die Standardmethoden nicht funktionieren, zum Beispiel:

  1. Das GerĂ€t befindet sich hinter einem NAT und neben dem ĂŒblichen http (Port 80) ist alles gesperrt. Eine ganz normale Situation fĂŒr große föderale Unternehmensnetze. Ports zu öffnen – das können sie, aber nicht sofort, nicht schnell und nicht fĂŒr Sie.
  2. Eine instabile und/oder 'schmale' Verbindung. Geringe Geschwindigkeit, stÀndige Paketverluste. Schmerz und EnttÀuschung beim Versuch, einen Tunnel zu organisieren.
  3. Ein teurer Kommunikationskanal, wo buchstĂ€blich jedes Megabyte zĂ€hlt. Zum Beispiel Satellitenkommunikation. Dazu kommen große Verzögerungen und eine 'schmale' Bandbreite.
  4. Eine Situation, in der Sie mit einer großen Anzahl kleiner Router jonglieren mĂŒssen, auf denen einerseits OpenWrt/Lede zur Erweiterung der Möglichkeiten installiert ist, andererseits aber der Speicher des Routers bei weitem nicht ausreicht.

Hinweis Nummer eins Was hindert Sie daran, einen USB-Stick in den USB-Port des Routers zu stecken und den Speicher des Routers zu erweitern?

HĂ€ufig sind die Kosten fĂŒr die Gesamtlösung entscheidend, aber manchmal spielt auch der Formfaktor eine SchlĂŒsselrolle. Zum Beispiel gibt es am Standort einen TP-Link ML3020, dessen einziger USB-Port fĂŒr ein 2G/3G-Modem verwendet wird, das alles ist in ein kleines Plast GehĂ€use verpackt und irgendwo hoch (auf einem Mast) und weit weg (im Feld, 30 km von der nĂ€chstgelegenen Mobilfunkbasisstation) platziert. Ja, man könnte einen USB-Hub anschließen und die Anzahl der Ports erweitern, aber die Erfahrung zeigt, dass das unhandlich und unzuverlĂ€ssig ist.

Also, ich habe versucht, Ihnen meine typische Situation zu beschreiben: 'irgendwo weit weg steht ein sehr wichtiger, einsamer und kleiner Router mit Linux. Es ist wichtig, mindestens einmal am Tag zu wissen, dass er "lebt" und bei Bedarf ihm Befehle zu senden, zum Beispiel "Sonnenstrahl, starte neu!"

Kommen wir zur Umsetzung:

1) Auf der Router-Seite sollte alle 5/10/1440 Minuten oder jederzeit ein HTTP-Request an den Server mittels wget gesendet werden. Das Ergebnis der Anfrage wird in einer Datei gespeichert, die Datei wird ausfĂŒhrbar gemacht und dann ausgefĂŒhrt.

Meine Zeile im Cron sieht ungefÀhr so aus:

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

, wo:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai — das ist die Domain meines Servers. Ich merke gleich an: Ja, man kann auch eine spezifische IP-Adresse des Servers angeben. Das haben wir frĂŒher so gemacht, bis unser Staat, in einem heiligen Eifer gegen irgendetwas, das ich nicht kenne — den Zugang zu einem Großteil der „Clouds“ von DigitalOcean und Amazon gesperrt hat. Bei Verwendung einer symbolischen Domain können Sie im Falle eines solchen Vorfalls einfach eine Backup-Cloud erstellen, die Domain umleiten und das Monitoring der GerĂ€te wiederherstellen.

a.php — das ist der Name des Skripts auf der Serverseite. Ja, ich weiß, dass es nicht richtig ist, Variablen und Dateinamen mit einem einzigen Buchstaben zu benennen... ich schlage vor, dass wir dies als ein Mittel betrachten, einige Bytes beim Senden der Anfrage zu sparen 🙂
u — der Benutzername, Login des GerĂ€ts
p — das Passwort
„-O /tmp/wa.sh“ — die Datei auf dem Remote-Router, in der die Antwort des Servers gespeichert wird, zum Beispiel der Befehl reboot.

Hinweis Nummer zwei: Aaaa, warum verwenden wir wget und nicht curl? Schließlich können mit curl HTTPS-Anfragen gesendet werden, und zwar nicht mit GET, sondern mit POST? Aaaa, weil es wie in dem alten Witz ist: „In die Krippe passt es nicht!“ In curl sind VerschlĂŒsselungsbibliotheken von etwa 2 MB enthalten, und deshalb wird es Ihnen wahrscheinlich schwerfallen, ein Image fĂŒr einen kleinen TP-LINK ML3020 zum Beispiel zu erstellen. Mit wget geht das allerdings problemlos.

2) Auf der Serverseite (bei mir ist das Ubuntu) verwenden wir Zabbix. Warum: Ich möchte, dass es schön (mit Grafiken) und praktisch (Befehle ĂŒber das KontextmenĂŒ senden) ist. Zabbix hat so eine wunderbare Funktion, wie den Zabbix-Agent. Über diesen Agenten werden wir ein PHP-Skript aufrufen, Server, welches Informationen darĂŒber zurĂŒckgibt, ob unser Router sich im erforderlichen Zeitraum registriert hat. Zum Speichern der Registrierungsinformationen und der Befehle fĂŒr die GerĂ€te verwende ich MySQL, eine separate Tabelle users mit ungefĂ€hr diesen Feldern:

		ERSTELLE TABELLE `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, // Zeit der letzten Verbindung
		  `last_ip` varchar(20) NOT NULL, // IP der letzten Verbindung 
		  `last_port` int(11) NOT NULL, // Port der letzten Verbindung
		  `task` text NOT NULL, // Aufgabe, die der Router erhÀlt
		  `reg_task` varchar(150) NOT NULL, // "regelmĂ€ĂŸige" Aufgabe, wenn wir möchten, dass die Aufgabe immer bei der Registrierung ausgefĂŒhrt wird
		  `last_task` text NOT NULL, // Log der Aufgaben
		  `response` text NOT NULL, // Hier wird die Antwort des GerÀts geschrieben
		  `seq` int(11) NOT NULL
		) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Alle Quellcodes können aus dem Git-Repository unter folgender Adresse abgerufen werden: https://github.com/BazDen/iotnet.online.git
Jetzt die PHP-Skripte, die auf der Serverseite platziert werden (zur Vereinfachung können sie in den Ordner /usr/share/zabbix/ gelegt werden):

Datei a.php:

set_charset("utf8");
	// hier suchen wir unseren Router in der Datenbanktabelle
	$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();
		// hier senden wir dem Router seine Aufgaben
		echo $task;
		echo "n";
		echo $reg_task;
		// hier schreiben wir die Antwortzeit und die Antwort des Routers
		$response_history="[".date("Y-m-d H:i")."] ".$message;
		// Die Aufgabe wurde gesendet, jetzt mĂŒssen wir sie löschen und in den Logs markieren, dass diese Aufgabe erledigt ist
		$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();
		}
		// Jetzt mĂŒssen wir die Registrierungszeit des Benutzers, seine IP und seine Nachricht speichern. Vorerst nur die Nachricht
		$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();
	}
	// Wenn wir den Router nicht in unserer Datenbank gefunden haben oder sein Status "inaktiv" ist, wird ihm ... der Befehl zum Neustart gesendet.
	// Warum so rigoros? Weil Router manchmal verschwinden, und das ist ein kleiner Weg, um die "neuen Besitzer" zu erziehen.
	else
	{
	echo "reboot";
	}
	$sql_users->close();
	?>

Die Datei agent.php (dies ist das Skript des aufgerufenen zabbix-Agenten):

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();
	// Der Datenaustausch erfolgt ĂŒber das Feld seq. Bei der Registrierung wird dieses Feld auf "1" gesetzt.
	if (($sql_users->num_rows)==1){
		$sql_users->fetch();
		echo $seq;
	}
		
	// Setze $seq auf 0 zurĂŒck.
	$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();
?>		

Und der letzte Schritt: Den Agenten konfigurieren und Grafiken hinzufĂŒgen.

Wenn Sie den Zabbix-Agenten noch nicht installiert haben, dann:

apt-get install zabbix-agent

Bearbeiten Sie die Datei /etc/zabbix/zabbix_agentd.conf.

FĂŒgen Sie die Zeile hinzu:

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

, wo:
test – der Name unseres Agenten
„php /usr/share/zabbix/agent.php user password“ – das aufgerufene Skript mit den Anmeldedaten des GerĂ€ts.

HinzufĂŒgen von Grafiken: Öffnen Sie die WeboberflĂ€che von Zabbix, im MenĂŒ wĂ€hlen Sie:
Einstellungen -> NetzwerkgerĂ€te -> NetzwerkgerĂ€t erstellen. Hier mĂŒssen Sie nur den Namen des NetzwerkgerĂ€ts, seine Gruppe und den Standard-Agenten-Interface angeben:

Fernmonitoring und -verwaltung von GerĂ€ten auf Basis von Lunix/OpenWrt/Lede ĂŒber Port 80


Jetzt mĂŒssen wir fĂŒr dieses NetzwerkgerĂ€t einen Datenelement hinzufĂŒgen. Achten Sie auf zwei Felder: „SchlĂŒssel“ – das ist genau der Parameter, den wir in der Datei /etc/zabbix/zabbix_agentd.conf angegeben haben (in unserem Fall ist es test), und „Aktualisierungsintervall“ – ich setze es auf 5 Minuten, da das GerĂ€t auch alle fĂŒnf Minuten auf dem Server registriert wird.

Fernmonitoring und -verwaltung von GerĂ€ten auf Basis von Lunix/OpenWrt/Lede ĂŒber Port 80


Und dann fĂŒgen wir die Grafik hinzu. Ich empfehle, als Zeichenstil „FĂŒllung“ zu wĂ€hlen.

Fernmonitoring und -verwaltung von GerĂ€ten auf Basis von Lunix/OpenWrt/Lede ĂŒber Port 80


Am Ende ergibt sich etwas sehr PrÀgnantes, zum Beispiel so:

Fernmonitoring und -verwaltung von GerĂ€ten auf Basis von Lunix/OpenWrt/Lede ĂŒber Port 80


Auf die berechtigte Frage: „Hat sich das gelohnt?“, antworte ich: NatĂŒrlich, siehe „GrĂŒnde fĂŒr die Erstellung eines Fahrrads“ zu Beginn des Artikels.

Wenn mein erster grafomanischer Versuch das Interesse der Leser weckt, möchte ich in den nĂ€chsten Artikeln beschreiben, wie man Befehle an entfernte GerĂ€te sendet. Es gelang mir auch, das gesamte Schema fĂŒr GerĂ€te auf Basis von RouterOS (Mikrotik) zu implementieren.

Quelle: habr.com

ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server đŸ”„ ZuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster