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

в 14:31, , рубрики: ddns, mikrotik, no-ip, noip, Сетевые технологии, системное администрирование

Прочитав множество руководств и примеров написания скрипта для работы 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.

На этом все!

Автор: Helldar

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js