[recovery mode] Скрипт автоматического обновления DDNS для No-IP

Прочитав множество руководств и примеров написания скрипта для работы Mikrotik с сервисом noip.com, так и не удалось найти готового решения.
Что не устраивало в других руководствах, например, здесь:
при написании необходимо прямо в тексте скрипта указывать имя интерфейса, с которого он будет получать внешний IP-адрес, а что если интерфейсов два, три или десять?
В моем случае имеется 2 канала: pppoe-client и ethernet без пароля, но с динамически получаемым адресом…
Также в роутах имеется 2 записи с «dst. address» равным »0.0.0.0/0» с дистанциями »1» и »2» соответственно.

image

Вначале необходимо перебрать все роуты, найдя в них записи с «dst. address» равным »0.0.0.0/0», после этого провести проверку активности интерфейса (: if ([get $counter active] = true)).
Таким образом, мы получим имя активного интерфейса и запоминаем его в локальную переменную «activeInterface».

:local activeInterface;
/ip route {
    :local gwintarray;
    :local counter;
    :local intfinder;
    :foreach counter in=[find dst-address=0.0.0.0/0] do={
        :if ([get $counter active] = true) do={
            :set $activeInterface [get $counter gateway];
        }
    }
}

После этого нам необходимо перебрать все записи таблицы /ip address и найти одну с названием искомого интерфейса.
Полученный адрес будет содержать маску подсети, которую мы сразу же и отсечем.

:local activeAddress;
/ip address {
    :set $activeAddress [get [find interface=$activeInterface] address];
    :set $activeAddress [:pick $activeAddress 0 [:find $activeAddress "/"]];
}

image

После этого пропишем данные для подключения к сервису NO-IP:

:local ddnsuser "your_no-ip_user";
:local ddnspass "your_no-ip_pass";
:local ddnshost "hostname.no-ip.org";

:local str "/nic/update?hostname=$ddnshost&myip=$activeAddress";
/tool fetch url="http://dynupdate.no-ip.com/$str" mode=http user=$ddnsuser password=$ddnspass \ dst-path=("/ServiceDNS.".$ddnshost);

где:
ddnsuser — логин в системе NO-IP
ddnspass — пароль в системе NO-IP
ddnshost — доменное имя, для которого необходимо обновить IP-адрес

И передадим информацию на сервис, скачав файл с ответом:

:local str "/nic/update?hostname=$ddnshost&myip=$activeAddress";
/tool fetch url="http://dynupdate.no-ip.com/$str" mode=http user=$ddnsuser password=$ddnspass \ dst-path=("/ServiceDNS.".$ddnshost);

После этого ожидаем 2 секунды и выводим содержимое файла (статус обновления IP-адреса), после чего удалим его.

:delay 2;
:local str [/file find name="ServiceDNS.$ddnshost"];
:log info [/file get $str contents];
/file remove $str

ВНИМАНИЕ!!! В руководстве используется глобальная переменная »previousIP», запоминающая предыдущий IP-адрес.
Если адрес глобальной переменной совпадает с вновь полученным, скрипт ничего обновлять на сервисе не будет.

МИНУС такого метода: заходим на сайт noip.com и вручную меняем IP-адрес. А скрипт микротика это никак не отслеживает. Так что в моем примере эта переменная просто исключена.

Полный код скрипта можно взять здесь
# Получаем имя интерфейса
# Get interface name
:local activeInterface;
/ip route {
    :local gwintarray;
    :local counter;
    :local intfinder;
    :foreach counter in=[find dst-address=0.0.0.0/0] do={
        :if ([get $counter active] = true) do={
            :set $activeInterface [get $counter gateway];
        }
    }
}

# Пролучаем IP адрес активного интерфейса
# Get IP-address of actived interface
:local activeAddress;
/ip address {
    :set $activeAddress [get [find interface=$activeInterface] address];
    :set $activeAddress [:pick $activeAddress 0 [:find $activeAddress "/"]];
}

# Информация об аккаунте NO-IP
# No-IP User account info
:local ddnsuser "your_no-ip_user";
:local ddnspass "your_no-ip_pass";
:local ddnshost "hostname.no-ip.org";

# Обновляем данные
# Updating data on NO-IP
:local str "/nic/update?hostname=$ddnshost&myip=$activeAddress";
/tool fetch url="http://dynupdate.no-ip.com/$str" mode=http user=$ddnsuser password=$ddnspass \ dst-path=("/ServiceDNS.".$ddnshost);

# Ждем 2 секунды
# Wait 2 seconds
:delay 2

# Выводим информацию о статусе обновления и удаляем скачанный файл
# Displays information about the status of the update and delete the downloaded file
:local str [/file find name="ServiceDNS.$ddnshost"];
:log info [/file get $str contents];
/file remove $str


Ниже информация для новичков
Для добавления скрипта в Mikrotik нужно открыть меню «System» > «Scripts» и добавить новый скрипт, нажав на значок «плюса», и называем скрипт, например,»update-ddns»

image

Осталось добавить правило запуска скрипта в планировщик. Для этого идем в «System» > «Scheduler» и нажимаем на знакомый нам «плюс».
В имени указываем имя правила в планировщике.
В поле »On Event» указываем имя нашего скрипта — »update-ddns», выставляем правила запуска и нажимаем »ОК».

В моем случае запуск скрипта производится каждую 61 секунду.

image

P.S.: Скрипт тестировался на Mikrotik RB850Gx2 (ядро powerpc) с прошивкой версии 6.33.5.
Также без всяких проблем запускается на Mikrotik RB450G и RB951G-2HnD с прошивкой версии 6.33.5.

На этом все!

© Habrahabr.ru