Здраво свима, ово је моје прво искуство на Хабреу. Желим да пишем о томе како управљати мрежном опремом на спољној мрежи на нестандардан начин. Шта значи нестандардно: у већини случајева, за управљање опремом на спољној мрежи потребно вам је:
- Јавна ИП адреса. Па, или ако опрема стоји иза нечијег НАТ-а, онда јавни ИП и „прослеђени“ порт.
- Тунел (ППТП/ОпенВПН/Л2ТП+ИПСец, итд.) до централног чвора кроз који би био доступан.
Стога ће вам требати "мој бицикл" када вам стандардне методе не одговарају, на пример:
- Опрема се налази иза НАТ-а и, осим уобичајеног хттп (порт 80), све је затворено. Ово је сасвим нормална ситуација за велике федералне корпоративне мреже. Они могу да региструју портове, али не одмах, не брзо и не за вас.
- Нестабилан и/или „узак“ канал комуникације. Мала брзина, стални губици. Бол и фрустрација када покушавате да организујете тунел.
- Скуп комуникациони канал, где се буквално сваки мегабајт рачуна. На пример, сателитске комуникације. Плус дуга кашњења и „уски” опсег.
- Ситуација када треба да "жонглирате" великим бројем малих рутера, на којима је, с једне стране, инсталиран ОпенВрт/Леде за проширење могућности, а са друге стране, ресурси (меморија) рутера нису довољни за све.
Напомена број пута Шта вас спречава да инсталирате флеш диск у УСБ порт рутера и проширите меморију рутера?
Најчешће су захтеви за цену решења у целини, али понекад фактор форме такође игра кључну улогу. На пример, на сајту постоји ТП-Линк МЛ3020, његов једини УСБ порт се користи за 2Г/3Г модем, све је то умотано у неку врсту мале пластичне кутије и постављено негде високо, високо (на јарбол), далеко, далеко (на терену, 30 км од базне станице најближег мобилног оператера). Да, можете прикључити УСБ чвориште и проширити број портова, али искуство показује да је то гломазно и непоуздано.
Дакле, покушао сам да вам опишем своју типичну ситуацију: „негде далеко, далеко, постоји веома важан, усамљен и мали рутер који покреће Линук. Важно је бар једном дневно знати да је "жив" и, ако је потребно, шаљу му се команде, на пример, "душо, поново покрени!"
Пређимо на имплементацију:
1) На страни рутера, преко црон-а, сваких 5/10/1440 минута, или кад год желите, потребно је да пошаљете хттп захтев серверу користећи вгет, сачувате резултат захтева у датотеци, учините датотеку извршном , и извршите га.
Моја црон линија изгледа отприлике овако:
Фајл /етц/цронтабс/роот:
*/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
, где:
кн--80абгфбдванб2акугдрд3а2е5гсбј.кн--п1аи је домен мог сервера. Одмах да приметим: да, можете да наведете конкретну ИП адресу сервера, то смо радили све док наша држава, у праведном нагону борбе, рећи ћу, не знам, није блокирала приступ лавовском удео „облака” ДигиталОцеана и Амазона. Ако користите симболички домен, ако дође до таквог инцидента, можете лако да подигнете резервни облак, преусмерите домен на њега и вратите праћење уређаја.
а.пхп је име скрипте на страни сервера. Да, знам да је погрешно називати променљиве и називе фајлова истим словом... Предлажем да на овај начин сачувамо неколико бајтова приликом слања захтева :)
у - корисничко име, пријава на хардвер
п - лозинка
„-О /тмп/ва.сх“ је датотека на удаљеном рутеру у којој ће бити сачуван одговор сервера, на пример команда за поновно покретање.
Напомена број два: Аххх, зашто користимо вгет а не цурл, јер преко цурл-а можете слати хттпс захтеве не са ГЕТ-ом, већ са ПОСТ-ом? Аххх јер, као у старом вицу "НЕ се пење у теглу!" цурл укључује библиотеке за шифровање величине око 2МБ, и због тога је мало вероватно да ћете моћи да саставите слику за мали ТП-ЛИНК МЛ3020, на пример. А са вгет-ом - молим.
2) На страни сервера (имам Убунту) користићемо Заббик. Зашто: Желим да буде лепо (са графиконима) и згодно (шаљи команде преко контекстног менија). Заббик има тако дивну ствар као што је заббик агент. Преко агента ћемо на серверу позвати ПХП скрипту, која ће вратити информацију о томе да ли се наш рутер регистровао у потребном временском периоду. За чување информација о времену регистрације, командама за уређаје, користим МиСКЛ, посебну табелу корисника са приближно следећим пољима:
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;
Сви извори се могу преузети из Гит спремишта на:
Сада су ПХП скрипте постављене на страни сервера (ради погодности, могу се поставити у фасциклу /уср/схаре/заббик/):
а.пхп датотека:
<?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();
?>
Агент.пхп фајл (ово је скрипта заббик агента):
<?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();
?>
Па, последња фаза: регистрација агента и додавање распореда.
Ако још нисте инсталирали заббик агента, онда:
apt-get install zabbix-agent
Уредите датотеку /етц/заббик/заббик_агентд.цонф.
Додајте ред:
UserParameter=test,php /usr/share/zabbix/agent.php user password
, где:
тест је име нашег агента
“пхп /уср/схаре/заббик/агент.пхп корисничка лозинка” - позвана скрипта која указује на податке о регистрацији уређаја.
Додавање графикона: отворите заббик веб интерфејс, изаберите из менија:
Подешавања -> Мрежни чворови -> Креирајте мрежни чвор. Овде је довољно да наведете име мрежног хоста, његову групу и подразумевани интерфејс агента:
Сада морамо да додамо елемент података за овај мрежни чвор. Обратите пажњу на два поља: „кључ“ – то је управо параметар који смо написали у датотеку /етц/заббик/заббик_агентд.цонф (у нашем случају је тест), и „интервал ажурирања“ – поставио сам га на 5 минута , јер и опрема се такође региструје на серверу једном у пет минута.
Па, хајде да додамо графикон. Препоручујем да одаберете „Попуни“ као стил приказивања.
Излаз је нешто врло лаконски, на пример овако:
На разумно питање: "да ли је вредело?", одговорићу: па, наравно, погледајте "разлоге за стварање бицикла" на почетку чланка.
Ако моје прво графоманско искуство изазове интересовање читалаца, онда у следећим чланцима желим да опишем како да шаљем команде удаљеној опреми. Такође смо успели да имплементирамо целу шему за уређаје засноване на РоутерОС-у (Микротик).
Извор: ввв.хабр.цом