80 портоор дамжуулан Lunix/OpenWrt/Lede-д суурилсан төхөөрөмжүүдийг алсаас хянах, хянах...

Сайн байцгаана уу, энэ бол миний Habré дээр анх удаа туршлага хуримтлуулах явдал юм. Гадны сүлжээн дэх сүлжээний тоног төхөөрөмжийг стандарт бус аргаар хэрхэн удирдах талаар бичмээр байна. Стандарт бус гэж юу гэсэн үг вэ: ихэнх тохиолдолд гадаад сүлжээнд байгаа тоног төхөөрөмжийг удирдахын тулд танд дараахь зүйл хэрэгтэй болно.

  • Нийтийн IP хаяг. Хэрэв төхөөрөмж нь хэн нэгний NAT-ийн ард байгаа бол нийтийн IP болон "дамжуулах" порт байна.
  • Хонгил (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 минут тутамд, эсвэл хүссэн үедээ wget ашиглан сервер рүү http хүсэлт илгээж, хүсэлтийн үр дүнг файлд хадгалах, файлыг гүйцэтгэх боломжтой болгох хэрэгтэй. , мөн гүйцэтгэнэ.

Миний 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 нь сервер талын скриптийн нэр юм. Тийм ээ, хувьсагч болон файлын нэрийг нэг үсгээр нэрлэх нь буруу гэдгийг би мэдэж байна... Ийм байдлаар хүсэлт илгээхдээ хэдэн байт хадгалахыг санал болгож байна :)
u - хэрэглэгчийн нэр, техник хангамжийн нэвтрэлт
p - нууц үг
“-O /tmp/wa.sh” нь алсын чиглүүлэгч дээрх файл бөгөөд серверийн хариу, тухайлбал дахин ачаалах тушаалыг хадгалах болно.

Хоёрдугаар тэмдэглэл: Аа, яагаад бид curl биш wget ашигладаг вэ, яагаад гэвэл curl-ээр дамжуулан https хүсэлтийг GET-ээр биш, харин POST-оор илгээх боломжтой вэ? Аххх, учир нь "НЭ вааранд авирдаг" гэдэг хуучин хошигнол шиг. curl нь ойролцоогоор 2МБ хэмжээтэй шифрлэлтийн сангуудыг агуулдаг бөгөөд иймээс та жишээ нь жижиг TP-LINK ML3020-д зориулж зураг цуглуулах боломжгүй юм. Мөн wget-тэй - гуйя.

2) Сервер талд (надад Ubuntu байгаа) бид 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 вэб интерфэйсийг нээж, цэснээс сонгоно уу:
Тохиргоо -> Сүлжээний зангилаа -> Сүлжээний зангилаа үүсгэ. Энд сүлжээний хостын нэр, түүний бүлэг, анхдагч агент интерфейсийг зааж өгөхөд хангалттай.

80 портоор дамжуулан Lunix/OpenWrt/Lede-д суурилсан төхөөрөмжүүдийг алсаас хянах, хянах...

Одоо бид энэ сүлжээний зангилааны өгөгдлийн элементийг нэмэх хэрэгтэй. Хоёр талбарт анхаарлаа хандуулаарай: "түлхүүр" - энэ бол бидний /etc/zabbix/zabbix_agentd.conf файлд бичсэн параметр юм (манай тохиолдолд энэ нь туршилт), "шинэчлэх интервал" - Би үүнийг 5 минут болгож тохируулсан. , учир нь мөн тоног төхөөрөмж нь сервер дээр таван минут тутамд нэг удаа бүртгэгддэг.

80 портоор дамжуулан Lunix/OpenWrt/Lede-д суурилсан төхөөрөмжүүдийг алсаас хянах, хянах...

За ингээд график нэмье. Би "Дүүргэх"-ийг дүрслэх хэв маягаар сонгохыг зөвлөж байна.

80 портоор дамжуулан Lunix/OpenWrt/Lede-д суурилсан төхөөрөмжүүдийг алсаас хянах, хянах...

Гаралт нь маш товчхон зүйл юм, жишээлбэл:

80 портоор дамжуулан Lunix/OpenWrt/Lede-д суурилсан төхөөрөмжүүдийг алсаас хянах, хянах...

"Энэ нь үнэ цэнэтэй байсан уу?" Гэсэн үндэслэлтэй асуултанд би хариулах болно: Мэдээжийн хэрэг, нийтлэлийн эхэнд "унадаг дугуй бий болгох шалтгааныг" үзнэ үү.

Хэрэв миний анхны графоманик туршлага уншигчдын сонирхлыг татсан бол дараагийн нийтлэлүүдэд би алсын төхөөрөмж рүү командыг хэрхэн илгээх талаар тайлбарлахыг хүсч байна. Бид RouterOS (Mikrotik) дээр суурилсан төхөөрөмжүүдийн бүх схемийг хэрэгжүүлж чадсан.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх