Lunix/OpenWrt/Lede oinarritutako gailuen urruneko monitorizazioa eta kontrola 80 atakaren bidez...

Kaixo guztioi, hau da Habré-n nire lehen esperientzia. Kanpoko sare batean sare-ekipoak modu ez-estandarran kudeatu nahi ditut. Zer esan nahi du ez estandarrak: kasu gehienetan, kanpoko sare batean ekipoak kudeatzeko behar duzu:

  • IP helbide publikoa. Beno, edo ekipamendua norbaiten NAT atzean badago, IP publikoa eta "birbidalitako" ataka bat.
  • Tunela (PPTP/OpenVPN/L2TP+IPSec, etab.) atzigarri izango litzatekeen erdiko nodoraino.

Hori dela eta, "nire bizikleta" beharko duzu metodo estandarrak egokitzen ez dituzunean, adibidez:

  1. Ekipamendua NAT atzean dago eta, ohiko http (80 ataka) izan ezik, dena itxita dago. Egoera guztiz normala da sare korporatibo federal handientzat. Portuak erregistra ditzakete, baina ez berehala, ez azkar, eta ez zuretzat.
  2. Komunikazio kanal ezegonkorra eta/edo “estua”. Abiadura baxua, etengabeko galerak. Mina eta frustrazioa tunel bat antolatzen saiatzean.
  3. Komunikazio kanal garestia, non literalki megabyte bakoitzak balio duen. Adibidez, satelite bidezko komunikazioak. Gainera atzerapen luzeak eta banda "estu" bat.
  4. Bideratzaile txiki ugari "malabareak" egin behar dituzun egoera, zeinetan, alde batetik, OpenWrt/Lede instalatuta dagoen gaitasunak zabaltzeko, eta, bestetik, bideratzailearen baliabideak (memoria) ez dira nahikoak. denetarako.

Kontuan izan zenbakiak aldiz Zerk eragozten dizu flash drive bat bideratzailearen USB atakan instalatzea eta bideratzailearen memoria zabaltzea?

Gehienetan, eskakizunak konponbide osoaren kostua dira, baina batzuetan forma-faktoreak ere funtsezko zeregina du. Adibidez, TP-Link ML3020 bat dago gunean, bere USB ataka bakarra 2G/3G modem baterako erabiltzen da, hau guztia plastikozko kaxa txiki batean bilduta dago eta nonbait altu, altu (mastan), urrun, urrun (eremuan, operadore mugikorren oinarrizko estaziotik 30 km-ra). Bai, USB hub bat konekta dezakezu eta ataka kopurua zabal dezakezu, baina esperientziak erakusten du astuna eta fidagarria ez dela.

Beraz, nire egoera tipikoa deskribatzen saiatu naiz: “nonbait urrun, urrun, Linux exekutatzen duen bideratzaile oso garrantzitsu, bakarti eta txiki bat dago. Garrantzitsua da egunean behin gutxienez jakitea "bizirik" dagoela eta, behar izanez gero, aginduak bidaltzen zaizkiola, adibidez, "eztia, berrabiarazi!"

Goazen ezarpenera:

1) Bideratzailearen aldean, cron bidez, 5/10/1440 minuturo edo nahi duzunean, http eskaera bidali behar diozu zerbitzariari wget erabiliz, eskaeraren emaitza fitxategi batean gorde, fitxategia exekutagarri bihurtu. , eta exekutatu.

Nire cron lerroak honelako itxura du:

/etc/crontabs/root fitxategia:

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

, non:
xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai nire zerbitzariaren domeinua da. Ohar nazazu berehala: bai, zerbitzariaren IP helbide zehatz bat zehaztu dezakezu, hau egiten genuen arte gure egoerak, borroka-bulkada zuzen batean, esango dut, ez dakit, lehoiaren sarbidea blokeatu arte. DigitalOcean eta Amazon "hodeien" kuota. Domeinu sinboliko bat erabiltzen baduzu, halako gertakari bat gertatzen bada, erraz sortu dezakezu babeskopia-hodeia, domeinua bertara birbideratu eta gailuaren jarraipena berrezarri.

a.php zerbitzariaren aldeko scriptaren izena da. Bai, badakit oker dagoela aldagaiak eta fitxategi-izenak letra berdinarekin izendatzea... Modu honetan eskaera bat bidaltzean byte batzuk gordetzea proposatzen dut :)
u - erabiltzaile-izena, hardware-saioa
p - pasahitza
"-O /tmp/wa.sh" urruneko bideratzailearen fitxategi bat da, non zerbitzariaren erantzuna gordeko den, adibidez, berrabiarazi komandoa.

Oharra bigarren zenbakia: Ahhh, zergatik erabiltzen dugu wget eta ez curl, curl bidez https eskaerak bidal ditzakezulako GET-rekin ez, POST-ekin baizik? Ahhh zeren, txiste zaharrean bezala "NE potora igotzen da!" curl-ek 2MB inguruko enkriptatze liburutegiak biltzen ditu eta horregatik nekez muntatu ahal izango duzu irudi bat TP-LINK ML3020 txiki baterako, adibidez. Eta wget-rekin - mesedez.

2) Zerbitzariaren aldetik (Ubuntu dut) Zabbix erabiliko dugu. Zergatik: ederra (grafikoekin) eta erosoa izatea nahi dut (komandoak laster-menuaren bidez bidali). Zabbix-ek zabbix agentea bezain gauza zoragarria du. Agentearen bidez, zerbitzarian PHP script-a deituko dugu, gure bideratzailea behar den denbora-tartean erregistratu den ala ez informazioa itzuliko duena. Erregistro-denborari eta gailuetarako komandoei buruzko informazioa gordetzeko, MySQL erabiltzen dut, gutxi gorabehera, eremu hauek dituen taula-erabiltzaile bereizi bat:

		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;

Iturburu guztiak Git biltegitik deskargatu daitezke hemen: https://github.com/BazDen/iotnet.online.git
Orain PHP scriptak zerbitzariaren aldean jarrita (erosotasunerako, /usr/share/zabbix/ karpetan jar daitezke):

a.php fitxategia:

<?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 fitxategia (hau da izeneko zabbix agentearen scripta):

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

Tira, azken etapa: agente bat erregistratzea eta ordutegiak gehitzea.

Oraindik ez baduzu zabbix agentea instalatu, orduan:

apt-get install zabbix-agent

Editatu /etc/zabbix/zabbix_agentd.conf fitxategia.

Gehitu lerroa:

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

, non:
test gure agentearen izena da
“php /usr/share/zabbix/agent.php erabiltzailearen pasahitza” - gailuaren erregistro-datuak adierazten dituen script-a.

Diagramak gehitzea: ireki zabbix web interfazea, hautatu menuan:
Ezarpenak -> Sare-nodoak -> Sortu sare-nodo bat. Hemen nahikoa da sareko ostalariaren izena, bere taldea eta agente interfaze lehenetsia zehaztea:

Lunix/OpenWrt/Lede oinarritutako gailuen urruneko monitorizazioa eta kontrola 80 atakaren bidez...

Orain sare-nodo honetarako datu-elementu bat gehitu behar dugu. Erreparatu bi eremuei: "gakoa" - hau da /etc/zabbix/zabbix_agentd.conf fitxategian idatzi dugun parametroa (gure kasuan proba da), eta "eguneratzeko tartea" - 5 minututan ezarri dut , zeren eta ekipoak ere zerbitzarian erregistratzen dira bost minuturo behin.

Lunix/OpenWrt/Lede oinarritutako gailuen urruneko monitorizazioa eta kontrola 80 atakaren bidez...

Beno, gehi dezagun grafiko bat. Errendatzeko estilo gisa "Bete" aukeratzea gomendatzen dut.

Lunix/OpenWrt/Lede oinarritutako gailuen urruneko monitorizazioa eta kontrola 80 atakaren bidez...

Irteera oso lakonikoa da, adibidez:

Lunix/OpenWrt/Lede oinarritutako gailuen urruneko monitorizazioa eta kontrola 80 atakaren bidez...

Arrazoizko galderari: "merezi al zuen?", erantzungo dut: ba, noski, ikusi "bizikleta bat sortzeko arrazoiak" artikuluaren hasieran.

Nire lehen esperientzia grafomanoak irakurleen interesa pizten badu, hurrengo artikuluetan komandoak urruneko ekipoetara nola bidali deskribatu nahi dut. RouterOS-en (Mikrotik) oinarritutako gailuetarako eskema osoa ezartzea ere lortu dugu.

Iturria: www.habr.com

Gehitu iruzkin berria