Здравствуйте!
На написание данной статьи меня побудило прочтение аналогичного содержания статьи пользователя nkusnetsov. По количеству просмотров видно, что сообществу интересна данная тема.
Поэтому я решил поделиться с вами собственным решением, которое было ранее реализовано мной и обладает:
Если вас интересует данная тематика, сохраните статью в закладки, я буду периодически её обновлять, по мере расширения функционала скрипта.
UPD 1.0 – Код php обновлен. Теперь он включает логирование всех запросов к скрипту (можно вкл/выкл) и рандомную отправку сообщений через несколько шлюзов в случае указания больше одного.
UPD 1.1 – Проект выложен в репозиторий на GitHub. По отзыву в комментарии добавлена возможность отправки через платные sms-шлюзы (с возможностью указания для каждого роутера откуда отправлять – модем или платно, можно рандомно сочетать несколько путей отправки для одного роутера).
UPD 1.2 – Добавлена функция firewall – доступ к функции генерации и отправки кодов авторизации есть только у роутеров занесенных в список (можно вкл/выкл). Все ответы заменены на базовые коды ответов HTTP
UPD 1.3 – Отправка сообщений с кодом пользователям в Synology Chat и через Telegram Bot. Причем различным пользователям уведомления могут доставляться по различным каналам. Также упрощены и обновлены скрипты для MT
Внимание! Актуальный код скриптов для MikroTik, а также php можно получить на github – ссылка в конце. В статье приведен изначальный код, который не теряет актуальность, т.к описывает общую логику действий.
В процессе разработки данного решения была поставлена задача минимизировать количество usb-модемов – уменьшив стоимость владения, упростить администрирование, локализовать модемы в одном месте и тем самым улучшить ремонтопригодность системы.
Было решено использовать один роутер установленный на «надежном канале» как базовый SMS-шлюз. Единственное я не знал какова будет нагрузка на систему, справятся модемы и не заблокирует ли оператор. Поэтому я заложил возможность подключения нескольких модемов и дальнейшего разбиения системы на группы. Причем дополнительные модемы могут быть подключены к базовому шлюзу через простой usb-hub. Но для полноценного функционирования, в минимальном функционале, нужен один модем в не зависимости от количества роутеров.
Предусмотреть возможность использования локальных сим-карт в зоне установки роутера.
Пример: широкая филиальная сеть с несколькими магазинами в Казахстане. Отправка sms-сообщения из РФ будет стоить достаточно дорого. Данное решение позволяет сотрудникам из РК получать sms с локального номера.
Но в процессе размышлений оказалось, что решение уже было найдено и реализовано в Задаче 1.
Авторизация туннеля с мобильного устройства без необходимости физически находиться на авторизуемом устройстве.
Цель – возможность авторизовывать не только пользовательские туннели, но и любые vpn-соединения: Mikrotik->Mikrotik, Сервер->Mikrotik и т.д При этом пользователю, ответственному за данные туннели, необходимо просто перейти по ссылке из SMS сообщения, в которой также отображается какой туннель хочет авторизоваться.
Для возможности авторизации таким способом появилась необходимость вынести скрипт на внешний ресурс – сервер, доступный из любой точки а также код авторизации использовать для целей маркировки адресного листа в firewall и последующей разблокировки.
Решение данной задачи уже однозначно подразумевало использование RouterOS API (или SSH). Победу одержало API, как наиболее простой вариант.
Во всех остальных случаях, если что-то не прошло проверку пользователь получит Request error.
Теперь перейдем от идейной части к настройке Mikrotik, коду и их описанию
Пояснение: указанные скрипты и php-код работоспособны при любом типе VPN-сервера. Выбор типа сервера (PPP/L2TP/SSTP), настройки профиля и туннеля – вы выбираете «на свой вкус», я же приведу общий пример быстрой настройки.
Создаем профиль в котором устанавливаем idle-таймаут соединения. Время должно быть меньше чем указанное в следующем скрипте On Up, в противном случае, если авторизация не была произведена, то после удаления списка из address-list пользователь получит доступ на время равное разнице (idle-таймаут минус address-list timeout)
Далее на последней вкладке Script добавляем:
Смысл скриптов
При подключении: в самом начале мы задаем логин и пароль роутера, которые будут проверяться на сервере. При авторизации пользователя получаем его номер телефона (может быть в имени или в комментарии) и локальный ip-адрес. Отправляем POST-запрос на сервер и получаем в ответе код авторизации. Сервер записывает в лог данные поступившего запроса. Добавляем ip-адрес в address-list VPN-blocked с кодом авторизации в комментарии и тайм-аутом на 1 минуту больше чем в профиле. Выводим все в лог.
При отключении: получаем ip-адрес пользователя и его номер телефона, отправляем POST-запрос на сервер для сохранения в лог авторизации, находим его в address-list и удаляем. Все выводим в лог.
Номер телефона можно указать прямо в name, но если хотим иметь возможность задавать один номер на несколько аккаунтов (для авторизации нескольких туннелей), то номер указываем в комментарии, при этом в скрипте On Up нужно изменить закомментированность строк
Ну и самое главное включаем PPTP или L2TP сервер.
На этом с Mikrotik работа закончена.
Ниже приведен код. Он достаточно подробно комментирован, поэтому не буду писать лишний текст. Самое главное – заменить данные в $host и $ruid_data на свои.
Полный проект на GitHub
RouterOS API class PHP используемый в коде можно взять на GitHub.
Благодарю за внимание. Буду рад любым комментариям.
На написание данной статьи меня побудило прочтение аналогичного содержания статьи пользователя nkusnetsov. По количеству просмотров видно, что сообществу интересна данная тема.
Поэтому я решил поделиться с вами собственным решением, которое было ранее реализовано мной и обладает:
- Низким уровнем вхождения и простотой кода (для понимания/отладки другим сотрудником)
- Простые скрипты ROS не создают никакой нагрузки и работают даже на hAP Lite
- Масштабируемость – возможность подключения большого количества VPN-шлюзов с целью снижения нагрузки или географического распределения
- Возможность использования Mikrotik CHR в качестве VPN-сервера
- «1хN» – 1 SMS-шлюз на неограниченное количество роутеров с возможностью расширения при росте нагрузки
- Возможность привязки отдельного роутера к «конкретному» модему (для чего? – об этом позже)
- Использование всего одного php скрипта на удаленном сервере
- Не важно какое устройство инициировало VPN-соединение, авторизация по ссылке из SMS
- Ведение log'а всех авторизаций на сервере (можно вкл/выкл)
- Увеличение отказоустойчивости и снижение нагрузки системы путем отправки SMS рандомно с нескольких модемов
- Возможность отправки SMS через платные SMS-шлюзы (в коде на примере smsc.ru)
- Функция Firewall – доступ только у роутеров занесенных в список (можно вкл/выкл)
- Новое: Отправка кодов через Synology Chat и Telegram Bot. Причем различным пользователям уведомления могут доставляться по различным каналам.
Если вас интересует данная тематика, сохраните статью в закладки, я буду периодически её обновлять, по мере расширения функционала скрипта.
UPD 1.0 – Код php обновлен. Теперь он включает логирование всех запросов к скрипту (можно вкл/выкл) и рандомную отправку сообщений через несколько шлюзов в случае указания больше одного.
UPD 1.1 – Проект выложен в репозиторий на GitHub. По отзыву в комментарии добавлена возможность отправки через платные sms-шлюзы (с возможностью указания для каждого роутера откуда отправлять – модем или платно, можно рандомно сочетать несколько путей отправки для одного роутера).
UPD 1.2 – Добавлена функция firewall – доступ к функции генерации и отправки кодов авторизации есть только у роутеров занесенных в список (можно вкл/выкл). Все ответы заменены на базовые коды ответов HTTP
UPD 1.3 – Отправка сообщений с кодом пользователям в Synology Chat и через Telegram Bot. Причем различным пользователям уведомления могут доставляться по различным каналам. Также упрощены и обновлены скрипты для MT
Внимание! Актуальный код скриптов для MikroTik, а также php можно получить на github – ссылка в конце. В статье приведен изначальный код, который не теряет актуальность, т.к описывает общую логику действий.
Постановка задачи и решение
Задача 1
В процессе разработки данного решения была поставлена задача минимизировать количество usb-модемов – уменьшив стоимость владения, упростить администрирование, локализовать модемы в одном месте и тем самым улучшить ремонтопригодность системы.
Было решено использовать один роутер установленный на «надежном канале» как базовый SMS-шлюз. Единственное я не знал какова будет нагрузка на систему, справятся модемы и не заблокирует ли оператор. Поэтому я заложил возможность подключения нескольких модемов и дальнейшего разбиения системы на группы. Причем дополнительные модемы могут быть подключены к базовому шлюзу через простой usb-hub. Но для полноценного функционирования, в минимальном функционале, нужен один модем в не зависимости от количества роутеров.
Задача 2
Предусмотреть возможность использования локальных сим-карт в зоне установки роутера.
Пример: широкая филиальная сеть с несколькими магазинами в Казахстане. Отправка sms-сообщения из РФ будет стоить достаточно дорого. Данное решение позволяет сотрудникам из РК получать sms с локального номера.
Но в процессе размышлений оказалось, что решение уже было найдено и реализовано в Задаче 1.
Задача 3
Авторизация туннеля с мобильного устройства без необходимости физически находиться на авторизуемом устройстве.
Цель – возможность авторизовывать не только пользовательские туннели, но и любые vpn-соединения: Mikrotik->Mikrotik, Сервер->Mikrotik и т.д При этом пользователю, ответственному за данные туннели, необходимо просто перейти по ссылке из SMS сообщения, в которой также отображается какой туннель хочет авторизоваться.
Для возможности авторизации таким способом появилась необходимость вынести скрипт на внешний ресурс – сервер, доступный из любой точки а также код авторизации использовать для целей маркировки адресного листа в firewall и последующей разблокировки.
Решение данной задачи уже однозначно подразумевало использование RouterOS API (или SSH). Победу одержало API, как наиболее простой вариант.
Логика
- Пользователь авторизуется с заранее добавленным логином и паролем
- VPN-шлюз заносит его ip в адресный лист ожидания и отправляет POST запрос на сервер
- Сервер получает данные, проверяет, формирует код-авторизации и отправляет на контактный номер SMS вида: «To autorize user 79001112233 connection open – http_://synome.ru/?ruid=vrG7yYMbZ6&auth=YU6zc»
- Пользователь переходит по ссылке с любого устройства
- Сервер делает запрос на роутер, проверяет наличие в адрес-листе записи с кодом авторизации в комментарии. Если запись найдена, удаляет ее, а пользователю отображает страницу удачной авторизации
Во всех остальных случаях, если что-то не прошло проверку пользователь получит Request error.
Настройка и код
Теперь перейдем от идейной части к настройке Mikrotik, коду и их описанию
Пояснение: указанные скрипты и php-код работоспособны при любом типе VPN-сервера. Выбор типа сервера (PPP/L2TP/SSTP), настройки профиля и туннеля – вы выбираете «на свой вкус», я же приведу общий пример быстрой настройки.
Добавляем на Mikrotik:
Firewall
Обязательно создаем список разрешенных ресурсов, среди которых: собственный адрес MT, любой публичный DNS, адрес сервера на котором будет происходить авторизация
/ip firewall address-list
add address=10.10.0.1 list=Allow-list
add address=8.8.8.8 list=Allow-list
add address=synome.ru list=Allow-list
Добавляем правило блокирующее трафик VPN-пользователей из списка ожидания на любой хост кроме разрешенных
/ip firewall raw
add action=drop chain=prerouting dst-address-list=!Allow-list src-address-list=VPN-blocked disabled=no
PPP Profile
Создаем профиль в котором устанавливаем idle-таймаут соединения. Время должно быть меньше чем указанное в следующем скрипте On Up, в противном случае, если авторизация не была произведена, то после удаления списка из address-list пользователь получит доступ на время равное разнице (idle-таймаут минус address-list timeout)
Добавляем профиль
/ppp profile
add dns-server=10.10.0.1 idle-timeout=59m local-address=10.10.1.1 name=2F-VPN use-compression=no use-encryption=no use-mpls=no
Далее на последней вкладке Script добавляем:
On Up
:global ruid "#ROUTERLOGIN#";
:global pass "#ROUTER_PASSWORD#";
:local userip [/ppp active get [find name=$user] address];
# if phone number stored in comment
#:local userphone [/ppp secret get [find name=$user] comment];
# if phone number = username
:local userphone $user;
:local authkey [/tool fetch http-method=post http-data="ruid=$ruidlogin&pass=$ruidpass&tel=$userphone&remote-ip=$userip" url="http://synome.ru/" mode=http as-value output=user];
/ip firewall address-list remove [find address=$userip];
/ip firewall address-list add address=$userip list=VPN-blocked timeout=1h comment=($authkey->"data");
:log info message="User connect:";
:log info message=$userphone;
:log info message=$userip;
:log info message=($authkey->"data");
On Down
:global ruid "#ROUTERLOGIN#";
:global pass "#ROUTER_PASSWORD#";
:local userip $"remote-address";
# if phone number stored in comment
:local userphone [/ppp secret get [find name=$user] comment];
# if phone number = username
#:local userphone $user;
/tool fetch http-method=post http-data="ruid=$ruidlogin&pass=$ruidpass&tel=$userphone&action=down&remote-ip=$userip" url="http://synome.ru/" mode=http as-value output=user;
/ip firewall address-list remove [find address=$userip];
:log info message="User disconnect:";
:log info message=$user;
:log info message=$userip;
Смысл скриптов
При подключении: в самом начале мы задаем логин и пароль роутера, которые будут проверяться на сервере. При авторизации пользователя получаем его номер телефона (может быть в имени или в комментарии) и локальный ip-адрес. Отправляем POST-запрос на сервер и получаем в ответе код авторизации. Сервер записывает в лог данные поступившего запроса. Добавляем ip-адрес в address-list VPN-blocked с кодом авторизации в комментарии и тайм-аутом на 1 минуту больше чем в профиле. Выводим все в лог.
При отключении: получаем ip-адрес пользователя и его номер телефона, отправляем POST-запрос на сервер для сохранения в лог авторизации, находим его в address-list и удаляем. Все выводим в лог.
PPP Secrets
Добавляем пользователя
/ppp secret
add comment="70001112233" name=70001112233 password=testuser profile=2F-VPN remote-address=10.10.1.100
Номер телефона можно указать прямо в name, но если хотим иметь возможность задавать один номер на несколько аккаунтов (для авторизации нескольких туннелей), то номер указываем в комментарии, при этом в скрипте On Up нужно изменить закомментированность строк
Изменение (вторую открываем, четвертую закрываем)
# if phone number stored in comment
:local userphone [/ppp secret get [find name=$user] comment];
# if phone number = username
#:local userphone $user;
Ну и самое главное включаем PPTP или L2TP сервер.
На этом с Mikrotik работа закончена.
Серверная часть на PHP
Ниже приведен код. Он достаточно подробно комментирован, поэтому не буду писать лишний текст. Самое главное – заменить данные в $host и $ruid_data на свои.
Полный проект на GitHub
index.php
<?php
// ------------------------------------------------------------------------------
// Copyright (с) 2020
// Author: Dmitri Agababaev, d.agababaev@duncat.net
//
// Copyright by authors for used RouterOS PHP API class in the source code files
//
// Redistributions and use of source code, with or without modification, are
// permitted that retain the above copyright notice
//
// License: MIT
// ------------------------------------------------------------------------------
require_once('routeros_api.class.php');
// https://github.com/BenMenking/routeros-api
// -------------------------
// Базовые настройки скрипта
// Base settings
// -------------------------
// Firewall - разрешает доступ к отправке SMS только роутерам из массива $ruid_data | Firewall - allow access to send SMS only for router from array $ruid_data
$firewall = true; // Используем firewall? | Use firewall? true | false
$uselog = true; // Используем лог? | Use log? true | false
$log_path = 'mt2Fvpn.log'; // Путь к файлу лога | Log file path
$host = 'https://yourwebsite.com/'; // Адрес по которому доступен данный скрипт | Full address that this script awalible
// Массив данных всех роутеров/vpn-шлюзов | Routers data array used as vpn-servers
$ruid_data = array(
// пароль в md5, глобальный ip-адрес, логин входа на роутер, пароль, SMS-шлюз через который происходит отправка SMS
// password in md5, global ip-address, mikrotik login, password, SMS-gateway-key will be use to send sms
'#ROUTERLOGIN#' => array('mdpass' => '#ROUTER_MD5_PASSWORD#',
'ip' => 'XXX.XXX.X.X',
'login' => '#ROSAPI_LOGIN#',
'password' => '#PASSWORD#',
'smsgw' => array(
// Если необходимо отправлять SMS рандомно с нескольких шлюзов (снижение нагрузки на модем)
// If you want send SMS randomly from any SMS-gateways, add one here (low modem load)
0 => 'SMS_gw1')
)
);
// Массив данных роутеров используемых в качестве sms-шлюзов | Routers data array will be used to send autherization sms
$SMS_gateway = array(
// ip-адрес шлюза (глобальный или локальный если в одной сети с сервером), логин, пароль, порт USB-модема, канал USB-модема
// ip-address (global or local if used in one local network with server), login, password, USB-modem port, USB-modem channel
'SMS_gw1' => array('ip' => 'XXX.XXX.X.X', 'login' => '#ROSAPI_LOGIN#', 'password' => '#PASSWORD#', 'port' => '#USB_PORT#', 'channel' => '#USB_CHANNEL#')
);
// -------------------------
// Входные проверки запросов
// Input data check
// -------------------------
if (!$_REQUEST) die(header('HTTP/1.0 406 Not Acceptable')); // если запроса нет – сброс | if request free - reset
if (!$_REQUEST['ruid']) die(header('HTTP/1.0 406 Not Acceptable')); // если не указан ruid - сбросс | if ruid not isset – reset
if (!array_key_exists($_REQUEST['ruid'], $ruid_data)) die(header('HTTP/1.0 406 Not Acceptable')); // если роутер не существует – сброс | if router does not exist – reset
if ($_REQUEST['auth']) autorize(); // если запрос на авторизацию, то пускаем без пароля и проверяем авторизацию | if auth request allow without password
if (!ruid_auth()) die(header('HTTP/1.0 401 Unauthorized')); // проверяем пароль роутера для отправки SMS | check ruid password
if (@$_REQUEST['action'] == 'down') { // Если vpn-соединение закрыто | if vpn-connection closed
writelog('CONNECTION CLOSED');
die(header('HTTP/1.0 200 ОК'));
}
if ($_REQUEST['tel']) send_authcode(); // если задан номер телефона, отправляем SMS | if phone number isset – sending SMS
// ---------------------------------------------------------------------
// Проверка на наличие роутера в списке разрешенных и пароля авторизации
// Check for router (ruid) is in allowed list
// ---------------------------------------------------------------------
function ruid_auth() {
global $ruid_data;
if (!$_REQUEST['pass']) return false; // если пароль не задан – сброс | if password not set - reset
// проверяем md5-хэш пароля | check password md5-hash
if (md5($_REQUEST['pass']) == $ruid_data[$_REQUEST['ruid']]['mdpass']) return true;
return false;
}
// ---------------------------------------------------------
// Функция отправки ссылки с кодом авторизации через ros api
// Send autherization sms via ros api function
// ---------------------------------------------------------
function send_authcode() {
global $ruid_data;
global $host;
global $firewall;
// Если firewall == true, то разрешаем доступ к отправке только роутрам внесенным в массив $ruid_data
// If firewall == true, allow access only to routers has record in array $ruid_data
if ($firewall) firewall();
// Выбираем шлюз рандомно | Get random SMS-gateway
$sms_gw = $ruid_data[$_REQUEST['ruid']]['smsgw'][array_rand($ruid_data[$_REQUEST['ruid']]['smsgw'], 1)]; // данные sms-шлюза
// генерируем код авторизации и добавляем его в массив | Generate auth-code and add to REQUEST array
$_REQUEST['authcode'] = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ123456789'), 0, 5);
// Формируем сообщение отправляемое пользователю – только eng или транслит
// Create message that will be sent to user
$message = rawurlencode('To authorize user '.$_REQUEST['tel'].' connection open '.$host.'?ruid='.$_REQUEST['ruid'].'&auth='.$_REQUEST['authcode']);
// Если используем платный sms шлюз | If use paid sms center gateway
if ($sms_gw == "PAY") UsePAYsmsc($message);
// подключаем класс | connect class
$API = new RouterosAPI();
// если подключились отправляем SMS | if connected successfully - sending message
if ($API->connect($SMS_gateway[$sms_gw]['ip'], $SMS_gateway[$sms_gw]['login'], $SMS_gateway[$sms_gw]['password'])) {
// Команда отправки SMS | SMS send command
$ARRAY = $API->comm("/tool/sms/send", array(
"port"=>$SMS_gateway[$sms_gw]['port'],
"channel"=>$SMS_gateway[$sms_gw]['channel'],
"phone-number"=>$_REQUEST['tel'],
"message"=>"To autorize user ".$_REQUEST['tel']." connection open – ".$host."?ruid=".$_REQUEST['ruid']."&auth=".$_REQUEST['authcode'],));
// если отправка не удалась и получили ошибку модема, то выполняем сброс питания usb для перезагрузки модема
// Checking if send failed and error message return, will make usb power-reset to restart modem
if($ARRAY['!trap']) {
$API->comm("/system/routerboard/usb/power-reset");
// логируем запросы | save log
// добавляем в массив сообщение об ошибке | Add error to array and save all array to log
$_REQUEST['ERROR'] = $ARRAY['!trap'][0]['message'];
writelog('MODEM ERROR');
die('Stop with error: '.$ARRAY['!trap'][0]['message'].' Making power reset of usb-port');}
}
$API->disconnect();
// логируем запросы | save log
writelog('SEND AUTH CODE');
die($_REQUEST['authcode']);
}
// --------------------------------------------------------------------
// Функция авторизации через ros api – удаление из address-list
// Autherization using ros api function – delete list from address-list
// --------------------------------------------------------------------
function autorize() {
global $ruid_data;
// подключаем класс | connect class
$API = new RouterosAPI();
if ($API->connect($ruid_data[$_REQUEST['ruid']]['ip'], $ruid_data[$_REQUEST['ruid']]['login'], $ruid_data[$_REQUEST['ruid']]['password'])) {
// если подключились отправляем команду | if connected successfully - sending command
$API->write('/ip/firewall/address-list/print', false);
$API->write('?comment='.$_REQUEST['auth'], false);
$API->write('=.proplist=.id');
// получаем ответ | get response
$ARRAYS = $API->read();
// Если запись не существует в адрес-листе - сброс
// If no record in firewall address_list – reset
if (!$ARRAYS[0]) die(header('HTTP/1.0 406 Not Acceptable'));
// удаляем запись | delete firewall address-list
$API->write('/ip/firewall/address-list/remove', false);
$API->write('=.id=' . $ARRAYS[0]['.id']);
$READ = $API->read();
}
$API->disconnect();
// логируем запросы | save log
writelog('AUTHERIZATION');
// Информируем пользователя об успешной авторизации | Show success page to user
die('
<!DOCTYPE html>
<html lang="ru">
<meta http-equiv="Content-Type" content="charset=utf-8" />
<body style="font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #282c34; color: #fff; height: 100vh; display: flex;">
<div style="margin: auto; max-width: 50%;">
<p style="font-size: 24pt; font-weight: bold; margin: 0 0 10px;">
VPN-соединение установлено, можете продолжить работу<br />
</p>
<p style="font-size: 12pt; color: #aaa;">
В случае недоступности сервисов обратитесь к вашему системному администратору<br />
</p>
<p style="font-size: 24pt; font-weight: bold; margin: 100px 0 10px;">
VPN connection is established, you can continue to work
</p>
<p style="font-size: 12pt; color: #aaa;">
If any services unavalible you must contact with your system administrator<br />
</p>
</div>
</body>
</html>
');
}
// ---------------------------------------------------------------------------------------------------------------------
// Отправка sms через платный сервис отправки сообщений (значение smsgw в $ruid_data должно быть установлено 0 => «pay»)
// Send sms via paid sms center gateway (smsgw value in $ruid_data should be installed 0 => «pay»)
// ---------------------------------------------------------------------------------------------------------------------
function UsePAYsmsc($message) {
// для примера использован smsc.ru | for example i use smsc.ru
$smsc_login = '#SMSCLOGIN#';
$smsc_pass = '#SMSCPASSWORD#';
$smsc_sendername = '#SMSCSENDERNAME#'; // если используется | if need
// Отправляем SMS | SEND SMS
$sms_send = file_get_contents('https://smsc.ru/sys/send.php?login='.$smsc_login.'&psw='.$smsc_pass.'&phones='.$_REQUEST['tel'].'&mes='.$message.'&sender='.$smsc_sendername.'&flash=0');
if (strpos($sms_send, 'OK') !== false) {
die($_REQUEST['authcode']);
}
die($_REQUEST['Send SMS error']);
};
// --------------------------------------------------------------------------------
// Firewall - разрешает доступ к отправке SMS только роутерам из массива $ruid_data
// Firewall - allow access to send SMS only for router from array $ruid_data
// --------------------------------------------------------------------------------
function firewall() {
global $uselog;
global $log_path;
global $ruid_data;
$result = false;
// перебираем массив и ищем ip в $ruid_data | serch ip in array $ruid_data
foreach ($ruid_data as $value) {
$result = (in_array($_SERVER['REMOTE_ADDR'], $value) === true) ? true : false;
if($result) break; // если нашли совпадение, прерываем | if found record – break
}
// $uselog == true сохраняем лог | save log
if (!$result) {
if ($uselog) {
$fp = fopen($log_path, 'a');
fputs($fp, "\nTime = " . date("Y-m-d H:i:s")."\n");
fputs($fp, 'FIREWALL BLOCKED ACCESS'."\n");
fputs($fp, $_SERVER['REMOTE_ADDR']."\n");
fclose($fp);
}
die(header('HTTP/1.0 403 Forbidden'));
}
}
// ------------------------
// Функция сохранения логов
// Save log function
// ------------------------
function writelog($type) {
global $uselog;
global $log_path;
// $uselog == false – break
if (!$uselog) return;
// удаляем пароль из массива перед сохранением лога | remove ruid password from array before saving log
unset($_REQUEST['pass']);
// сохраняем лог | save log
$fp = fopen($log_path, 'a');
fputs($fp, "\nTime = " . date("Y-m-d H:i:s")."\n");
fputs($fp, $type."\n");
fputs($fp, print_r($_REQUEST, true));
fclose($fp);
}
?>
RouterOS API class PHP используемый в коде можно взять на GitHub.
Благодарю за внимание. Буду рад любым комментариям.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Какие каналы уведомлений добавить?
90.91% Telegram30
12.12% Synology Chat4
24.24% E-mail8
Проголосовали 33 пользователя. Воздержался 1 пользователь.