نظارت و کنترل از راه دور دستگاه های مبتنی بر Lunix/OpenWrt/Lede از طریق پورت 80…

سلام به همه، این اولین تجربه من در Habré است. من می خواهم در مورد نحوه مدیریت تجهیزات شبکه در یک شبکه خارجی به روش غیر استاندارد بنویسم. معنی غیر استاندارد چیست: در بیشتر موارد، برای مدیریت تجهیزات در یک شبکه خارجی به:

  • آدرس IP عمومی خوب، یا اگر تجهیزات پشت NAT شخصی است، یک IP عمومی و یک پورت "forwarded" وجود دارد.
  • تونل (PPTP/OpenVPN/L2TP+IPSec و غیره) به گره مرکزی که از طریق آن قابل دسترسی است.

بنابراین، زمانی که روش های استاندارد مناسب شما نیست، به "دوچرخه من" نیاز خواهید داشت، به عنوان مثال:

  1. تجهیزات پشت NAT قرار دارند و به جز http معمول (پورت 80) همه چیز بسته است. این یک وضعیت کاملاً عادی برای شبکه های بزرگ شرکتی فدرال است. آنها می توانند پورت ها را ثبت کنند، اما نه فوراً، نه سریع و نه برای شما.
  2. کانال ارتباطی ناپایدار و/یا باریک. سرعت کم، تلفات ثابت. درد و ناامیدی هنگام تلاش برای سازماندهی یک تونل.
  3. یک کانال ارتباطی گران قیمت، که در آن به معنای واقعی کلمه هر مگابایت به حساب می آید. به عنوان مثال، ارتباطات ماهواره ای. به علاوه تاخیرهای طولانی و باند "باریک".
  4. وضعیتی که شما باید تعداد زیادی روتر کوچک را "جنگل" کنید که از یک طرف OpenWrt/Lede برای گسترش قابلیت ها روی آنها نصب شده است و از طرف دیگر منابع (حافظه) روتر کافی نیست. برای همه چیز.

تعداد دفعات را یادداشت کنید چه چیزی مانع از نصب فلش درایو در پورت USB روتر و افزایش حافظه روتر می شود؟

اغلب، الزامات مربوط به هزینه راه حل به عنوان یک کل است، اما گاهی اوقات فاکتور شکل نیز نقش کلیدی ایفا می کند. به عنوان مثال، یک TP-Link ML3020 در سایت وجود دارد، تنها پورت USB آن برای یک مودم 2G/3G استفاده می شود، همه اینها در نوعی کیس پلاستیکی کوچک پیچیده شده و در جایی بالا، بالا (روی دکل) قرار می گیرد. دور، دور (در میدان، 30 کیلومتر از نزدیکترین ایستگاه پایه اپراتور تلفن همراه). بله، می توانید یک هاب USB را وصل کنید و تعداد پورت ها را افزایش دهید، اما تجربه نشان می دهد که این کار دست و پا گیر و غیرقابل اعتماد است.

بنابراین، من سعی کردم شرایط معمول خود را برای شما شرح دهم: «در جایی دور، بسیار دور، یک روتر بسیار مهم، تنها و کوچک وجود دارد که لینوکس را اجرا می کند. مهم است که حداقل یک بار در روز بدانید که او "زنده" است و در صورت لزوم دستوراتی برای او ارسال می شود ، به عنوان مثال "عزیزم ، راه اندازی مجدد!"

بیایید به سمت اجرا برویم:

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 خاص سرور را مشخص کنید، ما این کار را انجام می دادیم تا زمانی که دولت ما، در یک انگیزه درست مبارزه، می گویم، نمی دانم، دسترسی به شیر را مسدود کرد. سهم «ابرهای دیجیتال اقیانوس» و آمازون. اگر از یک دامنه نمادین استفاده می کنید، اگر چنین اتفاقی رخ دهد، می توانید به راحتی یک ابر پشتیبان ایجاد کنید، دامنه را به آن هدایت کنید و نظارت دستگاه را بازیابی کنید.

a.php نام اسکریپت سمت سرور است. بله میدونم نامگذاری متغیرها و نام فایلها با یک حرف اشتباهه...پیشنهاد میکنم در ارسال درخواست چند بایت ذخیره کنیم :)
u - نام کاربری، ورود سخت افزار
p - رمز عبور
"-O /tmp/wa.sh" یک فایل در روتر راه دور است که در آن پاسخ سرور، به عنوان مثال دستور راه اندازی مجدد، ذخیره می شود.

یادداشت شماره دو: آهان، چرا از wget استفاده می کنیم و از curl استفاده نمی کنیم، زیرا از طریق curl می توانید درخواست های https را نه با GET بلکه با POST ارسال کنید؟ آهان، زیرا، همانطور که در جوک قدیمی "NE به کوزه می رود!" curl شامل کتابخانه های رمزگذاری با اندازه حدود 2 مگابایت است و به همین دلیل بعید است که بتوانید برای مثال یک TP-LINK ML3020 تصویری را جمع آوری کنید. و با wget - لطفا.

2) در سمت سرور (من اوبونتو دارم) از 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

، جایی که:
تست نام نماینده ماست
"رمز عبور کاربر 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

اضافه کردن نظر