80-port orqali Lunix/OpenWrt/Lede-ga asoslangan qurilmalarni masofadan kuzatish va boshqarish…

Hammaga salom, bu mening Habrédagi birinchi tajribam. Men tashqi tarmoqdagi tarmoq uskunalarini nostandart tarzda qanday boshqarish haqida yozmoqchiman. Nostandart nimani anglatadi: ko'p hollarda tashqi tarmoqdagi uskunani boshqarish uchun sizga kerak bo'ladi:

  • Umumiy IP manzili. Xo'sh, yoki agar uskuna kimningdir NAT-ning orqasida bo'lsa, u holda umumiy IP va "yo'naltirilgan" port.
  • Tunnel (PPTP/OpenVPN/L2TP+IPSec va boshqalar) markaziy tugunga, u orqali kirish mumkin.

Shuning uchun, standart usullar sizga mos kelmasa, sizga "mening velosipedim" kerak bo'ladi, masalan:

  1. Uskunalar NAT orqasida joylashgan va odatdagi http (port 80) bundan mustasno, hamma narsa yopiq. Bu yirik federal korporativ tarmoqlar uchun mutlaqo normal holat. Ular portlarni ro'yxatdan o'tkazishlari mumkin, lekin darhol emas, tez emas va siz uchun emas.
  2. Beqaror va/yoki “tor” aloqa kanali. Past tezlik, doimiy yo'qotishlar. Tunnelni tashkil etishga urinayotganda og'riq va umidsizlik.
  3. Qimmatbaho aloqa kanali, bu erda tom ma'noda har bir megabayt hisobga olinadi. Masalan, sun'iy yo'ldosh aloqasi. Bundan tashqari, uzoq kechikishlar va "tor" tarmoqli.
  4. Bir tomondan, imkoniyatlarni kengaytirish uchun OpenWrt/Lede o'rnatilgan, boshqa tomondan, yo'riqnoma resurslari (xotirasi) etarli bo'lmagan ko'p sonli kichik marshrutizatorlarni "junglyor qilish" kerak bo'lgan vaziyat. hamma narsa uchun.

Raqamli vaqtlarga e'tibor bering Routerning USB portiga flesh-diskni o'rnatishga va yo'riqnoma xotirasini kengaytirishga nima xalaqit beradi?

Ko'pincha, talablar umuman yechimning narxiga tegishli, ammo ba'zida shakl omili ham asosiy rol o'ynaydi. Masalan, saytda TP-Link ML3020 mavjud, uning yagona USB porti 2G/3G modem uchun ishlatiladi, bularning barchasi kichik plastik qutiga o'ralgan va baland, baland (mastda) joyga joylashtirilgan, uzoqda, uzoqda (dalada, eng yaqin uyali aloqa operatori tayanch stantsiyasidan 30 km uzoqlikda). Ha, siz USB hubni ulashingiz va portlar sonini kengaytirishingiz mumkin, ammo tajriba shuni ko'rsatadiki, bu noqulay va ishonchsizdir.

Shunday qilib, men sizga o'zimning odatiy holatimni tasvirlashga harakat qildim: “biror joyda, uzoqda, Linuxda ishlaydigan juda muhim, yolg'iz va kichik router bor. Kuniga kamida bir marta uning "tirik" ekanligini bilish juda muhim va agar kerak bo'lsa, unga buyruqlar yuboriladi, masalan, "asal, qayta yoqing!"

Keling, amalga oshirishga o'tamiz:

1) Router tomonida cron orqali har 5/10/1440 daqiqada yoki xohlagan vaqtda serverga wget yordamida http so'rovini yuborishingiz, so'rov natijasini faylga saqlashingiz, faylni bajariladigan qilib qo'yishingiz kerak. , va uni bajaring.

Mening cron chizig'im shunday ko'rinadi:

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

qaerda:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai mening serverim domeni. Darhol ta'kidlab o'taman: ha, siz serverning ma'lum bir IP-manzilini ko'rsatishingiz mumkin, biz buni davlatimiz to'g'ridan-to'g'ri to'g'ridan-to'g'ri kurashda, men aytaman, bilmayman, sherga kirishni to'sib qo'ydik. DigitalOcean va Amazon "bulutlari" ning ulushi. Agar siz ramziy domendan foydalansangiz, bunday hodisa yuzaga kelsa, osongina zaxira bulutini ko'tarishingiz, domenni unga yo'naltirishingiz va qurilma monitoringini tiklashingiz mumkin.

a.php - server tomonidagi skriptning nomi. Ha, o'zgaruvchilar va fayl nomlarini bir xil harf bilan nomlash noto'g'ri ekanligini bilaman... Shu tarzda so'rov yuborishda bir necha bayt saqlashni taklif qilaman :)
u - foydalanuvchi nomi, apparatga kirish
p - parol
“-O /tmp/wa.sh” bu masofaviy routerdagi fayl boʻlib, serverning javobi, masalan, qayta ishga tushirish buyrugʻi saqlanadi.

Ikkinchi eslatma: Ahhh, nega biz curl emas, wget dan foydalanamiz, chunki curl orqali https so'rovlarini GET bilan emas, POST bilan yuborishingiz mumkin? Ahh, chunki, eski hazilda bo'lgani kabi, "NE bankaga ko'tariladi!" curl taxminan 2 MB hajmdagi shifrlash kutubxonalarini o'z ichiga oladi va shuning uchun siz, masalan, kichik TP-LINK ML3020 uchun tasvirni yig'a olmasligingiz dargumon. Va wget bilan - iltimos.

2) Server tomonida (menda Ubuntu bor) biz Zabbixdan foydalanamiz. Nima uchun: Men chiroyli (grafiklar bilan) va qulay bo'lishini xohlayman (kontekst menyusi orqali buyruqlarni yuborish). Zabbixda zabbix agenti kabi ajoyib narsa bor. Agent orqali biz serverda PHP skriptiga qo'ng'iroq qilamiz, u bizning routerimiz talab qilingan vaqt ichida ro'yxatdan o'tganligi haqida ma'lumotni qaytaradi. Ro'yxatdan o'tish vaqti, qurilmalar uchun buyruqlar haqidagi ma'lumotlarni saqlash uchun men MySQL-dan, taxminan quyidagi maydonlarga ega bo'lgan alohida jadval foydalanuvchilaridan foydalanaman:

		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;

Barcha manbalarni Git omboridan yuklab olish mumkin: https://github.com/BazDen/iotnet.online.git
Endi PHP skriptlari server tomoniga joylashtirilgan (qulaylik uchun ularni /usr/share/zabbix/ jildiga joylashtirish mumkin):

a.php fayli:

<?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 fayli (bu zabbix agentining skripti deb ataladi):

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

Yakuniy bosqich: agentni ro'yxatdan o'tkazish va jadvallarni qo'shish.

Agar siz hali zabbix agentini o'rnatmagan bo'lsangiz, unda:

apt-get install zabbix-agent

/etc/zabbix/zabbix_agentd.conf faylini tahrirlang.

qatorni qo'shing:

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

qaerda:
test bizning agentimiz nomi
"php /usr/share/zabbix/agent.php foydalanuvchi paroli" - qurilma ro'yxatga olish ma'lumotlarini ko'rsatadigan skript deb ataladi.

Diagramma qo'shish: zabbix veb-interfeysini oching, menyudan tanlang:
Sozlamalar -> Tarmoq tugunlari -> Tarmoq tugunini yarating. Bu erda tarmoq xosti nomini, uning guruhini va standart agent interfeysini ko'rsatish kifoya:

80-port orqali Lunix/OpenWrt/Lede-ga asoslangan qurilmalarni masofadan kuzatish va boshqarish…

Endi biz ushbu tarmoq tuguniga ma'lumotlar elementini qo'shishimiz kerak. Ikkita maydonga e'tibor bering: "kalit" - bu biz /etc/zabbix/zabbix_agentd.conf faylida yozgan parametr (bizning holatlarimizda bu sinov) va "yangilanish oralig'i" - men uni 5 daqiqaga qo'ydim. , chunki va uskunalar ham har besh daqiqada bir marta serverda ro'yxatga olinadi.

80-port orqali Lunix/OpenWrt/Lede-ga asoslangan qurilmalarni masofadan kuzatish va boshqarish…

Keling, grafik qo'shamiz. Renderlash uslubi sifatida "To'ldirish" ni tanlashni tavsiya qilaman.

80-port orqali Lunix/OpenWrt/Lede-ga asoslangan qurilmalarni masofadan kuzatish va boshqarish…

Chiqish juda ixcham narsa, masalan:

80-port orqali Lunix/OpenWrt/Lede-ga asoslangan qurilmalarni masofadan kuzatish va boshqarish…

Oqilona savolga: "bu bunga arziydimi?" Men javob beraman: albatta, maqolaning boshida "velosiped yaratish sabablari" ga qarang.

Agar mening birinchi grafomanik tajribam o'quvchilarning qiziqishini uyg'otsa, keyingi maqolalarda men masofaviy uskunaga buyruqlarni qanday yuborishni tasvirlamoqchiman. Shuningdek, biz RouterOS (Mikrotik) asosidagi qurilmalar uchun butun sxemani amalga oshirishga muvaffaq bo'ldik.

Manba: www.habr.com

a Izoh qo'shish