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:
- 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.
- Eine instabile und/oder âengeâ Verbindung. Geringe Geschwindigkeit, stĂ€ndige Verluste. Schmerz und EnttĂ€uschung bei dem Versuch, einen Tunnel zu organisieren.
- Ein teurer Kommunikationskanal, bei dem wirklich jedes Megabyte zĂ€hlt. Zum Beispiel Satellitenkommunikation. Dazu kommen groĂe Latenzen und eine âengeâ Bandbreite.
- 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:
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-agentBearbeiten 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:

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.

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

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

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
