Surveillance à distance et gestion des appareils basés sur Lunix/OpenWrt/Lede via le port 80…

Bonjour à tous, c'est ma première expérience sur Habr. Je veux parler de la façon de gérer de manière non conventionnelle le matériel réseau dans un réseau externe. Que signifie non conventionnel : dans la plupart des cas, pour gérer le matériel d'un réseau externe, vous devez disposer de :

  • Une adresse IP publique. Ou, si le matériel est derrière un NAT, une IP publique et un port "ouvert".
  • Un tunnel (PPTP/OpenVPN/L2TP+IPSec, etc.) vers le nœud central, par lequel l'accès serait possible.

C'est pourquoi « mon vélo » vous sera nécessaire lorsque les méthodes standards ne vous conviennent pas, par exemple :

  1. Le matériel est derrière un NAT et, à part le http normal (port 80), tout est fermé. C’est une situation tout à fait normale pour de grands réseaux corporatifs fédéraux. Ils peuvent ouvrir des ports, mais pas immédiatement, pas rapidement et pas pour vous.
  2. Un canal de communication instable et/ou "étroit". Une petite vitesse, des pertes constantes. Douleur et déception lors de la tentative d'organiser un tunnel.
  3. Un canal de communication coûteux, où chaque mégaoctet compte. Par exemple, une communication par satellite. De plus, de grandes latences et une bande passante "étroite".
  4. Une situation où vous devez "jongler" avec un grand nombre de petits routeurs, sur lesquels OpenWrt/Lede est installé d'un côté pour étendre les fonctionnalités, et de l'autre côté, les ressources (mémoire) du routeur ne sont pas suffiantes pour tout.

Note numéro un Qu'est-ce qui empêche d'installer une clé USB dans le port USB du routeur pour augmenter la mémoire du routeur ?

Le plus souvent, les exigences concernant le coût de la solution dans son ensemble, mais parfois le format joue un rôle crucial. Par exemple, sur le site se trouve un TP-Link ML3020, son unique port USB est utilisé pour un modem 2G/3G, le tout étant enfermé dans un petit boîtier en plastique et placé haut, au sommet d'un mât, loin (dans un champ, à 30 km de la station de base la plus proche de l'opérateur mobile). Oui, vous pouvez brancher un hub USB pour augmenter le nombre de ports, mais l'expérience montre que c'est encombrant et peu fiable.

Ainsi, j'ai essayé de vous décrire ma situation typique : "quelque part, loin, se trouve un routeur très important, seul et petit, sous Linux. Il est important de savoir au moins une fois par jour qu'il est "vivant" et d'y envoyer des commandes si nécessaire, par exemple "soleil, redémarre-toi !"

Passons à la mise en œuvre :

1) Du côté du routeur, par cron toutes les 5/10/1440 minutes, ou à tout moment, il est nécessaire d'envoyer une requête http au serveur à l'aide de wget, de sauvegarder le résultat de la requête dans un fichier, de rendre le fichier exécutable et de l'exécuter.

Ma ligne dans cron ressemble à peu près à ceci :

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

, où :
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai — le domaine de mon serveur. Je précise : oui, vous pouvez également indiquer une adresse IP spécifique du serveur, nous l'avons fait auparavant, jusqu'à ce que notre État, dans un élan de lutte contre je ne sais quoi, ne ferme l'accès à une grande partie des « nuages » de DigitalOcean et Amazon. En cas d'utilisation d'un domaine symbolique, en cas d'apparition d'un tel incident, vous pourrez facilement créer un nuage de secours, rediriger le domaine vers celui-ci et restaurer la surveillance des appareils.

a.php — le nom du script côté serveur. Oui, je sais que ce n'est pas correct de nommer les variables et les noms de fichiers d'une seule lettre… considérons qu'ainsi nous économisons quelques octets lors de l'envoi de la requête 🙂
u — le nom d'utilisateur, le login de l'appareil
p — mot de passe
"-O /tmp/wa.sh" — le fichier sur le routeur distant où sera enregistré la réponse du serveur, par exemple la commande reboot.

Remarque numéro deux : Aaaa, pourquoi utilisons-nous wget et pas curl, après tout avec curl on peut envoyer des requêtes https et pas seulement en GET, mais en POST ? Aaaa parce que comme dans l'ancien blague « Dans la barrique, ça ne passe pas ! ». curl inclut des bibliothèques de cryptage d'environ 2 Mo et en raison de cela, il est peu probable que vous puissiez créer une image pour un petit TP-LINK ML3020 par exemple. Mais avec wget, pas de problème.

2) Du côté du serveur (j'utilise Ubuntu), nous allons utiliser Zabbix. Pourquoi : je veux que ce soit beau (avec des graphiques) et pratique (pour envoyer des commandes via le menu contextuel). Zabbix a une caractéristique charmante, appelée agent zabbix. Via cet agent, nous allons appeler un script php sur le serveur, qui retournera des informations sur la connexion de notre routeur durant la période requise. Pour stocker les informations sur le temps de connexion, les commandes pour les appareils, j'utilise MySQL, une table séparée users avec des champs comme ceux-ci :

		CRÉER TABLE `users` (
		  `id` varchar(25) NON NUL,
		  `passwd` varchar(25) NON NUL,
		  `description` varchar(150) NON NUL,
		  `category` varchar(30) NON NUL,
		  `status` varchar(10) NON NUL,
		  `last_time` varchar(20) NON NUL, // dernier temps de connexion
		  `last_ip` varchar(20) NON NUL, // IP de la dernière connexion
		  `last_port` int(11) NON NUL, // port de la dernière connexion
		  `task` text NON NUL, // tâche que reçoit le routeur
		  `reg_task` varchar(150) NON NUL, // tâche "régulière", si nous souhaitons que la tâche soit toujours exécutée lors de l'enregistrement
		  `last_task` text NON NUL, // journal des tâches
		  `response` text NON NUL, // réponse de l'appareil
		  `seq` int(11) NON NUL
		) MOTEUR=InnoDB DEFAULT CHARSET=utf8;

Tous les sources peuvent être récupérés depuis le dépôt Git à l'adresse : https://github.com/BazDen/iotnet.online.git
Maintenant, les scripts PHP, placés du côté du serveur (pour plus de commodité, vous pouvez les placer dans le dossier /usr/share/zabbix/) :

Fichier a.php :

set_charset("utf8");
	// ici nous cherchons notre routeur dans la table de la base de données
	$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();
		// ici nous envoyons les tâches au routeur
		echo $task;
		echo "n";
		echo $reg_task;
		// ici nous écrivons le temps de réponse et la réponse du routeur
		$response_history="[".date("Y-m-d H:i")."] ".$message;
		// la tâche a été envoyée, maintenant il faut la supprimer, puis dans les logs noter que la tâche a été accomplie
		$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();
		}
		// maintenant il faut enregistrer le temps d'enregistrement de l'utilisateur, son IP et son message. Pour l'instant seulement le message
		$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();
	}
	// si nous n'avons pas trouvé le routeur dans notre base de données, ou si son statut est "inactif", alors une commande reboot lui sera envoyée....
	// Pourquoi si sévèrement ? Parce que les routeurs disparaissent parfois, et c'est un petit moyen de punir les "nouveaux propriétaires". 
	else
	{
	echo "reboot";
	}
	$sql_users->close();
?>

Fichier agent.php (c'est le script appelé par l'agent zabbix) :

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();
	// l'échange de données se fait via le champ seq. Lors de l'enregistrement, le matériel définit ce champ à "1"
	if (($sql_users->num_rows)==1){
		$sql_users->fetch();
		echo $seq;
	}
		
	// réinitialisation de $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();
?>		

Et la dernière étape : configuration de l'agent et ajout des graphiques.

Si vous n'avez pas encore installé l'agent zabbix, alors :

apt-get install zabbix-agent

Nous modifions le fichier /etc/zabbix/zabbix_agentd.conf.

Ajoutez la ligne :

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

, où :
test — le nom de notre agent
„php /usr/share/zabbix/agent.php user password“ — le script appelé avec les informations d'identification de l'appareil.

Ajout des graphiques : ouvrez l'interface web de zabbix, dans le menu sélectionnez :
Configuration -> Nœuds du réseau -> Créer un nœud du réseau. Ici, il suffit d'indiquer le nom du nœud du réseau, son groupe, l'interface de l'agent par défaut :

Surveillance à distance et gestion des appareils basés sur Lunix/OpenWrt/Lede via le port 80…

Maintenant, pour ce nœud du réseau, nous devons ajouter un élément de données. Faites attention à deux champs : „clé“ — c'est le paramètre que nous avons spécifié dans le fichier /etc/zabbix/zabbix_agentd.conf (dans notre cas c'est test), et „intervalle de mise à jour“ — je fixe 5 minutes, car l'équipement s'enregistre également sur le serveur une fois toutes les cinq minutes.

Surveillance à distance et gestion des appareils basés sur Lunix/OpenWrt/Lede via le port 80…

Et ajoutons un graphique. Je recommande de choisir „Remplissage“ comme style de rendu.

Surveillance à distance et gestion des appareils basés sur Lunix/OpenWrt/Lede via le port 80…

Au final, cela donne quelque chose de très concis, par exemple comme ceci :

Surveillance à distance et gestion des appareils basés sur Lunix/OpenWrt/Lede via le port 80…

À la question légitime : „est-ce que cela en valait la peine ?“, je répondrai : bien sûr, regardez „les raisons de créer un vélo“ au début de l'article.

Si ma première expérience d'écriture provoque l'intérêt des lecteurs, alors dans les prochains articles je veux décrire comment envoyer des commandes à des équipements distants. J'ai également réussi à réaliser tout le schéma pour les appareils basés sur RouterOS (Mikrotik).

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster