Mikrotik DNS и DHCP для Active Directory

В версии 6.47 RouterOS Mikrotik наконец добавил возможность заводить в DNS разные типы записей — CNAME, FWD, MX, NS, NSDOMAIN, SRV и TXT (раньше были только А- и АААА-записи). А это значит, что теперь роутер можно использовать в качестве DNS для домена Active Directory с возможностью переноса на него и DHCP-сервера тоже.

Если открыть на доменном контроллере панель управления dns и посмотреть настройки зоны домена — вы увидите несколько десятков SRV-записей, указывающих на доменный контроллер. Клиентские машины обращаются за ними к dns-серверу в попытке выяснить, какой сервер является доменным контроллером для указанном на них домене: запрашивая SRV-записи с разными значениями, в ответ они получают FQDN-имя доменного контроллера, которое резолвится в ip через запись типа А.

Я не ставил себе задачу разбирать смысл каждой записи в рамках этого поста, но (при желании) это всё можно нагуглить. В этой заметке я приведу набор SRV-записей, которого достаточно для стабильной работы домена с перенесенными на Mikrotik DNS и DHCP.

Итак, на вашем роутере уже настроены DNS- и DHCP-серверы (отдельно на этом пункте останавливаться нет смысла, вокруг полно статей на эту тему). В примерах ниже — на микротике настроен ip 10.0.0.1/24 (который является для клиентов и шлюзом, и dns-сервером), а доменный контроллер имеет имя controller.koobik.lan и ip 10.0.0.2. Сначала добавим А-запись для контроллера:

/ip dns static add address=10.0.0.2 name=controller.koobik.lan type=A

Теперь добавим SRV-записи для Active Directory:

/ip dns static
add name=domains._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.dc._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.default-first-site-name._sites.gc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.default-first-site-name._sites.dc._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.Default-First-Site-Name._sites.controller.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.controller._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.default-first-site-name._sites.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.controller.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.gc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_kerberos._tcp.koobik.lan srv-port=88 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_kerberos._tcp.default-first-site-name._sites.koobik.lan srv-port=88 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_kerberos._tcp.default-first-site-name._sites.dc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_kerberos._tcp.dc._msdcs.koobik.lan srv-port=88 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_kerberos._udp.koobik.lan srv-port=88 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_kpasswd._tcp.koobik.lan srv-port=464 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_kpasswd._udp.koobik.lan srv-port=464 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_tcp.Default-First-Site-Name._sites.dc._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_tcp.Default-First-Site-Name._sites.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_tcp.default-first-site-name._sites.gc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_tcp.gc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=default-first-site-name._sites.gc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=gc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_gc._tcp.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_gc._tcp.default-first-site-name._sites.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_sites.gc._msdcs.koobik.lan srv-port=3268 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_vlmcs._tcp.koobik.lan srv-port=1688 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV

Теперь клиентские машины домена могут без проблем найти в сети доменный контроллер. Однако, помимо имени, контроллер создаёт несколько уникальных ID домена и в классическом варианте так же помещает их в dns. Отловить их можно в IP — DNS — Cache после авторизации клиентской машины в Active Directory, у них будет статус unknown; их достаточно создать вручную с параметрами srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV. Они имеют такой вид:

/ip dns static
add name=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.domains._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_ldap._tcp.aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.domains._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV
add name=_tcp.aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.domains._msdcs.koobik.lan srv-port=389 srv-priority=0 srv-target=controller.koobik.lan srv-weight=100 type=SRV

Эта схема позволяет добавить в dns любое количество доменов и контроллеров в рамках одной сети — достаточно для каждого из них создать А-запись контроллера и пачку SRV-записей из образца выше; количество ограничено только вашей фантазией и объемом памяти mikrotik; это удобно, если вам достался зоопарк систем и нужно быстрое решение по их совместной работе с централизованным управлением сетью через роутер.

Усложним задачу. У нас есть распределенная сеть с двумя доменами (koobik.lan и koobik.local), на роутерах настроена маршрутизация, клиентские машины видят друг друга по серым ip и привязаны к разным доменам, при этом клиенты могут физически перемещаться между подсетями.

Сеть mikrotik с двумя доменами active directory

Тут два варианта:

  1. Выбираем один из микротиков (например, 10.0.0.1) головным DNS и выдаём его ip клиентам во всех сетях, а данные о dhcp-клиентах со всех микротиков записываем в его статические записи.
  2. Каждый из микротиков является dns для своих клиентов, в этом случае во всех dns создаём статические записи для dhcp-клиентов со всех микротиков.

Я разберу первый вариант, т.к. второй является его производным. Для этих целей у себя я задействовал виртуалку с ubuntu, но можно использовать и внутренние скрипты микротика.

Сначала разрешаем ssh на всех микротиках:

/ip service set ssh disabled=no

В целях безопасности создадим правило, разрешающее ssh-соединения только с конкретного ip (в примере — с ip 10.0.0.10).

/ip firewall raw add action=drop chain=prerouting dst-port=22 in-interface=ether1 protocol=tcp src-address=!10.0.0.10

На виртуалке делаем SSH авторизацию без пароля на микротиках, чтобы она могла самостоятельно обращаться к ним по расписанию.

Создаём скрипты, один будет собирать со всех микротиков данные об арендованных адресах и хостнеймах клиентов (export_dhcp.sh), а затем генерировать команды для создания статических записей в dns головного микротика и помещать их во второй файл (add_dns.sh).

$ touch /root/mikrotik/export_dhcp.sh
$ chmod +x /root/mikrotik/export_dhcp.sh
$ touch /root/mikrotik/add_dns.sh
$ chmod +x /root/mikrotik/add_dns.sh

Второй файл (add_dns.sh) будет наполняться и очищаться командами из первого и никаких действий с ним не требуется. Открываем на редактирование export_dhcp.sh и копипастим туда код (скорректировав ip и учётки на свои).

#!/bin/bash
echo 'Очищаю файл от старых данных.'
:> /root/mikrotik/add_dns.sh;
echo '#!/bin/bash' >> /root/mikrotik/add_dns.sh;
 
echo 'Получаю данные с 10.0.2.1...'
ssh admin@10.0.2.1 'ip dhcp-server lease print terse where status=bound' | grep host-name | sed 's/.*active-address=//' | sed '1,$ s/active.*name=//g' | awk '{print "ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.local]'\'' \n ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.lan]'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.local address="$1" ttl=4h'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.lan address="$1" ttl=4h'\''"}' >> /root/mikrotik/add_dns.sh
 
echo 'Получаю данные с 10.0.1.1...'
ssh admin@10.0.1.1 'ip dhcp-server lease print terse where status=bound' | grep host-name | sed 's/.*active-address=//' | sed '1,$ s/active.*name=//g' | awk '{print "ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.local]'\'' \n ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.lan]'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.local address="$1" ttl=4h'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.lan address="$1" ttl=4h'\''"}' >> /root/mikrotik/add_dns.sh
 
echo 'Загружаю данные с 10.0.0.1...'
ssh admin@10.0.0.1 'ip dhcp-server lease print terse where status=bound' | grep host-name | sed 's/.*active-address=//' | sed '1,$ s/active.*name=//g' | awk '{print "ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.local]'\'' \n ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.lan]'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.local address="$1" ttl=4h'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.lan address="$1" ttl=4h'\''"}' >> /root/mikrotik/add_dns.sh
 
echo 'Передаю данные на 10.0.0.1...'
sh /root/mikrotik/add_dns.sh;
echo 'Готово.'

Что делает скрипт:

  1. Чистит /root/mikrotik/add_dns.sh от команд предыдущей итерации (мы же будем по крону его использовать)
  2. Поочередно обращается к трём микротикам, получая от них список активных dhcp-клиентов
  3. Генерит по каждому клиенту по четыре команды:
    1. — поиск удаление из статических записей для имя_хоста.koobik.local
    2. — поиск удаление из статических записей для имя_хоста.koobik.lan
    3. — создание статической записи для имя_хоста.koobik.local
    4. — создание статической записи для имя_хоста.koobik.lan

Удаление нужно из-за того, что микротик допускает существование двух одинаковых А-записей с разными ip.

Создание двух записей с разными dns-суффиксами нужно для обращения с одного клиента на другой по имени хоста. Дело в том, что если клиент относится к какому-либо домену, то при любом обращении по имени без суффикса он автоматически подставляет суффикс своего домена. А т.к. у нас два разных домена — клиенты могут быть в любом из них.

Разберём по частям одну из команд:

ssh admin@10.0.0.1 'ip dhcp-server lease print terse where status=bound' | grep host-name | sed 's/.*active-address=//' | sed '1,$ s/active.*name=//g' | awk '{print "ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.local]'\'' \n ssh admin@10.0.0.1 '\''ip dns static remove [find name="$2".koobik.lan]'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.local address="$1" ttl=4h'\'' \n ssh admin@10.0.0.1 '\''ip dns static add name="$2".koobik.lan address="$1" ttl=4h'\''"}' 
>> /root/mikrotik/add_dns.sh

ssh admin@10.0.0.1 ‘ip dhcp-server lease print terse where status=bound’

По ssh-ключу с логином admin подключаемся к микротику 10.0.0.1 и выполняем на нём команду ip dhcp-server lease print terse where status=bound.

grep host-name

Оставляем только те строки, в которых есть имя хоста.

0 address=10.0.0.14 mac-address=00:0C:29:D9:89:0C client-id=ff:9f:6e:85:24:0:2:0:0:ab:11:31:f2:a1:5a:46:98:8:43 address-lists=»» server=dhcp1 dhcp-option=»» status=bound expires-after=8m9s last-seen=1m51s active-address=10.255.0.14 active-mac-address=00:0C:29:D9:89:0C active-client-id=ff:9f:6e:85:24:0:2:0:0:ab:11:31:f2:a1:5a:46:98:8:43 active-server=dhcp1 host-name=client1

Пример выдачи — получаем список с активными арендами.

sed ‘s/.active-address=//’ | sed ‘1,$ s/active.name=//g’

Вытаскиваем из выдачи значения active-address и host-name с помощью обрезки через sed

Далее команда awk обрабатывает два оставшихся значения (ip и имя хоста) и генерит четыре команды с использованием двух переменных: $1 — первое слово в строке (ip), $2 — второе слово в строке (имя хоста). Для указанного примера будет сгенерировано следующее:

ssh admin@10.0.0.1 'ip dns static remove [find name=client1.koobik.local]'
ssh admin@10.0.0.1 'ip dns static remove [find name=client1.koobik.lan]'
ssh admin@10.0.0.1 'ip dns static add name=client1.koobik.local address=10.0.0.14 ttl=4h'
ssh admin@10.0.0.1 'ip dns static add name=client1.koobik.lan address=10.0.0.14 ttl=4h'

>> /root/mikrotik/add_dns.sh

Эти команды будут дописаны в конец файла add_dns.sh

Ну и, конечно, не забываем добавить в crontab задачу на выполнение скрипта /root/mikrotik/export_dhcp.sh с нужным интервалом.

4 комментария

    1. Хочу дополнить уточнение.
      Нужно добавить две записи типа А:
      /ip dns static add address=10.0.0.2 name=controller.koobik.lan type=A
      /ip dns static add address=10.0.0.2 name=koobik.lan type=A

      Почему-то у меня по-другому не взлетело.
      А ещё хотелось бы уточнить. Возможно ли как-то узнать ID домена, типа: aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.domains._msdcs.koobik.lan
      Без обязательной установки роли DNS на контроллере домена?
      Данные идентификаторы храняться в файле: %systemroot%\System32\Config\Netlogon.dns
      но я не знаю, генерируется этот файл на каком этапе?
      За статью респектище!!!

      1. Александр, добавление второй А-записи для двух контроллеров в сети подразумевается, хотя явно в статье не указано, это верно.
        Что касается выяснения ID-записей dns без кэша dns на микротике — не довелось выяснять, однако — если если их нет в кэше со статусом unknown, значит к ним не было обращений от хостов клиентских машин, а значит и делать для них записи смысла нет.

  1. Ооох, а мне досталось «наследство» от предыдущего эникея. Контроллер домена на winserver 2003, к нему же прикручен TMG древний дырявый. И самое ужасное, что имя домена состоит из одного слова без каких-либо точек. Это очень усложняет работу, особенно когда пытался перенести всё на новый домен. Пытаюсь вот выкинуть из этой задачи хотя бы TMG и заменить его Микротиком RB4011. Но кругом одни подставы, оставленные предыдущим недоадмином…

Оставьте ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *