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


Hallo zusammen, dies ist meine erste Erfahrung auf Habra. 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 der GerĂ€te im externen Netzwerk:

  • Eine öffentliche IP-Adresse. Oder, falls das GerĂ€t hinter einer NAT ist, dann eine öffentliche IP und ein „freigegebener“ Port.
  • Einen Tunnel (PPTP/OpenVPN/L2TP+IPSec usw.) zum zentralen Knoten, ĂŒber den der Zugang möglich wĂ€re.

Deshalb werden Sie „mein Fahrrad“ benötigen, wenn die Standardmethoden fĂŒr Sie nicht geeignet sind, zum Beispiel:

  1. Das GerĂ€t befindet sich hinter einer NAT und außer dem normalen HTTP (Port 80) ist alles gesperrt. Eine ganz normale Situation in großen bundesweiten Unternehmensnetzen. Ports freizuschalten ist möglich, aber nicht sofort, nicht schnell und nicht fĂŒr Sie.
  2. Eine instabile und/oder „enge“ Verbindung. Geringe Geschwindigkeit, stĂ€ndige Verluste. Schmerz und EnttĂ€uschung bei dem Versuch, einen Tunnel zu organisieren.
  3. Ein teurer Kommunikationskanal, bei dem wirklich jedes Megabyte zĂ€hlt. Zum Beispiel Satellitenkommunikation. Dazu kommen große Latenzen und eine „enge“ Bandbreite.
  4. Die Situation, in der man mit einer Vielzahl kleiner Router jonglieren muss, die auf der einen Seite OpenWrt/Lede zur Erweiterung der Möglichkeiten installiert haben, auf der anderen Seite aber nicht genĂŒgend Speicherressourcen bieten.

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

In der Regel sind die Kosten fĂŒr die gesamte Lösung ausschlaggebend, aber manchmal spielt auch der Formfaktor eine entscheidende Rolle. Zum Beispiel steht an einem Standort der TP-Link ML3020, dessen einzelner USB-Port fĂŒr ein 2G/3G-Modem verwendet wird. Das Ganze ist in ein kleines KunststoffgehĂ€use verpackt und befindet sich hoch oben (auf einem Mast), weit weg (im Feld, 30 km von der nĂ€chsten Mobilfunkbasisstation). Ja, man könnte einen USB-Hub anschließen, um die Anzahl der Ports zu erweitern, aber die Erfahrung zeigt, dass dies klobig und unzuverlĂ€ssig ist.

Ich habe versucht, Ihnen meine typische Situation zu schildern: „Irgendwo weit weg steht ein sehr wichtiger, einsamer und kleiner Router, der mit Linux betrieben wird. Es ist wichtig, mindestens einmal tĂ€glich zu wissen, dass er ‚lebendig‘ ist, und gegebenenfalls Befehle zu senden, zum Beispiel ‚Sonnenschein, starte neu!‘

Kommen wir nun zur Umsetzung:

1) Auf der Router-Seite sollte ein http-Request mittels wget alle 5/10/1440 Minuten oder nach Bedarf gesendet werden. Das Ergebnis des Requests wird in einer Datei gespeichert, die ausfĂŒhrbar gemacht wird, und anschließend ausgefĂŒhrt.

Mein cron-Eintrag 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

, wobei:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai — die Domain meines Servers. Ich möchte gleich bemerken: Ja, es ist auch möglich, eine bestimmte IP-Adresse des Servers anzugeben. Das haben wir frĂŒher gemacht, bis unser Staat im gerechter Kampf gegen ungewisse Gefahren den Zugang zu einem Großteil der „Clouds“ von DigitalOcean und Amazon sperrte. Bei Verwendung einer symbolischen Domain haben Sie im Falle eines solchen Vorfalls die Möglichkeit, eine Ersatz-Cloud hochzufahren, die Domain dorthin umzuleiten und das Monitoring wiederherzustellen.

a.php — der Name des Skripts auf der Serverseite. Ja, ich weiß, dass es nicht korrekt ist, Variablen und Dateinamen mit einem Buchstaben zu benennen
 betrachten wir es als eine Möglichkeit, einige Bytes beim Senden der Anfrage zu sparen 🙂
u — der Benutzername, Login des GerĂ€ts
p — das Passwort
„-O /tmp/wa.sh“ — eine Datei auf dem entfernten Router, in der die Antwort des Servers gespeichert wird, beispielsweise der Befehl reboot.

Hinweis Nummer zwei: Aaaa, warum verwenden wir wget und nicht curl, obwohl curl https-Anfragen und nicht nur GET, sondern auch POST senden kann? Aaaa, weil es wie in dem alten Witz ist: „In die KrĂŒge passen keine NĂŒsse!“. Curl enthĂ€lt etwa 2 MB große VerschlĂŒsselungsbibliotheken, und es wird schwierig sein, ein Image fĂŒr einen kleinen TP-LINK ML3020 zusammenzustellen. Mit wget hingegen ist das kein Problem.

2) Auf der Serverseite (bei mir ist das Ubuntu) verwenden wir Zabbix. Warum: Ich möchte, dass es schön aussieht (mit Grafiken) und bequem ist (Befehle ĂŒber das KontextmenĂŒ zu senden). Zabbix hat so eine wunderbare Funktion namens zabbix-agent. Über den Agenten werden wir ein PHP-Skript aufrufen Server, das Informationen darĂŒber zurĂŒckgibt, ob unser Router im erforderlichen Zeitraum registriert wurde. Zur Speicherung von Informationen ĂŒber den Registrierungszeitpunkt und die Befehle fĂŒr die GerĂ€te verwende ich MySQL, eine separate Tabelle users mit ungefĂ€hr folgenden Feldern:

		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, // Zeitpunkt der letzten Verbindung
		  `last_ip` varchar(20) NOT NULL, // IP-Adresse 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, // "regulĂ€re" Aufgabe, falls 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 vom Git-Repository unter folgender Adresse abgerufen werden: https://github.com/BazDen/iotnet.online.git
Jetzt die PHP-Skripte, die auf der Serverseite abgelegt werden (zum besseren Überblick 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 notieren wir die Antwortzeit und die Antwort des Routers
		$response_history="[".date("Y-m-d H:i")."] ".$message;
		// Die Aufgabe wurde gesendet, nun muss sie gelöscht werden, und nach dem Löschen in den Logs vermerkt werden, dass diese Aufgabe erledigt wurde
		$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. ZunĂ€chst 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 reboot... gesendet.
	// Warum so drastisch? Weil Router manchmal verschwinden und dies eine kleine Methode ist, um die "neuen Besitzer" zu bestrafen.
	else
	{
	echo "reboot";
	}
	$sql_users->close();
?>

Die Datei agent.php (dies ist das Skript des aufgerufenen Zabbix-Agents):

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 setzt das GerĂ€t dieses Feld auf "1"
	if (($sql_users->num_rows)==1){
		$sql_users->fetch();
		echo $seq;
	}
		
	// Setze $seq 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: Registrierung des Agents und HinzufĂŒgen der Grafiken.

Falls Sie den Zabbix-Agent noch nicht installiert haben:

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

, wobei:
test – der Name unseres Agents
„php /usr/share/zabbix/agent.php Benutzer Passwort“ — das Skript, das mit den Anmeldedaten des GerĂ€ts aufgerufen wird.

Diagramme hinzufĂŒgen: Öffnen Sie die Web-OberflĂ€che von Zabbix, und wĂ€hlen Sie im MenĂŒ:
Einstellungen -> NetzwerkgerÀte -> NetzwerkgerÀt erstellen. Hier reicht es, den Namen des NetzwerkgerÀts, seine Gruppe und die Standard-Agenten-Schnittstelle anzugeben:

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


Jetzt mĂŒssen wir fĂŒr dieses NetzwerkgerĂ€t ein Datenelement hinzufĂŒgen. Beachten Sie die beiden Felder: „SchlĂŒssel“ — das ist der Parameter, den wir in der Datei /etc/zabbix/zabbix_agentd.conf eingetragen haben (in unserem Fall ist das test), und „Aktualisierungsintervall“ — ich setze es auf 5 Minuten, da die GerĂ€te auch nur alle fĂŒnf Minuten auf dem Server registriert werden.

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


Und dann fĂŒgen wir das Diagramm hinzu. Ich empfehle, den Stil „FĂŒllen“ zu wĂ€hlen.

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


Am Ende erhalten wir etwas sehr PrÀgnantes, zum Beispiel so:

FernĂŒberwachung 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, schauen Sie sich die „GrĂŒnde fĂŒr die Erfindung des Fahrrads“ am Anfang des Artikels an.

Falls mein erster grafomanischer Versuch das Interesse der Leser weckt, möchte ich in den folgenden 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) umzusetzen.

Quelle: habr.com

Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server đŸ”„ Kaufen Sie zuverlĂ€ssiges Hosting fĂŒr Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster