Скрипт предназначен для удаленного включения или выключения USB-модема, подключенного к MikroTik. Помимо этого он умеет тестировать поднятый канал, сбрасывать модем и, при необходимости, подключать удаленный доступ к WebFig. Естественно, для работы удаленного доступа модем должен иметь белый IP.
Инициализация функций, используемых в скрипте. Эти функции вводятся скриптом «variable-initialization»!
:global sendEvent; :global pingSession; :global ispLogging;
Эти переменные также вводятся скриптом «variables-initialization».
:global pppNumber; :global pingCount;
Настройка имени для удаленного доступа. Может не существовать в системе, тогда будет создано автоматически.
:local remoteName dasha;
Прочие нужные переменные.
:local interfaceName [/interface ppp-client get $pppNumber name]; :local pingCountTotal ($pingCount * 2);
Локальная функция простого генератора пин-кодов, основанного на текущей дате и времени, приправленные некоторым количеством псевдослучайных чисел. Используется для удаленного доступа к WebFig.
:local pinGen do={ :local hourTemp ([:pick [/system clock get time] 0 2]); :local minuteTemp ([:pick [/system clock get time] 3 5]); :local secondTemp ([:pick [/system clock get time] 6 8]); :local dayTemp ([:pick [/system clock get date] 4 6]); :local arbitraryNumber 485; :local pickTemp; :set pickTemp ([:pick $secondTemp 0]); :local secondPick0 ([:pick "9563575442" $pickTemp]); :set pickTemp ([:pick $secondTemp 1]); :local secondPick1 ([:pick "9715837939" $pickTemp]); :set pickTemp ([:pick $minuteTemp 1]); :local minutePick1 ([:pick "8419467984" $pickTemp]); :set pickTemp; :local randomPick (($secondPick0 . $secondPick1 . $minutePick1)); :local tempPin (($hourTemp+$minuteTemp+$secondTemp+$dayTemp+$randomPick)*($hourTemp+$dayTemp+$arbitraryNumber)); :return $tempPin; }
Включает модем и отчитывается посредством SMS.
:if ( $mode = "on" ) do={ /interface ppp-client { :if ( [get $pppNumber disable] = true ) do={ :log info ("Connecting modem via SMS command."); :do { set $pppNumber disable=no } on-error={ :log warning ("Interface enabled at the second attempt!"); set $pppNumber disable=no; } :delay 10s; $sendEvent mode=sms msg="Modem connected!"; } else={ $sendEvent mode=sms msg="Modem is already connected!"; } } }
В версии RouterOS 6.46.3
(про другие не знаю) есть баг из-за которого, если в списке PPP интерфейсов есть только модем, он с первой попытки не включается, только со второй. Поэтому пришлось вводить костыль. Как только в списке их стало больше одного, добавилась постоянно подключенная VPN сессия, ошибка пропала!
:if ( $mode = "off" ) do={ /interface ppp-client { :if ( [get $pppNumber disable] = false ) do={ set $pppNumber disable=yes; :log info ("Disconnecting modem via SMS command."); $sendEvent mode=sms msg="Modem disconnected!"; } else={ $sendEvent mode=sms msg="Modem is already disconnected!"; } } }
Проверяет, поднят ли модем. Если нет то сообщает об этом и выходит. Если модем поднят, делает несколько сессий тестирования, пишет это в лог и отправляет результат в SMS.
:if ( $mode = "test" ) do={ /interface ppp-client { :if ( [get $pppNumber disable] = true ) do={ $sendEvent mode=sms msg="Modem disconnected!"; } else={ :local pingStatus; :set pingStatus [ $pingSession pingFrom=$interfaceName ]; :local pingResult1 $pingStatus; $ispLogging outInt=$interfaceName receivedPing=$pingStatus totalPing=$pingCountTotal startMode="test-modem-sms" newFileAt=month; :delay 2s; :set pingStatus [ $pingSession pingFrom=$interfaceName ]; $ispLogging outInt=$interfaceName receivedPing=$pingStatus totalPing=$pingCountTotal startMode="test-modem-sms" newFileAt=month; :local txtMsg "Received ping's:\r\nfirst test - $pingResult1/$pingCountTotal,\r\nsecond test - $pingStatus/$pingCountTotal"; $sendEvent mode=sms msg=$txtMsg; } } }
Пытается сделать USB Power reset
и отправить SMS, если не получилось, отправляет Email.
:if ( $mode = "reset" ) do={ :local smsError "Failed to enable SMS reception after modem reset!"; :log warning ("Starting USB power reset via SMS command..."); $sendEvent mode=sms msg="Power reset started..."; :do { /interface ppp-client set $pppNumber disable=yes; } on-error={} :delay 10s; :do { /tool sms set receive-enabled=no; } on-error={} :delay 10s; /system routerboard usb power-reset duration=10s; :delay 30s; :do { /tool sms set receive-enabled=yes; } on-error={ $sendEvent mode=mail body=$smsError; :error "$smsError"; } :delay 10s; $sendEvent mode=sms msg="Power reset complited!"; }
При получении соответствующей команды происходит следующее:
Если команда на включение удаленного доступа отсутствует происходит следующее:
Отдельной команды на выключение нет, т.к. оно выполняется при получении любых команд, кроме ping
.
:if ( [/interface ppp-client get $pppNumber disable] = false && $remote = "on" ) do={ :local tempPin; :do { /user set $remoteName disable=no; } on-error={ /user add name="$remoteName" group="full" password="485158" disabled=no; } :set tempPin [$pinGen]; /user set $remoteName password="$tempPin"; :local pppAddress [/ip address get [find interface="$interfaceName"] address ]; :local pppClearAddr ([:pick $pppAddress 0 [:find $pppAddress "/"]]); /ip service set www-ssl disable=no; /ip firewall filter set [find comment~"id4534233"] disabled=no; :local txtMsg "WebFig: https://$pppClearAddr; User: $remoteName, Password: $tempPin"; $sendEvent mode=sms msg=$txtMsg; } else={ :if ( $mode != "test" ) do={ :do { /user set $remoteName disable=yes; } on-error={}; /ip service set www-ssl disable=yes; /ip firewall filter set [find comment~"id4534233"] disabled=yes; :local txtMsg "User \"$remoteName\", WWW-service, FireWall filter rule and WebFig disabled!"; $sendEvent mode=sms msg=$txtMsg; } }
/system script add comment="\D3\E4\E0\EB\E5\ED\ED\EE\E5 \F3\EF\F0\E0\E2\EB\E5\ED\E8\E5 3G \EC\ \EE\E4\E5\EC\EE\EC \F1 \EE\F2\EF\F0\E0\E2\EA\EE\E9 SMS" \ dont-require-permissions=no name=modem owner=petya policy=\ ftp,read,write,policy,test,password,sensitive source="# Written by Nikolay\ \_Soloshin (nikolay@soloshin.su) for RouterOS v6.46.3 on RB3011UiAS (arm) \ @ 2020.03\r\ \n\r\ \n# Functions used in the script. They are entered by the script \"variabl\ e-initialization\" when the device starts!\r\ \n:global sendEvent;\r\ \n:global pingSession;\r\ \n:global ispLogging;\r\ \n\r\ \n# These variables are set by the script \"variables-initialization\" whe\ n the device starts!\r\ \n:global pppNumber;\r\ \n:global pingCount;\r\ \n\r\ \n# Local variables set and used only by this script.\r\ \n# Remote control username\r\ \n:local remoteName dasha;\r\ \n\r\ \n# Local variables used in the script.\r\ \n:local interfaceName [/interface ppp-client get \$pppNumber name];\r\ \n:local pingCountTotal (\$pingCount * 2);\r\ \n\r\ \n# Function. Simple pincode generator.\r\ \n:local pinGen do={\r\ \n :local hourTemp ([:pick [/system clock get time] 0 2]);\r\ \n :local minuteTemp ([:pick [/system clock get time] 3 5]);\r\ \n :local secondTemp ([:pick [/system clock get time] 6 8]);\r\ \n :local dayTemp ([:pick [/system clock get date] 4 6]);\r\ \n :local arbitraryNumber 977;\r\ \n :local pickTemp;\r\ \n :set pickTemp ([:pick \$secondTemp 0]);\r\ \n :local secondPick0 ([:pick \"2346712653\" \$pickTemp]);\r\ \n :set pickTemp ([:pick \$secondTemp 1]);\r\ \n :local secondPick1 ([:pick \"5269938717\" \$pickTemp]);\r\ \n :set pickTemp ([:pick \$minuteTemp 1]);\r\ \n :local minutePick1 ([:pick \"4746588836\" \$pickTemp]);\r\ \n :set pickTemp;\r\ \n :local randomPick ((\$secondPick0 . \$secondPick1 . \$minutePick1))\ ;\r\ \n :local tempPin ((\$hourTemp+\$minuteTemp+\$secondTemp+\$dayTemp+\$r\ andomPick)*(\$hourTemp+\$dayTemp+\$arbitraryNumber));\r\ \n :return \$tempPin;\r\ \n}\r\ \n\r\ \n# SMS command to turn on the modem\r\ \n:if ( \$mode = \"on\" ) do={\r\ \n /interface ppp-client {\r\ \n :if ( [get \$pppNumber disable] = true ) do={\r\ \n :log info (\"Connecting modem via SMS command.\");\r\ \n :do { set \$pppNumber disable=no } on-error={\r\ \n :log warning (\"Interface enabled at the second attempt!\");\r\ \n set \$pppNumber disable=no; }\r\ \n :delay 10s;\r\ \n \$sendEvent mode=sms msg=\"Modem connected!\";\r\ \n } else={ \$sendEvent mode=sms msg=\"Modem is already connected!\";\ \r\ \n }\r\ \n }\r\ \n}\r\ \n\r\ \n# SMS command to turn off the modem\r\ \n:if ( \$mode = \"off\" ) do={\r\ \n /interface ppp-client {\r\ \n :if ( [get \$pppNumber disable] = false ) do={\r\ \n set \$pppNumber disable=yes;\r\ \n :log info (\"Disconnecting modem via SMS command.\");\r\ \n \$sendEvent mode=sms msg=\"Modem disconnected!\";\r\ \n } else={ \$sendEvent mode=sms msg=\"Modem is already disconnected!\ \";\r\ \n }\r\ \n }\r\ \n}\r\ \n\r\ \n# SMS command for testing communication through a modem\r\ \n:if ( \$mode = \"test\" ) do={\r\ \n /interface ppp-client {\r\ \n :if ( [get \$pppNumber disable] = true ) do={\r\ \n \$sendEvent mode=sms msg=\"Modem disconnected!\";\r\ \n } else={\r\ \n :local pingStatus;\r\ \n :set pingStatus [ \$pingSession pingFrom=\$interfaceName ];\r\ \n :local pingResult1 \$pingStatus;\r\ \n \$ispLogging outInt=\$interfaceName receivedPing=\$pingStatus to\ talPing=\$pingCountTotal startMode=\"test-modem-sms\" newFileAt=month;\r\ \n :delay 2s;\r\ \n :set pingStatus [ \$pingSession pingFrom=\$interfaceName ];\r\ \n \$ispLogging outInt=\$interfaceName receivedPing=\$pingStatus to\ talPing=\$pingCountTotal startMode=\"test-modem-sms\" newFileAt=month;\r\ \n :local txtMsg \"Received ping's:\\r\\nfirst test - \$pingResult1\ /\$pingCountTotal,\\r\\nsecond test - \$pingStatus/\$pingCountTotal\";\r\ \n \$sendEvent mode=sms msg=\$txtMsg;\r\ \n }\r\ \n }\r\ \n}\r\ \n\r\ \n# SMS command for hardware reset of the modem\r\ \n:if ( \$mode = \"reset\" ) do={\r\ \n :local smsError \"Failed to enable SMS reception after modem reset!\";\ \r\ \n :log warning (\"Starting USB power reset via SMS command...\");\r\ \n \$sendEvent mode=sms msg=\"Power reset started...\";\r\ \n :do { /interface ppp-client set \$pppNumber disable=yes; } on-error={}\ \r\ \n :delay 10s;\r\ \n :do { /tool sms set receive-enabled=no; } on-error={}\r\ \n :delay 10s;\r\ \n /system routerboard usb power-reset duration=10s;\r\ \n :delay 30s;\r\ \n :do { /tool sms set receive-enabled=yes; } on-error={\r\ \n \$sendEvent mode=mail body=\$smsError;\r\ \n :error \"\$smsError\"; }\r\ \n :delay 10s;\r\ \n \$sendEvent mode=sms msg=\"Power reset complited!\";\r\ \n}\r\ \n\r\ \n# SMS command to enable remote access (access is turned off automaticall\ y when sending any commands except ping)\r\ \n:if ( [/interface ppp-client get \$pppNumber disable] = false && \$remot\ e = \"on\" ) do={\r\ \n :local tempPin;\r\ \n :do { /user set \$remoteName disable=no; } on-error={\r\ \n /user add name=\"\$remoteName\" group=\"full\" password=\"485158\" d\ isabled=no; }\r\ \n :set tempPin [\$pinGen];\r\ \n /user set \$remoteName password=\"\$tempPin\";\r\ \n :local pppAddress [/ip address get [find interface=\"\$interfaceName\"\ ] address ];\r\ \n :local pppClearAddr ([:pick \$pppAddress 0 [:find \$pppAddress \"/\"]]\ );\r\ \n /ip service set www-ssl disable=no;\r\ \n /ip firewall filter set [find comment~\"id4534233\"] disabled=no;\r\ \n :local txtMsg \"WebFig: https://\$pppClearAddr; User: \$remoteName, Pa\ ssword: \$tempPin\";\r\ \n \$sendEvent mode=sms msg=\$txtMsg;\r\ \n } else={\r\ \n :if ( \$mode != \"test\" ) do={\r\ \n :do { /user set \$remoteName disable=yes; } on-error={};\r\ \n /ip service set www-ssl disable=yes;\r\ \n /ip firewall filter set [find comment~\"id4534233\"] disabled=yes;\ \r\ \n :local txtMsg \"User \\\"\$remoteName\\\", WWW-service, FireWall f\ ilter rule and WebFig disabled!\";\r\ \n \$sendEvent mode=sms msg=\$txtMsg; }\r\ \n }\r\ \n\r\ \n# With love from Vladivostok."
Скрипт запускается через SMS на номер модема с синтаксисом :cmd 12345 script modem mode=variable [remote=on]
, где 12345
, это секрет, назначенный при настройке приема SMS, а variable
- одна из поддерживаемых переменных.
Это минимально необходимый набор для работы скрипта.
Обсуждение