Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • Changelogs
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Настройка
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    RouterOS
    Ещё один скрипт для преобразования DHCP в DNS

    Ещё один скрипт для преобразования DHCP в DNS

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    Ещё один скрипт для преобразования DHCP в DNS, RouterOS
     
    dse
    Guest
    #1
    0
    10.03.2017 20:51:00
    Этот скрипт предназначен для работы в качестве lease-скрипта DHCP-сервера и управляет (регистрирует или удаляет) статические DNS-записи в соответствии с выделением или истечением аренды DHCP. Скрипт регистрирует только полностью квалифицированные доменные имена (FQDN). Часть имени хоста в регистрируемом FQDN — это значение свойства «host-name» аренды или свойства «comment», если «host-name» пустое. Часть домена — это значение свойства «domain» соответствующей сети DHCP-сервера. Скрипт не регистрирует DNS-записи с некорректными FQDN, у которых пустая или неопределённая часть хоста или домена. Также скрипт не регистрирует DNS-запись, если запись с таким же IP-адресом или FQDN уже существует в статической DNS-базе маршрутизатора. Управляемые скриптом статические DNS-записи имеют тег #DHCP в комментарии, чтобы отличать их от созданных вручную. TTL регистрируемой DNS-записи совпадает с TTL соответствующей аренды DHCP. При истечении аренды DHCP скрипт удаляет соответствующую DNS-запись с таким же IP-адресом, помеченную комментарием #DHCP. Скрипт логирует различные ошибки и информационные сообщения с тегом DHCP2DNS. Логируемые сообщения понятны сами по себе. Скрипт должен быть создан как стандартный системный скрипт. Чтобы скрипт запускался для данного DHCP-сервера, его имя должно быть назначено свойству «lease-script» этого сервера. Исходный код далее:

    :local DHCPtag  
    :set DHCPtag "#DHCP"

    :if ( [ :len $leaseActIP ] <= 0 ) do={ :error "пустой адрес аренды" }

    :if ( $leaseBound = 1 ) do=\
    {
     :local ttl  
     :local domain  
     :local hostname  
     :local fqdn  
     :local leaseId  
     :local comment

     /ip dhcp-server  
     :set ttl [ get [ find name=$leaseServerName ] lease-time ]
     network  
     :set domain [ get [ find $leaseActIP in address ] domain ]
     
     .. lease  
     :set leaseId [ find address=$leaseActIP ]

     # Проверка на множественные активные аренды для одного IP. Странно, но на всякий случай.

     :if ( [ :len $leaseId ] != 1) do=\
     {  
      :log info "DHCP2DNS: не регистрируем доменное имя для адреса $leaseActIP из-за множественных активных аренд для $leaseActIP"  
      :error "множественные активные аренды для $leaseActIP"  
     }  

     :set hostname [ get $leaseId host-name ]
     :set comment [ get $leaseId comment ]
     /

     :if ( [ :len $hostname ] <= 0 ) do={ :set hostname $comment }

     :if ( [ :len $hostname ] <= 0 ) do=\
     {  
       :log error "DHCP2DNS: не регистрируем доменное имя для адреса $leaseActIP из-за пустого host-name или comment аренды"  
       :error "пустое host-name или comment аренды"  
     }  
     :if ( [ :len $domain ] <= 0 ) do=\
     {  
       :log error "DHCP2DNS: не регистрируем доменное имя для адреса $leaseActIP из-за пустого доменного имени сети"  
       :error "пустое доменное имя сети"  
     }

     :set fqdn "$hostname.$domain"
     
     /ip dns static  
     :if ( [ :len [ find name=$fqdn and address=$leaseActIP and disabled=no ] ] = 0 ) do=\
     {  
       :log info "DHCP2DNS: регистрируем статическое доменное имя $fqdn для адреса $leaseActIP с ttl $ttl"  
       add address=$leaseActIP name=$fqdn ttl=$ttl comment=$DHCPtag disabled=no  
     } else=\
     {  
       :log error "DHCP2DNS: не регистрируем доменное имя $fqdn для адреса $leaseActIP, так как уже существует активная статическая DNS-запись с таким именем или адресом"  
     }  
     /
    } \
    else=\
    {
     /ip dns static  
     :local dnsDhcpId  
     :set dnsDhcpId [ find address=$leaseActIP and comment=$DHCPtag ]

     :if ( [ :len $dnsDhcpId ] > 0 ) do=\
     {  
       :log info "DHCP2DNS: удаляем статическое доменное имя(ена) для адреса $leaseActIP"  
       remove $dnsDhcpId  
     }  
     /
    }
     
     
     
    neutronlaser
    Guest
    #2
    0
    12.09.2020 18:56:00
    Кто-нибудь, выложите самый свежий и лучший скрипт на вики.
     
     
     
    mniewiera
    Guest
    #3
    0
    03.12.2019 20:04:00
    Думаю, с вашим DNS всё в порядке, раз он работал через winbox. Значит, на ваших клиентских устройствах в качестве DNS-сервера стоит 9.9.9.9? Если да, то так не сработает. Потому что 9.9.9.9 не может разрешать ваши внутренние DNS-записи. Это может делать только Mikrotik. Если DNS установлен на 9.9.9.9, и эта настройка приходит с DHCP-сервера, тогда нужно изменить то, что им назначается. Я так понимаю, ваш DHCP-сервер — тоже Mikrotik? Если да, то нужно поправить конфигурацию DHCP-сервера на Mikrotik. Так как сейчас у меня нет доступа к устройству Mikrotik, не могу точно сказать, куда там заходить. Но на вики Mikrotik, скорее всего, есть полезная статья по этому вопросу. Так что пока вам изучать, как работает DNS, не обязательно. По моему мнению, проблема именно в DHCP.
     
     
     
    Ameeno
    Guest
    #4
    0
    03.02.2020 06:33:00
    Здравствуйте, это сломано? При запуске скрипта появляется следующая ошибка: «empty lease address». Похоже, это связано со значением: if ( [ :len $leaseActIP ] <= 0 ) do={ :error “empty lease address” }. Возможно, Mikrotik изменил, удалил или переименовал эту переменную?
     
     
     
    willianwrm
    Guest
    #5
    0
    15.04.2020 16:41:00
    В долгосрочной версии 6.45.8 всё работает отлично. Нужно поместить этот скрипт в Lease Script DHCP-сервера — он будет вызываться автоматически при выдаче новых аренды. Единственное, что я заметил — скрипт не запускается при продлении адреса (после истечения срока), а только когда хост запрашивает новую аренду.
     
     
     
    sebaz
    Guest
    #6
    0
    26.04.2020 12:48:00
    Публикую это, возможно, кому-то поможет. На моём RouterOS v6.46.5 у меня были проблемы со скриптом: в логах появлялись сообщения вроде DHCP2DNS: не регистрируется доменное имя для адреса xxx.yyy.> www.zzz > из-за пустого lease host-name или комментария у некоторых устройств. Оказалось, что имя хоста не считывалось в таком вызове: set hostname [ get $leaseId host-name ], поэтому я решил добавить строку: if ( [ :len $hostname ] <= 0 ) do={ :set hostname $"lease-hostname" }. В итоге в скрипте получилось так:

    if ( [ :len $hostname ] <= 0 ) do={ :set hostname $comment }

    if ( [ :len $hostname ] <= 0 ) do={ :set hostname $"lease-hostname" }
     
     
     
    RackKing
    Guest
    #7
    0
    02.07.2020 16:32:00
    Кто-нибудь имеет обновлённую версию этого? У меня оно не работает на 6.47. Спасибо.
     
     
     
    jbl42
    Guest
    #8
    0
    05.07.2020 19:50:00
    Спасибо за скрипт. Он определённо должен быть в официальной документации. Я создал немного изменённую версию:

    Удаляю пробелы и символы \00 из имён хостов в DHCP-лизах перед объединением с доменом для формирования полного DNS-имени (FQDN). Некоторые DHCP-клиенты, в моём случае умные коммутаторы Zyxel, регистрируются с именами хостов, содержащими пробелы и завершающие символы \00 (скорее всего, это ошибка прошивки Zyxel).

    Генерирую имя хоста для DHCP-клиентов с пустыми именами, чтобы создать статическую DNS A-запись для всех клиентов. Большинство устройств на Android начиная с версии 8 не передают имена хостов в DHCP-запросах. Мне нравится, когда для всех клиентов работает DNS.

    Делаю префикс логов настраиваемым:  
    :local DHCPtag   "#*# Created by DHCP2DNS #*#"  
    :local LogPrefix "DHCP2DNS ($leaseServerName)"

    ###  
    # Функции

    # Удаляет \0 и пробелы из строки, переданной как inStr=<строка>  
    :local trimString do=\
    {  
     :local outStr  
     :for i from=0 to=([:len $inStr] - 1) do=\
     {  
       :local tmp [:pick $inStr $i];
       :if (($tmp !=" ") and ($tmp !="\00")) do=\
       {  
         :set outStr ($outStr . $tmp)  
       }  
     }  
     :return $outStr  
    }

    # "a.b.c.d" -> "a-b-c-d" для IP-адресов, используемых как заменитель отсутствующих имён хостов  
    :local ip2Host do=\
    {  
     :local outStr  
     :for i from=0 to=([:len $inStr] - 1) do=\
     {  
       :local tmp [:pick $inStr $i];
       :if ($tmp =".") do=\
       {  
         :set tmp "-"  
       }  
       :set outStr ($outStr . $tmp)  
     }  
     :return $outStr  
    }

    ###  
    # Точка входа скрипта  
    # Ожидаемые переменные окружения:  
    # leaseBound         1 = лиз добавлен, 0 = лиз удалён  
    # leaseServerName    имя DHCP-сервера  
    # leaseActIP         IP-адрес DHCP-клиента

    :if ( [ :len $leaseActIP ] <= 0 ) do=\
    {  
     :log error "$LogPrefix: пустой IP-адрес лиза"  
     :error "пустой IP-адрес лиза"  
    }

    :if ( $leaseBound = 1 ) do=\
    {  
     # новый лиз DHCP добавлен

     /ip dhcp-server  
     :local ttl [ get [ find name=$leaseServerName ] lease-time ]
     network  
     :local domain [ get [ find $leaseActIP in address ] domain ]
     :set domain [ $trimString inStr=$domain ]

     .. lease  
     :local leaseId [ find address=$leaseActIP ]

     # Проверяем наличие нескольких активных лизов с одним IP. Это странно и не должно быть, но на всякий случай.  
     :if ( [ :len $leaseId ] != 1) do=\
     {  
       :log warning "$LogPrefix: Несколько активных DHCP-лизов для '$leaseActIP' (???)"  
       :error "Несколько активных DHCP-лизов для '$leaseActIP' (???)"  
     }  
     :local hostname [ get $leaseId host-name ]
     :set hostname [ $trimString inStr=$hostname ]
     
     :if ( [ :len $hostname ] <= 0 ) do=\
     {  
       :set hostname [ $ip2Host inStr=$leaseActIP ]
       :log info "$LogPrefix: Пустое имя хоста для '$leaseActIP', используем сгенерированное имя '$hostname'"  
     }  
     :if ( [ :len $domain ] <= 0 ) do=\
     {  
       :log warning "$LogPrefix: Пустое доменное имя для '$leaseActIP', не могу создать статическое DNS-имя"  
       :error "Пустое доменное имя для '$leaseActIP'"  
     }

     :local fqdn ($hostname . "." .  $domain)

     /ip dns static  
     :if ( [ :len [ find name=$fqdn and address=$leaseActIP and disabled=no ] ] = 0 ) do=\
     {  
       add address=$leaseActIP name=$fqdn ttl=$ttl comment=$DHCPtag disabled=no  
       :log info "$LogPrefix: Статическое доменное имя '$fqdn' создано для '$leaseActIP' с ttl '$ttl'"  
     }\
     else=\
     {  
       :log warning "$LogPrefix: '$fqdn' уже существует, не могу создать статическое DNS-имя для '$leaseActIP'"  
       :error "$LogPrefix: '$fqdn' уже существует"  
     }  
    }\
    else=\
    {  
     # DHCP-лиз удалён

     /ip dns static  
     :local dnsDhcpId  
     :set dnsDhcpId [ find address=$leaseActIP and comment=$DHCPtag ]
     :if ( [ :len $dnsDhcpId ] > 0 ) do=\
     {  
       remove $dnsDhcpId  
       :log info "$LogPrefix: Статические DNS-имена для '$leaseActIP' удалены"  
     }  
    }

    Для большей гибкости этот скрипт можно сохранить как /system script. Это позволит использовать один и тот же скрипт на всех DHCP-серверах для удобства поддержки, просто добавив небольшой обёрточный скрипт в свойство lease script сервера DHCP:

    :local scriptName "dhcp2dns.rsc"  
    :do {  
     :local scriptSrc [ /system script get [ find name=$scriptName ] source ]
     :local scriptObj [ :parse $scriptSrc ]
     $scriptObj leaseBound=$leaseBound leaseServerName=$leaseServerName leaseActIP=$leaseActIP  
    } on-error={ :log warning "Ошибка скрипта lease сервера DHCP '$leaseServerName'" };

    Тестировалось на RB4011 V6.47.1
     
     
     
    HiltonT
    Guest
    #9
    0
    11.07.2020 07:25:00
    Согласен.
     
     
     
    Smoerrebroed
    Guest
    #10
    0
    07.09.2020 08:16:00
    Отличный скрипт! Единственная проблема, с которой я столкнулся, — он автоматически устанавливает одинаковое время аренды для всех (даже для статических) лизов, а так может быть не всегда. Поэтому я заменил

    /ip dhcp-server  
    :set ttl [ get [ find name=$leaseServerName ] lease-time ]
    network  

    на

    /ip dhcp-server lease  
    :set ttl [ get [ find address=$leaseActIP ] lease-time ]
    /ip dhcp-server network  

    Кроме этого, большое спасибо за участие и помощь!
     
     
     
    Smoerrebroed
    Guest
    #11
    0
    10.09.2020 10:57:00
    Хорошо, я заметил, что с моим изменением в кеш DNS создаются только те аренды, у которых установлен собственный lease-time, поэтому используйте вместо этого:

    /ip dhcp-server lease  
    :set ttl [get [find address=$leaseActIP] lease-time]
    :if ([:len $ttl] <= 0) do={
       /ip dhcp-server  
       :set ttl [get [find name=$leaseServerName] lease-time]
    }
     
     
     
    nescafe2002
    Guest
    #12
    0
    10.09.2020 12:06:00
    На самом деле устанавливать TTL DNS равным времени аренды не имеет смысла и только приводит к неожиданному поведению, особенно при длительных периодах аренды.
     
     
     
    phin
    Guest
    #13
    0
    11.02.2018 04:25:00
    Это именно то, что мне было нужно. Спасибо. Всё работает как и ожидалось.
     
     
     
    emk2203
    Guest
    #14
    0
    15.08.2018 12:06:00
    Гораздо лучший сценарий, чем все предыдущие. Это точно должно быть в вики.
     
     
     
    xrlls
    Guest
    #15
    0
    13.01.2019 18:04:00
    Отлично! Именно то, что мне было нужно!
     
     
     
    dca1
    Guest
    #16
    0
    31.08.2019 12:01:00
    Кто-нибудь может подсказать, что я здесь делаю не так? Я разместил этот скрипт в разделе «Lease Script» в окне настройки DHCP-сервера. Я вижу, что аренды обновляются, но при этом ничего не добавляется в статические DNS-записи. Я также пробовал добавить скрипт отдельно и в качестве Lease Script указать команду /system script run dhcptodns. Просто не понимаю, как это правильно настроить...
     
     
     
    dca1
    Guest
    #17
    0
    01.09.2019 10:46:00
    В итоге сам же и ответил на свой вопрос. Скрипт выдавала ошибку, потому что у меня не был задан локальный домен. Задал — и теперь все работает. Большое спасибо.
     
     
     
    revamp
    Guest
    #18
    0
    03.12.2019 12:20:00
    Нужна помощь. Я только что перешёл на MikroTik, и этот пост — именно то, что мне было нужно. После добавления скрипта я вижу в логах, что FQDN имена установлены правильно. Но с клиентов пинг по FQDN не проходит (пинг просто по имени хоста работает нормально).

    Вот моя конфигурация: ether4 (10.9.7.0/24) с назначенным скриптом и доменом «rev.local». Есть две машины на Windows со статическими адресами:
    M1 – 10.9.7.11
    M2 – 10.9.7.12

    Машины получают правильные IP, но DNS-сервер у них установлен 9.9.9.9 (на WAN-интерфейсе).

    Когда с M1 пробую:
    ping M2.rev.local — не разрешается…
    ping M2 — возвращается 10.9.7.2 и пинг проходит нормально.

    То же самое с M2.

    Однако из терминала winBox на обеих машинах M1 и M2 пинг по M1.rev.local и M2.rev.local проходит без проблем.

    Ещё одно наблюдение: есть M3 без статического адреса (получает 10.9.8.131) — с неё пингуются M1 и M2, но не M1.rev.local.

    Что-то я упускаю?
     
     
     
    mniewiera
    Guest
    #19
    0
    03.12.2019 17:31:00
    Насколько я понимаю, ваша проблема в том, что машины (m1, m2 и m3) используют 9.9.9.9 в качестве DNS-сервера. Им нужно использовать mikrotik как DNS-сервер. Тогда они смогут разрешать m1.rev.local, а запросы DNS для публичных доменов (например, google.com) будут перенаправляться на 9.9.9.9. Думаю, вы даже можете пинговать m1 или m2, но .rev.local берётся из службы WINS. (Если я правильно понимаю, у вас Windows в качестве операционной системы?) Вы можете изменить DNS-сервер, который они получают, в разделе DHCP.
     
     
     
    revamp
    Guest
    #20
    0
    03.12.2019 17:47:00
    Спасибо за ответ. На Windows-машинах настройки DNS получают автоматически через DHCP, WINS включён, но на моём старом DD-WRT всё прекрасно работало. Нужно разобраться, как настроить внутренний DNS (есть какие-то советы?).
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2026 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры