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

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

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

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

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

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

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

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

Незабавно уточнениеМоето решение за управление е работещо, не е много ограничено и съм сигурен — криво, дори и да удовлетворява повечето от моите клиенти. Как БИ могло да бъде направено както трябва — да се напише малка утилита, която чрез 80-ия порт изпраща бинарни данни с POST. Да я включим в състава на фърмуера на рутера и след това чрез 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 не сработва

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

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

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

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

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