Lunix/OpenWrt/Lede tabanlı cihazların port 80… üzerinden uzaktan izlenmesi ve kontrolü

Herkese merhaba, bu benim Habré'deki ilk deneyimim. Harici bir ağdaki ağ ekipmanlarının standart olmayan bir şekilde nasıl yönetileceği hakkında yazmak istiyorum. Standart dışı ne anlama gelir: çoğu durumda harici bir ağdaki ekipmanı yönetmek için ihtiyacınız olan:

  • Genel IP adresi. Peki ya da ekipman birinin NAT'ının arkasındaysa, o zaman genel bir IP ve "yönlendirilen" bir bağlantı noktası.
  • Erişilebilir olacağı merkezi düğüme tünel açın (PPTP/OpenVPN/L2TP+IPSec vb.).

Bu nedenle, standart yöntemler size uygun olmadığında "bisikletime" ihtiyacınız olacaktır, örneğin:

  1. Ekipman NAT'ın arkasında bulunur ve normal http (bağlantı noktası 80) dışında her şey kapalıdır. Bu, büyük federal kurumsal ağlar için tamamen normal bir durumdur. Bağlantı noktalarını kaydedebilirler, ancak hemen değil, hızlı bir şekilde ve sizin için değil.
  2. Kararsız ve/veya “dar” iletişim kanalı. Düşük hız, sürekli kayıplar. Bir tünel düzenlemeye çalışırken acı ve hayal kırıklığı.
  3. Kelimenin tam anlamıyla her megabaytın önemli olduğu pahalı bir iletişim kanalı. Örneğin uydu iletişimi. Ayrıca uzun gecikmeler ve "dar" bir bant.
  4. Bir yandan yetenekleri genişletmek için OpenWrt/Lede'nin kurulu olduğu, diğer yandan yönlendiricinin kaynaklarının (belleğinin) yeterli olmadığı çok sayıda küçük yönlendiriciyle "hokkabazlık yapmanız" gereken bir durum herşey için.

Sayı katlarını not edin Yönlendiricinin USB bağlantı noktasına bir flash sürücü takmanızı ve yönlendiricinin belleğini genişletmenizi engelleyen nedir?

Çoğunlukla gereksinimler çözümün bir bütün olarak maliyetine yöneliktir ancak bazen form faktörü de önemli bir rol oynar. Örneğin, sitede bir TP-Link ML3020 var, tek USB bağlantı noktası 2G/3G modem için kullanılıyor, tüm bunlar bir tür küçük plastik kasaya sarılmış ve yüksek, yüksek bir yere (direğe) yerleştirilmiş, çok çok uzakta (sahada, en yakın mobil operatör baz istasyonundan 30 km uzaklıkta). Evet, bir USB hub'ı takabilir ve bağlantı noktası sayısını artırabilirsiniz, ancak deneyimler bunun hantal ve güvenilmez olduğunu göstermektedir.

Bu yüzden size tipik durumumu anlatmaya çalıştım: “Çok çok uzaklarda bir yerde, Linux çalıştıran çok önemli, yalnız ve küçük bir yönlendirici var. Günde en az bir kez "canlı" olduğunu ve gerekirse ona "tatlım, yeniden başlat!" Gibi komutlar gönderildiğini bilmek önemlidir.

Uygulamaya geçelim:

1) Yönlendirici tarafında cron aracılığıyla her 5/10/1440 dakikada bir veya istediğiniz zaman wget kullanarak sunucuya http isteği göndermeniz, isteğin sonucunu bir dosyaya kaydetmeniz, dosyayı çalıştırılabilir hale getirmeniz gerekir. ve yürütün.

Cron çizgim şuna benziyor:

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

, nerede:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai sunucumun etki alanıdır. Hemen şunu belirteyim: evet, sunucunun belirli bir IP adresini belirtebilirsiniz, biz bunu devletimize kadar yapardık, haklı bir mücadele dürtüsüyle, bilmiyorum diyeceğim, aslanın erişimini engelledi. DigitalOcean ve Amazon “bulutlarının” payı. Sembolik bir etki alanı kullanıyorsanız, böyle bir olay meydana gelirse, kolayca bir yedekleme bulutu oluşturabilir, etki alanını ona yönlendirebilir ve cihaz izlemeyi geri yükleyebilirsiniz.

a.php sunucu tarafı betiğinin adıdır. Evet, değişkenleri ve dosya adlarını aynı harfle adlandırmanın yanlış olduğunu biliyorum... Bu şekilde istek gönderirken birkaç byte tasarruf etmemizi öneririm :)
u - kullanıcı adı, donanım girişi
p-şifre
“-O /tmp/wa.sh”, uzak yönlendiricideki sunucu yanıtının, örneğin yeniden başlatma komutunun kaydedileceği bir dosyadır.

İkinci not: Ahhh, neden curl yerine wget kullanıyoruz, çünkü curl aracılığıyla https isteklerini GET ile değil POST ile gönderebilirsiniz? Ahhh çünkü eski şakada olduğu gibi “NE kavanozun içine tırmanıyor!” curl, yaklaşık 2 MB boyutunda şifreleme kitaplıkları içerir ve bu nedenle, örneğin küçük bir TP-LINK ML3020 için bir görüntü oluşturmanız pek olası değildir. Ve wget ile - lütfen.

2) Sunucu tarafında (Ubuntu'm var) Zabbix'i kullanacağız. Neden: Güzel (grafiklerle) ve kullanışlı (bağlam menüsü aracılığıyla komutlar gönder) olmasını istiyorum. Zabbix'in zabbix ajanı gibi harika bir özelliği var. Aracı aracılığıyla, sunucuda yönlendiricimizin gerekli süre boyunca kayıtlı olup olmadığı hakkında bilgi döndürecek bir PHP betiği çağıracağız. Kayıt süresi ve cihazlara yönelik komutlar hakkında bilgi depolamak için, yaklaşık olarak aşağıdaki alanları içeren ayrı bir kullanıcı tablosu olan MySQL'i kullanıyorum:

		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;

Tüm kaynaklar şu adresteki Git deposundan indirilebilir: https://github.com/BazDen/iotnet.online.git
Artık PHP betikleri sunucu tarafına yerleştirildi (kolaylık olması açısından /usr/share/zabbix/ klasörüne yerleştirilebilirler):

a.php dosyası:

<?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 dosyası (bu, çağrılan zabbix aracısının komut dosyasıdır):

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

Son aşama: bir acentenin kaydedilmesi ve programların eklenmesi.

Zabbix aracısını henüz yüklemediyseniz:

apt-get install zabbix-agent

/etc/zabbix/zabbix_agentd.conf dosyasını düzenleyin.

Satırı ekleyin:

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

, nerede:
test acentemizin adıdır
“php /usr/share/zabbix/agent.php kullanıcı şifresi” - cihaz kayıt verilerini gösteren çağrılan bir komut dosyası.

Grafik ekleme: zabbix web arayüzünü açın, menüden seçim yapın:
Ayarlar -> Ağ düğümleri -> Bir ağ düğümü oluşturun. Burada ağ ana bilgisayarının adını, grubunu ve varsayılan aracı arayüzünü belirtmek yeterlidir:

Lunix/OpenWrt/Lede tabanlı cihazların port 80… üzerinden uzaktan izlenmesi ve kontrolü

Şimdi bu ağ düğümü için bir veri öğesi eklememiz gerekiyor. İki alana dikkat edin: "anahtar" - bu tam olarak /etc/zabbix/zabbix_agentd.conf dosyasında yazdığımız parametredir (bizim durumumuzda testtir) ve "güncelleme aralığı" - 5 dakikaya ayarladım , çünkü ekipman da her beş dakikada bir sunucuya kaydedilir.

Lunix/OpenWrt/Lede tabanlı cihazların port 80… üzerinden uzaktan izlenmesi ve kontrolü

Peki, bir grafik ekleyelim. Oluşturma stili olarak “Doldur”u seçmenizi öneririm.

Lunix/OpenWrt/Lede tabanlı cihazların port 80… üzerinden uzaktan izlenmesi ve kontrolü

Çıktı çok kısa ve öz bir şey, örneğin şöyle:

Lunix/OpenWrt/Lede tabanlı cihazların port 80… üzerinden uzaktan izlenmesi ve kontrolü

Mantıklı soruya: "Buna değdi mi?" Cevap vereceğim: elbette, makalenin başındaki "bisiklet yaratmanın nedenlerine" bakın.

İlk grafomani deneyimim okuyucuların ilgisini çekerse, sonraki makalelerde uzak ekipmanlara nasıl komut gönderileceğini anlatmak istiyorum. Ayrıca RouterOS (Mikrotik) tabanlı cihazlar için tüm şemayı uygulamayı başardık.

Kaynak: habr.com

Yorum ekle