Απομακρυσμένη παρακολούθηση και έλεγχος συσκευών που βασίζονται σε Lunix/OpenWrt/Lede μέσω της θύρας 80…

Γεια σε όλους, αυτή είναι η πρώτη μου εμπειρία στο Habré. Θέλω να γράψω για το πώς να διαχειρίζομαι τον εξοπλισμό δικτύου σε ένα εξωτερικό δίκτυο με μη τυπικό τρόπο. Τι σημαίνει μη τυπικό: στις περισσότερες περιπτώσεις, για τη διαχείριση εξοπλισμού σε εξωτερικό δίκτυο χρειάζεστε:

  • Δημόσια διεύθυνση IP. Λοιπόν, ή εάν ο εξοπλισμός βρίσκεται πίσω από το NAT κάποιου, τότε μια δημόσια IP και μια "προωθημένη" θύρα.
  • Σήραγγα (PPTP/OpenVPN/L2TP+IPSec, κ.λπ.) στον κεντρικό κόμβο μέσω του οποίου θα ήταν προσβάσιμο.

Επομένως, θα χρειαστείτε το "my bike" όταν οι τυπικές μέθοδοι δεν σας ταιριάζουν, για παράδειγμα:

  1. Ο εξοπλισμός βρίσκεται πίσω από το NAT και, εκτός από το συνηθισμένο http (θύρα 80), όλα είναι κλειστά. Αυτή είναι μια απολύτως φυσιολογική κατάσταση για μεγάλα ομοσπονδιακά εταιρικά δίκτυα. Μπορούν να καταχωρήσουν θύρες, αλλά όχι αμέσως, όχι γρήγορα και όχι για εσάς.
  2. Ασταθής και/ή «στενός» δίαυλος επικοινωνίας. Χαμηλή ταχύτητα, σταθερές απώλειες. Πόνος και απογοήτευση όταν προσπαθείτε να οργανώσετε ένα τούνελ.
  3. Ένα ακριβό κανάλι επικοινωνίας, όπου κυριολεκτικά κάθε megabyte μετράει. Για παράδειγμα, δορυφορικές επικοινωνίες. Συν μεγάλες καθυστερήσεις και μια «στενή» μπάντα.
  4. Μια κατάσταση κατά την οποία πρέπει να "ζυγκλάρετε" μεγάλο αριθμό μικρών δρομολογητών, στους οποίους, αφενός, είναι εγκατεστημένο το OpenWrt/Lede για επέκταση των δυνατοτήτων και, αφετέρου, οι πόροι (μνήμη) του δρομολογητή δεν επαρκούν για όλα.

Σημειώστε αριθμούς φορές Τι σας εμποδίζει να εγκαταστήσετε μια μονάδα flash στη θύρα USB του δρομολογητή και να επεκτείνετε τη μνήμη του δρομολογητή;

Τις περισσότερες φορές, οι απαιτήσεις αφορούν το κόστος της λύσης στο σύνολό της, αλλά μερικές φορές ο παράγοντας μορφής παίζει επίσης βασικό ρόλο. Για παράδειγμα, υπάρχει ένα TP-Link ML3020 στην τοποθεσία, η μοναδική του θύρα USB χρησιμοποιείται για ένα μόντεμ 2G/3G, όλα αυτά είναι τυλιγμένα σε κάποιο είδος μικρής πλαστικής θήκης και τοποθετημένα κάπου ψηλά, ψηλά (στον ιστό), μακριά, πολύ μακριά (στο πεδίο, 30 km από τον πλησιέστερο σταθμό βάσης παρόχου κινητής τηλεφωνίας). Ναι, μπορείτε να συνδέσετε έναν διανομέα USB και να επεκτείνετε τον αριθμό των θυρών, αλλά η εμπειρία δείχνει ότι αυτό είναι δυσκίνητο και αναξιόπιστο.

Έτσι, προσπάθησα να σας περιγράψω την τυπική μου κατάσταση: «κάπου μακριά, πολύ μακριά, υπάρχει ένας πολύ σημαντικός, μοναχικός και μικρός δρομολογητής που τρέχει Linux. Είναι σημαντικό να γνωρίζετε τουλάχιστον μία φορά την ημέρα ότι είναι "ζωντανό" και, εάν είναι απαραίτητο, του στέλνονται εντολές, για παράδειγμα, "αγάπη μου, επανεκκίνηση!"

Ας προχωρήσουμε στην υλοποίηση:

1) Στην πλευρά του δρομολογητή, μέσω cron, κάθε 5/10/1440 λεπτά ή όποτε θέλετε, πρέπει να στείλετε ένα αίτημα http στον διακομιστή χρησιμοποιώντας το wget, να αποθηκεύσετε το αποτέλεσμα του αιτήματος σε ένα αρχείο, να κάνετε το αρχείο εκτελέσιμο , και εκτελέστε το.

Η γραμμή cron μου μοιάζει κάπως έτσι:

Αρχείο /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

, όπου:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai είναι ο τομέας του διακομιστή μου. Επιτρέψτε μου να σημειώσω αμέσως: ναι, μπορείτε να καθορίσετε μια συγκεκριμένη διεύθυνση IP του διακομιστή, το κάναμε μέχρι που το κράτος μας, σε μια δίκαιη παρόρμηση αγώνα, θα πω, δεν ξέρω, απέκλεισε την πρόσβαση στο λιοντάρι μερίδιο των «σύννεφων» DigitalOcean και Amazon. Εάν χρησιμοποιείτε έναν συμβολικό τομέα, εάν συμβεί ένα τέτοιο περιστατικό, μπορείτε εύκολα να δημιουργήσετε ένα εφεδρικό σύννεφο, να ανακατευθύνετε τον τομέα σε αυτόν και να επαναφέρετε την παρακολούθηση της συσκευής.

a.php είναι το όνομα του σεναρίου από την πλευρά του διακομιστή. Ναι, ξέρω ότι είναι λάθος να ονομάζουμε μεταβλητές και ονόματα αρχείων με το ίδιο γράμμα... Προτείνω έτσι να αποθηκεύσουμε μερικά byte κατά την αποστολή ενός αιτήματος :)
u - όνομα χρήστη, σύνδεση υλικού
p - κωδικός πρόσβασης
Το "-O /tmp/wa.sh" είναι ένα αρχείο στον απομακρυσμένο δρομολογητή όπου θα αποθηκευτεί η απάντηση διακομιστή, για παράδειγμα η εντολή επανεκκίνησης.

Σημείωση νούμερο δύο: Αχχ, γιατί χρησιμοποιούμε wget και όχι curl, γιατί μέσω του curl μπορείς να στείλεις αιτήματα https όχι με GET, αλλά με POST; Αχχ γιατί, όπως στο παλιό αστείο «το ΝΕ ανεβαίνει στο βάζο!» Το curl περιλαμβάνει βιβλιοθήκες κρυπτογράφησης μεγέθους περίπου 2 MB και εξαιτίας αυτού είναι απίθανο να μπορέσετε να συναρμολογήσετε μια εικόνα για ένα μικρό TP-LINK ML3020, για παράδειγμα. Και με wget - παρακαλώ.

2) Από την πλευρά του διακομιστή (έχω Ubuntu) θα χρησιμοποιήσουμε το Zabbix. Γιατί: Θέλω να είναι όμορφο (με γραφήματα) και βολικό (αποστολή εντολών μέσω του μενού περιβάλλοντος). Το Zabbix έχει ένα υπέροχο πράγμα όπως ο πράκτορας zabbix. Μέσω του πράκτορα, θα καλέσουμε ένα σενάριο PHP στον διακομιστή, το οποίο θα επιστρέψει πληροφορίες σχετικά με το εάν ο δρομολογητής μας εγγράφηκε κατά την απαιτούμενη χρονική περίοδο. Για να αποθηκεύσω πληροφορίες σχετικά με το χρόνο εγγραφής, εντολές για συσκευές, χρησιμοποιώ το MySQL, έναν ξεχωριστό πίνακα χρηστών με περίπου τα ακόλουθα πεδία:

		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;

Όλες οι πηγές μπορούν να ληφθούν από το αποθετήριο Git στη διεύθυνση: https://github.com/BazDen/iotnet.online.git
Τώρα τα σενάρια PHP τοποθετούνται στην πλευρά του διακομιστή (για ευκολία, μπορούν να τοποθετηθούν στο φάκελο /usr/share/zabbix/):

αρχείο a.php:

<?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 (αυτό είναι το σενάριο του πράκτορα zabbix που ονομάζεται):

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

Λοιπόν, το τελικό στάδιο: εγγραφή ενός πράκτορα και προσθήκη χρονοδιαγραμμάτων.

Εάν δεν έχετε εγκαταστήσει ακόμη τον παράγοντα zabbix, τότε:

apt-get install zabbix-agent

Επεξεργαστείτε το αρχείο /etc/zabbix/zabbix_agentd.conf.

Προσθέστε τη γραμμή:

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

, όπου:
test είναι το όνομα του αντιπροσώπου μας
"php /usr/share/zabbix/agent.php κωδικός πρόσβασης χρήστη" - ένα καλούμενο σενάριο που υποδεικνύει τα δεδομένα εγγραφής της συσκευής.

Προσθήκη γραφημάτων: ανοίξτε τη διεπαφή ιστού zabbix, επιλέξτε από το μενού:
Ρυθμίσεις -> Κόμβοι δικτύου -> Δημιουργία κόμβου δικτύου. Εδώ αρκεί να καθορίσετε το όνομα του κεντρικού υπολογιστή δικτύου, την ομάδα του και την προεπιλεγμένη διεπαφή πράκτορα:

Απομακρυσμένη παρακολούθηση και έλεγχος συσκευών που βασίζονται σε Lunix/OpenWrt/Lede μέσω της θύρας 80…

Τώρα πρέπει να προσθέσουμε ένα στοιχείο δεδομένων για αυτόν τον κόμβο δικτύου. Δώστε προσοχή σε δύο πεδία: "κλειδί" - αυτή είναι ακριβώς η παράμετρος που γράψαμε στο αρχείο /etc/zabbix/zabbix_agentd.conf (στην περίπτωσή μας είναι δοκιμή) και "διάστημα ενημέρωσης" - το έβαλα σε 5 λεπτά , γιατί και ο εξοπλισμός καταχωρείται επίσης στον διακομιστή μία φορά κάθε πέντε λεπτά.

Απομακρυσμένη παρακολούθηση και έλεγχος συσκευών που βασίζονται σε Lunix/OpenWrt/Lede μέσω της θύρας 80…

Λοιπόν, ας προσθέσουμε ένα γράφημα. Προτείνω να επιλέξετε "Γέμισμα" ως στυλ απόδοσης.

Απομακρυσμένη παρακολούθηση και έλεγχος συσκευών που βασίζονται σε Lunix/OpenWrt/Lede μέσω της θύρας 80…

Η έξοδος είναι κάτι πολύ λακωνικό, για παράδειγμα όπως αυτό:

Απομακρυσμένη παρακολούθηση και έλεγχος συσκευών που βασίζονται σε Lunix/OpenWrt/Lede μέσω της θύρας 80…

Στην εύλογη ερώτηση: «άξιζε τον κόπο;», θα απαντήσω: καλά, φυσικά, δείτε τους «λόγους για τη δημιουργία ενός ποδηλάτου» στην αρχή του άρθρου.

Εάν η πρώτη μου γραφομανική εμπειρία προκαλεί το ενδιαφέρον των αναγνωστών, τότε στα ακόλουθα άρθρα θέλω να περιγράψω τον τρόπο αποστολής εντολών σε απομακρυσμένο εξοπλισμό. Καταφέραμε επίσης να εφαρμόσουμε ολόκληρο το σχέδιο για συσκευές που βασίζονται στο RouterOS (Mikrotik).

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο