Отдален мониторинг и управление устройства на базата на Linux/OpenWrt/Lede чрез 80-ти порт, продължение

Това е финалната част на статията, ето началото habr.com/bg/post/445568
В последния път писах как прилагам мониторинг на устройства, сега ще стане дума за управление. В дискусиите с 'техниците' от страна на Клиента често срещам ограничено възприятие на възможностите на такива малки устройства (с ниски ресурси на памет и производителност), много хора смятат, че 'максимумът, от който ще имаме нужда, е да изпратим reboot, за нещо по-сериозно — ще изпратим екип'.
Но практиката показва, че това не е съвсем така. Ето малък списък с чести типични задачи:

  1. Мрежова диагностика и отстраняване. Зад ethernet-порта на вашия рутер обикновено 'живее' друго устройство, което има свой собствен вътрешен ip-адрес. Понякога, то може (и трябва) да бъде 'пингнато'. Или управление на тунела — ако на рутера, работещ през 3G-модем, внезапно не се вдига тунел, но самият рутер го виждаме.
  2. Системно обслужване. Актуализация на фърмуера, ъпгрейд на служебните скриптове.
  3. Еквилибристика. Това можеше да се нарече 'извращения', но понятието 'еквилибристика' като, цитирам, 'способността на цирков артист да поддържа равновесие при нестабилно положение на тялото' — подхожда повече. Подобни ситуации възникват поради ограничения бюджет на клиента. По-долу представям няколко примера, но тъй като нямат пряко отношение към темата на разказа, ги изнесох в бележки.

Wi-Fi мониторингПоследните пет години актуална тема, основно сред федералните мрежи на търговията. Вие бавно се разхождате из магазините, а Вашият мобилен телефон с включен Wi-Fi редовно изпраща пакети Probe Request в опити да се свърже с някоя мрежа, които могат да се анализират, за да се определи: колко често посещавате този магазин, по какви маршрути се движите и т.н. След това данните се събират, анализират, създават се топлинни карти и мениджърите за такива графики "изстискват" пари от ръководството или инвеститорите. А междувременно... "парите ги няма, но вие се стараете...", а резултатът (реален) вече трябва да бъде показан, включва се старата добра песен "Да-да, после определено ще изнесем всичко необходимо, но сега трябва да покажем на Клиента резултата! Между другото, забравихме да споменем, че Клиентът разреши нашето оборудване да се свърже с неговия хотспот чрез Wi-Fi, но на общи начала, просто като че сме гости." И така се налага да правим роутери-еквилибристи — създават се няколко WiFi подинтерфейса, един от които се свързва с хотспота, а другият следи околната среда, втурвайки се да експортира резултата от tcpdump в себе си, след това съдържанието на файла се пакетира в архив и рискувайки да "преяжда" се опитва да изпрати съдържанието на FTP сървър. Не е изненадващо, че роутер-еквилиристите често "изпадат" и по някакъв начин трябва да бъдат възстановявани дистанционно.

RadiusТук е по-лесно да се опише ситуацията с следното твърдение от клиента: "Искаме децентрализирана мрежа от хотспотове, които да работят на оборудване, моделът на което не е известен предварително, през канали, за които все още не знаем. О, забравихме да споменем, не само искаме да показваме реклама на клиентите, но и да анализираме всичко около мястото на инсталиране на хотспота. Не, все още не знаем защо, но ще измислим, не се притеснявайте, успяхме да измислим тази идея."

И не бива да се забравя, че поради множество предопределени обстоятелства управлението трябва да се осъществява в нестандартни условия, когато не можем да се свържем с роутера директно през ip: порт и сме принудени просто да чакаме появата на активност от него. Ако се абстрахираме, диалогът между сървъра и роутера може да се представи по следния начин:

  • Роутер: привет. аз съм роутер такъв, имам ли задачи?
  • Сървър: рутер такъв, аз те регистрирах, че си жив. Ето задачата: покажи ми резултата от командата ifconfig?
  • Роутер: здравей. аз съм рутер такъв, миналия път поиска да покажа резултата от ifconfig, ето го. Има ли задачи за мен?
  • Сървър: рутер такъв, аз те регистрирах, че си жив. Нямам задачи за теб.

Най-интересният въпрос: как по-точно отдалеченият рутер може да изпрати определен обем информация? В предишната част описах, че на рутера заради ограничените ресурси има само 'осакатен' wget, който работи само чрез GET и нищо повече, няма нито FTP клиент, нито curl. По-точно, ни е нужен универсален начин, независимо от особеностите на сборката на образа. Застанах на решение с wget. По-точно, както 'застанах' — просто нямах избор 🙂

Веднага уточнявамМоето решение за управление е работещо, не е много ограничено и съм сигурен — неправилно, дори ако удовлетворява повечето от моите клиенти. Как БИ могло да се направи по-разумно — да се напише малка утилита, която изпраща бинарни данни чрез POST на 80-ти порт. Да я включим (утилитата) в състава на фърмуера на рутера и чрез bash да се обръщаме към нея. Но реалността е такава, че: а) трябва бързо б) може би всичко да е на съществуващия 'зоопарк от рутери' в) 'не вреди!' — ако рутерът работи и изпълнява други задачи, опитайте се да правите промени, които да не засегнат съществуващата функционалност.

Да преминем към реализацията. Да предположим, че вашият клиент иска от zabbix да рестартира рутера лесно и удобно, 'с клик на мишката'. Днес ще започнем описание на реализацията с zabbix.
В менюто 'Администриране' -> 'Скриптове' добавяме нов скрипт. Наравяме го 'Reboot', като команда пишем 'php /usr/share/zabbix/reboot.php {HOST.HOST}'

Отдален мониторинг и управление устройства на базата на Linux/OpenWrt/Lede чрез 80-ти порт, продължение

След това: Меню 'Мониторинг' -> 'Последни данни' -> 'Щракнете с десния бутон на нужния възел в мрежата'. Така ще изглежда менюто след добавянето на скрипта.

Отдален мониторинг и управление устройства на базата на Linux/OpenWrt/Lede чрез 80-ти порт, продължение
Съответно, скриптът reboot.php поставяме в директория /usr/share/zabbix (при вас може да е друга, аз използвам основната директория на zabbix).

Уточнение за безопасностЗа наглядност в обяснението на скрипта използвам само id на рутера, но не ползвам паролата. В работната версия така не е препоръчително! Защо го направих така: защото е важен въпрос — къде да се съхраняват паролите за рутерите? В самия Zabbix в «инвентарните данни»? Противоречива практика. Като вариант: да ограничим достъпа до самия файл reboot.php.

Файл reboot.php

set_charset("utf8");
	
	// "Изпращаме" командата reboot чрез промяна на полето task в таблицата users. В полето task може да се изпраща всяка команда.
	$sql_users=$conn->prepare("UPDATE users SET task='reboot' WHERE id=? AND status='active';");
	$sql_users->bind_param('s', $user);
	$sql_users->execute();
	$sql_users->close();
?>

Собственно всичко. Остава отворен въпросът „как да получим резултата от изпълнението на командата от страна на устройството“. Нека разгледаме задачата с примера на командата ifconfig. Можем да изпратим такава команда на устройството:

message=`ifconfig`; wget "http://xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai/a.php?u=user&p=password!&m=$message" -O /tmp/out.txt

, където:
message=`ifconfig` — задаваме на променливата $message резултата от изпълнението на командата ifconfig.
wget "xn--80abgfbdwanb2akugdrd3a2e5gsbj.xn--p1ai/a.php — нашият скрипт a.php, който регистрира рутерите и приема съобщения от тях.
u=user&p=password!&m=$message — идентификационни данни, а на параметъра m — присвоява стойността на променливата $message.
-O /tmp/out.txt — изходът в файл /tmp/out.txt в този случай не ни е нужен, но ако не посочим този параметър, wget не сработва.

Защо това не работи добре?Защото е потенциална дупка в сигурността. Най-невинната грешка, която може да се случи — е ако в изхода на вашата команда, например, има символ „&“. Затова е необходимо да се филтрира всичко, което се изпраща от рутерите и всичко, което идва на сървъра. Дааа, срам ме е, наистина. В своето оправдание мога само да напиша — че цялата статия е посветена на това как да управляваме рутери с неопределима предварително фърмуер, с неопределими предварително канали за свързване.

И задел за framtid: все още не съм разбрал как стандартно да отразявам резултатите (например, резултата от изпълнението на команди), които идват на сървера в zabbix.

Напомням, че всички изходни кодове могат да се вземат от Git хранилището на адрес: github.com/BazDen/iotnet.online.git

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster