Проект mikrotik-doh-failover v0.1.0 — первый публичный релиз набора .rsc-скриптов, который настраивает на MikroTik один DoH-апстрим с обязательной проверкой сертификата, заворачивает классический DNS локальной сети на роутер и добавляет планировщик, переключающий резолвер на обычный DNS при отказе шифрованного канала. Схема «DoH в RouterOS с автоматическим откатом» собрана из семи файлов и не требует ни пакетов, ни внешних служб: всё живёт внутри роутера, а единственная работающая часть — запись планировщика, запускающая скрипт каждые три минуты. Релиз вышел 22 октября 2026 года, проверен на RouterOS 7.23.1 и 7.24.5. Ценность здесь не в самом DoH — его RouterOS умеет с версии 7.x, — а в двух вещах: явном импорте корневого сертификата там, где встроенное хранилище цепочку Cloudflare не покрывает, и в честном отказе от несуществующего «резервного DoH». Материал для тех, кто держит MikroTik шлюзом и хочет шифрованный апстрим, не потеряв DNS при сбое.

mikrotik-doh-failover v0.1.0 — обложка релиза
Один проверяемый DoH-апстрим на MikroTik и автоматический откат на обычный DNS

TL;DR

  • mikrotik-doh-failover v0.1.0 — первый публичный релиз: семь .rsc-файлов для RouterOS 7.20 и новее, лицензия MIT.
  • Один активный DoH-апстрим с verify-doh-cert=yes, обычный DNS как резерв и монитор, который сам меняет use-doh-server.
  • Установка — импорт четырёх файлов на роутер (00 → 01 → 02 → 05) плюс необязательные 03 и 04.
  • Главный риск: импорт без доверенного CA останавливает резолвинг во всей сети; откат — очистка use-doh-server и экспорт конфигурации, снятый до начала работ.
  • Автоматический планировщик требует device-mode=advanced; на устройствах с home монитор запускается только вручную.

Что нового

Это конфигурация, а не программа: ничего не устанавливается, ни один процесс не запускается вне роутера. Скрипты пишут в собственную конфигурацию устройства — хранилище сертификатов, раздел /ip dns, статические записи, правила nat и filter, один скрипт и одно задание планировщика. Никакой телеметрии и обращений в репозиторий нет; сетевой доступ нужен только к самому DoH-эндпоинту по TCP 443 и к NTP-серверам по IP во время настройки.

Логика набора простая и оттого проверяемая. 01-configure-doh.rsc прописывает два статических A-адреса для имени DoH-сервера, чтобы оно резолвилось даже при мёртвом обычном DNS, и включает один use-doh-server с проверкой цепочки. 02-security-policies.rsc перенаправляет UDP и TCP 53 с LAN-бриджа на роутер через action=redirect, разрешает DNS из локальной сети и запрещает его из WAN. 05-dns-health-monitor.rsc создаёт скрипт DNS_HealthMonitor_Failover с политикой read,write,policy,test и задание Scheduler_DNS_Health_Check с интервалом 3m: монитор проверяет резолвинг, при отказе очищает use-doh-server и возвращает его после восстановления.

Файл Что делает
routeros/00-install-ca.rsc импортирует корневой CA и помечает его trusted=yes
routeros/01-configure-doh.rsc один DoH-апстрим, bootstrap-записи, allow-remote-requests
routeros/02-security-policies.rsc перехват 53 (UDP и TCP) и защита резолвера от WAN
routeros/03-capsman.rsc необязательная привязка к одной конфигурации /caps-man
routeros/04-cert-update.rsc необязательное обновление CA
routeros/05-dns-health-monitor.rsc проверка состояния, переключение режима, планировщик
routeros/config.example.rsc все настраиваемые значения одним файлом-справочником

Кроме скриптов в наборе три документа (docs/architecture.md, docs/verification.md, docs/troubleshooting.md), три диаграммы Mermaid и сам корневой сертификат certs/cloudflare-doh-ca.crt — SSL.com TLS ECC Root CA 2022, 1533 байта, SHA-256 24B226BCA66D2FD890EA56CF56D9DDD177FD5ED57FF9F9859B073057A96A881B, действует до 1 января 2029 года.

Что исправлено

Релиз первый, поэтому раздел «Fixed» — это не исправления после предыдущих версий, а отказ от подходов, которые встречаются в чужих конфигурациях и не работают:

  • убран несуществующий механизм «резервного DoH» через /ip dns static-server type=doh — такого синтаксиса в RouterOS нет, резерв теперь обычный DNS плюс скрипт переключения;
  • принудительный DNS переведён с dst-nat to-addresses=<router-ip> на action=redirect;
  • права скрипта сужены с полного набора до read,write,policy,test;
  • добавлен приём TCP/53 там, где перехват затрагивает оба протокола;
  • исправлено указание по сертификатам: builtin-trust-store=default на 7.23 и 7.24 цепочку Cloudflare не покрывает, а параметра builtin-trust-anchors не существует вовсе.

Ключевые изменения

Что Было (типовая ошибка) Стало
Резерв DoH /ip dns static-server type=doh — синтаксис не существует один use-doh-server + обычные servers + скрипт переключения
Принудительный DNS dst-nat to-addresses=<router-ip> action=redirect для UDP и TCP 53 с LAN-бриджа
Доверие сертификату расчёт на встроенное хранилище RouterOS явный импорт certs/cloudflare-doh-ca.crt и trusted=yes
Права скрипта полный набор политик read,write,policy,test
DNS из WAN правило только на LAN accept для LAN (UDP и TCP) и drop для WAN

Как обновиться

Обновляться не с чего: это первый релиз, установка равна первой настройке. Файлы берутся из репозитория с закреплением на тег, потому что ветка main уже ушла вперёд относительно v0.1.0.

git clone --depth 1 --branch v0.1.0 https://github.com/paulmann/mikrotik-doh-failover.git

Дальше сертификат и нужные .rsc загружаются в корень файловой системы роутера — import file-name= ищет именно там, а не в рабочем каталоге вашей машины. Порядок импорта важен, проверка выполняется после каждого шага:

/import file-name=00-install-ca.rsc
/import file-name=01-configure-doh.rsc
/import file-name=02-security-policies.rsc
/import file-name=05-dns-health-monitor.rsc

Перед первым импортом снимается откат: /export file=before-doh и /system backup save name=before-doh. Файлы 03-capsman.rsc и 04-cert-update.rsc необязательны: первый нужен только для устаревшего контроллера /caps-man и целится в одну конфигурацию по имени, второй — только при плановой смене CA. Перезагрузка не требуется, но 01 и 02 не идемпотентны: в них нет проверки существования записей, поэтому повторный импорт добавит вторую такую же. Перед повторным запуском смотрите, что уже есть в конфигурации.

Что проверить после обновления

/certificate print where trusted=yes
/ip dns print
/ip dns static print where name=family.cloudflare-dns.com
/system ntp client print
/ip firewall nat print where comment~"force DNS"
/ip firewall filter print where comment~"DNS"
/ip dns cache flush
:put [:resolve example.com]
:put [:resolve pornhub.com]
:put $DNSCurrentMode
/log print where message~"connection error"

Критерий «работает»: в /certificate print where trusted=yes виден SSL.com TLS ECC Root CA 2022; /ip dns print показывает servers=1.1.1.3,1.0.0.3, use-doh-server с адресом Family и verify-doh-cert=yes; для имени family.cloudflare-dns.com есть ровно две статические записи; :resolve example.com возвращает реальный IP, а :resolve pornhub.com — 0.0.0.0; $DNSCurrentMode равен doh; в логе нет строк connection error. Пустой вывод проверки DNS-ошибок — это здоровое состояние, а не «ничего не проверилось». Отдельно стоит помнить, что /tool fetch к /dns-query для проверки не годится: ответы 400 на POST и 405 на GET означают успешное TLS-рукопожатие, а не аварию.

Совместимость и требования

Параметр Значение
Платформа RouterOS 7.20 и новее; замерено на 7.23.1 и 7.24.5
Проверенные устройства Chateau PRO ax, cAP ax, RB4011iGS+, hAP ax², RB951Ui-2HnD, RB2011UiAS
Оговорка о числе в разделе «By the numbers» указано 5 устройств, таблица совместимости перечисляет шесть: пять на 7.24.5 и RB2011UiAS на 7.23.1
device-mode advanced для автоматического планировщика; home отвергает задание
NTP обязателен: сбитые часы ломают проверку TLS
Сертификат certs/cloudflare-doh-ca.crt, SSL.com TLS ECC Root CA 2022, до 01.01.2029
Лицензия MIT

Провайдер DoH меняется тремя значениями сразу — адресом, обычными servers и корневым CA. Если подставить чужой корень, verify-doh-cert=yes откажет точно так же, как при полном отсутствии сертификата.

Провайдер use-doh-server Обычные servers
Cloudflare Family https://family.cloudflare-dns.com/dns-query 1.1.1.3,1.0.0.3
Cloudflare standard https://cloudflare-dns.com/dns-query 1.1.1.1,1.0.0.1
Cloudflare security https://security.cloudflare-dns.com/dns-query 1.1.1.2,1.0.0.2
Quad9 https://dns.quad9.net/dns-query 9.9.9.9,149.112.112.112
Google https://dns.google/dns-query 8.8.8.8,8.8.4.4

Кому это нужно

Первый сценарий — офис или дом с MikroTik на входе, где провайдер подменяет DNS, а руки до DNSSEC и шифрования не доходили: набор даёт предсказуемый апстрим и заодно закрывает резолвер от запросов снаружи. Второй — площадка, где уже настроен DoH вручную и один раз в год случается «интернет есть, сайты не открываются»: здесь появляется то, чего у ручной настройки нет, — запись в логе о переключении режима и автоматический возврат после восстановления.

Подводные камни

  • Сертификат импортируется первым, иначе сеть останется без DNS. Проверено в замерах: если снять доверие со всех CA и выполнить :resolve, ответ будет failure: dns server failure. Импорт — обязательный шаг, а не рекомендация.
  • Встроенное хранилище не спасает. /certificate settings set builtin-trust-anchors=… возвращает bad parameter; параметр называется builtin-trust-store, и на 7.23/7.24 его содержимое цепочку Cloudflare не покрывает.
  • device-mode=home отключает автоматику. /system scheduler add и /tool fetch отвечают not allowed by device-mode; остаётся ручной запуск DNS_HealthMonitor_Failover. Перевод в advanced — решение владельца с подтверждением на устройстве и перезагрузкой.
  • Обновляться не надо, если нет окна обслуживания. Неверный CA или несовпадение имён интерфейсов в 02 останавливает резолвинг во всей сети; правило, нацеленное на отсутствующий интерфейс, добавляется молча и не срабатывает.
  • /ip dns static сильнее ответа DoH. Закреплённое имя обходит фильтр Family — это штатное поведение RouterOS, а не дефект набора.

FAQ

Нужно ли ставить пакет или службу на роутер?

Нет. Это только конфигурация: импорт .rsc-файлов, сертификат в файловой системе и одна запись планировщика. Пакеты, контейнеры и внешние демоны не используются, откат — импорт ранее снятого экспорта.

Почему резервный DoH не сделан через второй use-doh-server?

Потому что RouterOS поддерживает ровно один use-doh-server и не имеет механизма резервного DoH; синтаксис static-server type=doh не существует. Резерв в проекте — обычные servers плюс скрипт, который очищает use-doh-server при отказе и возвращает его после восстановления.

Что будет, если DoH упадёт ночью?

Монитор проверяет резолвинг каждые три минуты, при отказе переводит резолвер в обычный режим и пишет в лог error, после восстановления возвращает DoH с уровнем warning. Если недоступны и DoH, и обычный DNS, скрипт оставляет последнюю конфигурацию и пишет critical.

Подходит ли это для RouterOS 7.20–7.22?

Заявленная граница — 7.20+, но замеры сделаны только на 7.23.1 и 7.24.5, поведение на 7.20–7.22 в репозитории не документировано. На такой версии сначала проверьте импорт CA и :resolve на одном устройстве, а не на всей площадке.

Итог

Релиз небольшой по объёму и неожиданно полезный по содержанию: он фиксирует не «как включить DoH», а «как не потерять DNS, когда DoH перестал отвечать». Семь файлов, один сертификат, один планировщик — и при этом честно перечисленные ограничения: клиентский DoH по 443 не блокируется, DNSSEC не добавляется, автоматика недоступна на home-устройствах. Обновляться не с чего, но если на площадке есть MikroTik со старым plaintext-апстримом, набор стоит прогнать на одном устройстве и посмотреть на $DNSCurrentMode в работе.

Цитата: Отказоустойчивость DNS на микротике начинается не с включения DoH, а с импортированного корневого сертификата и записанного в лог переключения режимов — всё остальное в этой схеме производное.

Связанные материалы

LLM Summary

  • Тема: набор .rsc-скриптов mikrotik-doh-failover для отказоустойчивого DNS-over-HTTPS на MikroTik RouterOS.
  • Версия: v0.1.0, опубликована 22 октября 2026 года, первый публичный релиз, лицензия MIT.
  • Что изменилось: появились семь скриптов (CA, DoH, политики, CAPsMAN, обновление сертификата, монитор), три документа и корневой CA; убраны несуществующий static-server type=doh, dst-nat to-addresses и полные права скрипта.
  • Ключевые команды: /import file-name=00-install-ca.rsc, /import file-name=01-configure-doh.rsc, /ip dns cache flush, :put [:resolve example.com].
  • Требования: RouterOS 7.20+, синхронизированный NTP, device-mode=advanced для планировщика, загруженный в файловую систему роутера сертификат.
  • Основные риски: импорт без доверенного CA останавливает резолвинг во всей сети; 01 и 02 не идемпотентны и при повторном импорте дублируют записи; на home-устройствах автоматика недоступна.
  • Проверка результата: trusted=yes у SSL.com TLS ECC Root CA 2022, use-doh-server и verify-doh-cert=yes в /ip dns print, 0.0.0.0 для pornhub.com, $DNSCurrentMode = doh, отсутствие connection error в логе.
  • Кому полезно: администраторам MikroTik-шлюзов, которым нужен шифрованный апстрим с автоматическим откатом на обычный DNS.
  • Ссылки: https://github.com/paulmann/mikrotik-doh-failover/releases/tag/v0.1.0, https://github.com/paulmann/mikrotik-doh-failover

Промт для агента (установка)

Готовый промт для AI-агента: скопируйте блок целиком кнопкой и отдайте своему ассистенту. Шаги и команды взяты из файла AGENTS.md в репозитории проекта — это инструкция, которую автор написал для агентов, а не пересказ.

Задача: развернуть mikrotik-doh-failover v0.1.0 на устройстве MikroTik RouterOS и доказать, что резолвинг работает.

Материалы:
- релиз: https://github.com/paulmann/mikrotik-doh-failover/releases/tag/v0.1.0
- репозиторий: https://github.com/paulmann/mikrotik-doh-failover
- инструкция для агентов (прочитать первой): https://github.com/paulmann/mikrotik-doh-failover/blob/main/AGENTS.md
- проверки подсистем: https://github.com/paulmann/mikrotik-doh-failover/blob/main/docs/verification.md

Предусловия (AGENTS.md §2). Непройденная строка — стоп, а не предупреждение:
- версия: /system resource print → version: 7.20 или новее
- часы: /system ntp client print → status: synchronized
- режим: /system device-mode print (для планировщика нужен advanced)
- интерфейсы: /interface bridge print; /interface list print
- откат: /export file=before-doh; /system backup save name=before-doh

Получить файлы (§3), ref закрепить на теге:
git clone --depth 1 --branch v0.1.0 https://github.com/paulmann/mikrotik-doh-failover.git

Сверить сертификат до импорта (§3.3): 1533 байта, CN=SSL.com TLS ECC Root CA 2022, SHA-256 24B226BCA66D2FD890EA56CF56D9DDD177FD5ED57FF9F9859B073057A96A881B. Другой отпечаток — остановиться. Файлы .crt и .rsc загружаются в корень Files роутера: import file-name= ищет там.

Применить по порядку (§4), после каждого шага — проверка из §5:
/import file-name=00-install-ca.rsc
/import file-name=01-configure-doh.rsc
/import file-name=02-security-policies.rsc
/import file-name=05-dns-health-monitor.rsc

03-capsman.rsc — только для старого /caps-man и одной конфигурации по имени; 04-cert-update.rsc не нужен, пока корневой CA действителен до 2029-01-01.

01 и 02 не идемпотентны: повторный импорт добавит вторую запись. Перед повторным импортом посмотреть, что уже есть:
/ip dns static print where comment="DoH bootstrap"
/ip firewall nat print where comment~"force DNS"
/ip firewall filter print where comment~"DNS"
/system script print where name="DNS_HealthMonitor_Failover"

Проверка (§5). Ожидаемые значения — из docs/verification.md; расхождение считается дефектом, а не поводом «повторить»:
/certificate print where trusted=yes
/ip dns print
/ip dns static print where name=family.cloudflare-dns.com
/system ntp client print
/ip firewall nat print where comment~"force DNS"
/ip firewall filter print where comment~"DNS"
/ip dns cache flush
:put [:resolve example.com]
:put [:resolve pornhub.com]
:put $DNSCurrentMode
/log print where message~"connection error"

Что считать успехом: SSL.com в trusted=yes; /ip dns print отдаёт use-doh-server с адресом Family и verify-doh-cert=yes; :resolve example.com даёт реальный IP, pornhub.com — 0.0.0.0; $DNSCurrentMode = doh; строк connection error в логе нет.

Откат, если что-то пошло не так (§8):
/ip dns set use-doh-server=""
/ip dns cache flush
/ip firewall nat remove [find comment~"force DNS"]
/ip firewall filter remove [find comment~"DNS"]
/ip dns static remove [find comment="DoH bootstrap"]
/system scheduler remove [find name="Scheduler_DNS_Health_Check"]
/system script remove [find name="DNS_HealthMonitor_Failover"]
/certificate remove [find where name~"cloudflare-doh-ca"]
/import file-name=before-doh.rsc

Ограничения:
- одно устройство за раз: сломанный шаг 2 на десяти роутерах — это десять сетей без DNS;
- не выполнять /system reset-configuration и не удалять правила через [find] без фильтра по comment;
- не менять device-mode: это решение владельца, нужны подтверждение на устройстве и перезагрузка;
- не проверять DoH через /tool fetch к /dns-query: 400 (POST) и 405 (GET) — успешное TLS-рукопожатие, а не авария;
- если команда падает — остановиться и показать команду, вывод и код возврата.