Pemantauan dan kawalan jauh peranti berasaskan Lunix/OpenWrt/Lede melalui port 80…

Hello semua, ini adalah pengalaman pertama saya di Habré. Saya ingin menulis tentang cara mengurus peralatan rangkaian pada rangkaian luaran dengan cara yang tidak standard. Apakah maksud bukan standard: dalam kebanyakan kes, untuk mengurus peralatan pada rangkaian luaran anda perlukan:

  • Alamat IP awam. Nah, atau jika peralatan berada di belakang NAT seseorang, maka IP awam dan port "diteruskan".
  • Terowong (PPTP/OpenVPN/L2TP+IPSec, dsb.) ke nod pusat yang melaluinya ia boleh diakses.

Oleh itu, anda memerlukan "basikal saya" apabila kaedah standard tidak sesuai dengan anda, contohnya:

  1. Peralatan terletak di belakang NAT dan, kecuali untuk http biasa (port 80), semuanya ditutup. Ini adalah situasi biasa untuk rangkaian korporat persekutuan yang besar. Mereka boleh mendaftarkan port, tetapi tidak serta-merta, tidak cepat, dan bukan untuk anda.
  2. Saluran komunikasi yang tidak stabil dan/atau "sempit". Kelajuan rendah, kerugian berterusan. Kesakitan dan kekecewaan apabila cuba mengatur terowong.
  3. Saluran komunikasi yang mahal, di mana secara literal setiap megabait dikira. Contohnya, komunikasi satelit. Ditambah kelewatan yang panjang dan jalur "sempit".
  4. Situasi apabila anda perlu "menyulap" sejumlah besar penghala kecil, di mana, di satu pihak, OpenWrt/Lede dipasang untuk mengembangkan keupayaan, dan sebaliknya, sumber (memori) penghala tidak mencukupi untuk segala-galanya.

Nota nombor kali Apakah yang menghalang anda daripada memasang pemacu denyar ke dalam port USB penghala dan mengembangkan memori penghala?

Selalunya, keperluan adalah untuk kos penyelesaian secara keseluruhan, tetapi kadangkala faktor bentuk juga memainkan peranan penting. Sebagai contoh, terdapat TP-Link ML3020 di tapak, satu-satunya port USBnya digunakan untuk modem 2G/3G, semua ini dibalut dengan sejenis bekas plastik kecil dan diletakkan di suatu tempat yang tinggi, tinggi (di tiang), jauh, jauh (di padang, 30 km dari stesen pangkalan pengendali mudah alih terdekat). Ya, anda boleh memasangkan hab USB dan mengembangkan bilangan port, tetapi pengalaman menunjukkan bahawa ini menyusahkan dan tidak boleh dipercayai.

Oleh itu, saya cuba menerangkan kepada anda situasi biasa saya: “di suatu tempat yang jauh, jauh, terdapat penghala yang sangat penting, sunyi dan kecil yang menjalankan Linux. Adalah penting untuk mengetahui sekurang-kurangnya sekali sehari bahawa dia "hidup" dan, jika perlu, arahan dihantar kepadanya, sebagai contoh, "sayang, but semula!"

Mari kita beralih kepada pelaksanaan:

1) Di bahagian penghala, melalui cron, setiap 5/10/1440 minit, atau bila-bila masa anda mahu, anda perlu menghantar permintaan http ke pelayan menggunakan wget, simpan hasil permintaan ke fail, jadikan fail boleh laku , dan laksanakannya.

Barisan cron saya kelihatan seperti ini:

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

, di mana:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai ialah domain pelayan saya. Biar saya ambil perhatian segera: ya, anda boleh menentukan alamat IP tertentu pelayan, kami biasa melakukan ini sehingga keadaan kami, dalam dorongan perjuangan yang benar, saya akan berkata, saya tidak tahu, menyekat akses ke singa bahagian "awan" DigitalOcean dan Amazon. Jika anda menggunakan domain simbolik, jika insiden sedemikian berlaku, anda boleh menaikkan awan sandaran dengan mudah, mengubah hala domain kepadanya dan memulihkan pemantauan peranti.

a.php ialah nama skrip sebelah pelayan. Ya, saya tahu bahawa adalah salah untuk menamakan pembolehubah dan nama fail dengan huruf yang sama... Saya cadangkan dengan cara ini kita menyimpan beberapa bait semasa menghantar permintaan :)
u - nama pengguna, log masuk perkakasan
p - kata laluan
“-O /tmp/wa.sh” ialah fail pada penghala jauh di mana respons pelayan, contohnya arahan but semula, akan disimpan.

Nota nombor dua: Ahhh, mengapa kita menggunakan wget dan bukan curl, kerana melalui curl anda boleh menghantar permintaan https bukan dengan GET, tetapi dengan POST? Ahhh kerana, seperti dalam jenaka lama "NE naik ke dalam balang!" curl termasuk perpustakaan penyulitan bersaiz kira-kira 2MB, dan kerana ini tidak mungkin anda akan dapat memasang imej untuk TP-LINK ML3020 kecil, sebagai contoh. Dan dengan wget - sila.

2) Di bahagian pelayan (saya mempunyai Ubuntu) kami akan menggunakan Zabbix. Sebab: Saya mahu ia cantik (dengan graf) dan mudah (hantar arahan melalui menu konteks). Zabbix mempunyai perkara yang hebat seperti ejen zabbix. Melalui ejen, kami akan memanggil skrip PHP pada pelayan, yang akan mengembalikan maklumat tentang sama ada penghala kami didaftarkan dalam tempoh masa yang diperlukan. Untuk menyimpan maklumat tentang masa pendaftaran, arahan untuk peranti, saya menggunakan MySQL, pengguna jadual berasingan dengan lebih kurang medan berikut:

		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;

Semua sumber boleh dimuat turun dari repositori Git di: https://github.com/BazDen/iotnet.online.git
Sekarang skrip PHP diletakkan di sebelah pelayan (untuk kemudahan, ia boleh diletakkan dalam folder /usr/share/zabbix/):

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

Fail Agent.php (ini ialah skrip ejen zabbix yang dipanggil):

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

Nah, peringkat akhir: mendaftar ejen dan menambah jadual.

Jika anda masih belum memasang ejen zabbix, maka:

apt-get install zabbix-agent

Edit fail /etc/zabbix/zabbix_agentd.conf.

Tambah baris:

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

, di mana:
test adalah nama ejen kami
“php /usr/share/zabbix/agent.php kata laluan pengguna” - skrip dipanggil yang menunjukkan data pendaftaran peranti.

Menambah carta: buka antara muka web zabbix, pilih daripada menu:
Tetapan -> Nod rangkaian -> Buat nod rangkaian. Di sini sudah cukup untuk menentukan nama hos rangkaian, kumpulannya, dan antara muka ejen lalai:

Pemantauan dan kawalan jauh peranti berasaskan Lunix/OpenWrt/Lede melalui port 80…

Sekarang kita perlu menambah elemen data untuk nod rangkaian ini. Beri perhatian kepada dua medan: "kunci" - ini betul-betul parameter yang kami tulis dalam fail /etc/zabbix/zabbix_agentd.conf (dalam kes kami ia adalah ujian), dan "selang kemas kini" - Saya menetapkannya kepada 5 minit , kerana dan peralatan juga didaftarkan pada pelayan sekali setiap lima minit.

Pemantauan dan kawalan jauh peranti berasaskan Lunix/OpenWrt/Lede melalui port 80…

Baiklah, mari tambah graf. Saya mengesyorkan memilih "Isi" sebagai gaya pemaparan.

Pemantauan dan kawalan jauh peranti berasaskan Lunix/OpenWrt/Lede melalui port 80…

Outputnya adalah sesuatu yang sangat singkat, contohnya seperti ini:

Pemantauan dan kawalan jauh peranti berasaskan Lunix/OpenWrt/Lede melalui port 80…

Kepada soalan yang munasabah: "adakah ia berbaloi?", Saya akan menjawab: sudah tentu, lihat "sebab untuk mencipta basikal" pada permulaan artikel.

Jika pengalaman graphomaniac pertama saya membangkitkan minat pembaca, maka dalam artikel berikut saya ingin menerangkan cara menghantar arahan ke peralatan jauh. Kami juga berjaya melaksanakan keseluruhan skim untuk peranti berdasarkan RouterOS (Mikrotik).

Sumber: www.habr.com

Tambah komen