Pi-hole в контейнере на MikroTik — блокировка рекламы
Pi-hole в контейнере на MikroTik — блокировка рекламы на уровне сети
Pi-hole — один из самых популярных DNS-фильтров для блокировки рекламы и трекеров. Запуск Pi-hole непосредственно на маршрутизаторе MikroTik устраняет необходимость в отдельном устройстве (Raspberry Pi, Mini-PC) и обеспечивает блокировку рекламы для всех клиентов сети без установки блокировщиков на каждое устройство. В этом руководстве подробно разберём установку, настройку, перенаправление DNS и эксплуатацию Pi-hole на RouterOS 7.20+.
Описание
Зачем Pi-hole на роутере
Традиционный подход — установить Pi-hole на Raspberry Pi или виртуальную машину. Но MikroTik с поддержкой контейнеров предлагает элегантное решение:
- Одно устройство — маршрутизатор совмещает routing, firewall и DNS-фильтрацию;
- Нет дополнительного железа — не нужен Raspberry Pi, нет лишнего энергопотребления;
- Все клиенты защищены — любое устройство, подключённое к сети, автоматически использует Pi-hole;
- Централизованное управление — всё в одном интерфейсе (WinBox + Pi-hole dashboard);
- Отказоустойчивость — при падении Pi-hole маршрутизатор может переключиться на обычный DNS.
Как работает Pi-hole
Pi-hole выступает DNS-сервером. Когда устройство запрашивает доменное имя (например, ads.doubleclick.net), Pi-hole проверяет его по чёрным спискам (gravity lists). Если домен заблокирован — возвращает 0.0.0.0 (NXDOMAIN). Если разрешён — пересылает запрос на upstream DNS (Cloudflare, Google и т.д.) и возвращает ответ.
Схема работы:
codeКлиент -> MikroTik (DNS redirect) -> Pi-hole (172.17.0.2) -> Upstream DNS (1.1.1.1) | Заблокировано? -> 0.0.0.0
Требования
| Компонент | Минимум | Рекомендуется |
|---|---|---|
| RouterOS | 7.4+ | 7.20+ |
| Устройство | RB5009, CCR2004, CHR | RB5009UPr+S+ |
| Архитектура | ARM64 или x86 | ARM64 |
| Свободная RAM | 256 МБ | 512 МБ+ |
| Хранилище | 1 ГБ на USB | 4 ГБ+ USB |
| Container mode | Включён | — |
Важно: Pi-hole в контейнере потребляет 80–150 МБ RAM при стандартных списках фильтров. На устройствах с 256 МБ общей RAM (не свободной!) запуск нецелесообразен.
Pi-hole vs DNS static на MikroTik — сравнение
| Параметр | Pi-hole (контейнер) | DNS static (MikroTik) |
|---|---|---|
| Количество правил | 300 000+ доменов | Ограничено RAM, не более 10 000 удобно |
| Автообновление списков | Да (встроенное) | Нет (скрипты вручную) |
| Веб-интерфейс | Да (полноценный dashboard) | Нет |
| Статистика | Подробная (клиенты, домены, графики) | Нет |
| Wildcard-блокировка | Да (regex) | Нет (только точное совпадение) |
| Whitelist/Blacklist | Удобный UI | Ручное управление |
| Потребление RAM | 80–150 МБ | 5–50 МБ |
| Зависимость от контейнера | Да | Нет |
| DNS-over-HTTPS | Через upstream (cloudflared) | Встроенный DoH в RouterOS 7.x |
Вывод: для небольшого домашнего использования (до 1000 записей) достаточно DNS static. Для полноценной фильтрации с аналитикой — Pi-hole.
Настройка
Шаг 1: Подготовка инфраструктуры
Если container mode ещё не включён:
[admin@MikroTik] >/system/device-mode/update container=yes # Нажмите кнопку reset на устройстве для подтверждения
Настройка хранилища:
[admin@MikroTik] ># Проверяем USB-накопитель /disk/print # Настройка контейнерной среды /container/config/set registry-url=https://registry-1.docker.io tmpdir=usb1/tmp ram-high=512M
Шаг 2: Создание сетевой инфраструктуры
Bridge и IP-адрес
[admin@MikroTik] ># Bridge для контейнеров (если ещё не создан) /interface/bridge/add name=bridge-containers comment="Container network" # IP-адрес — шлюз для контейнеров /ip/address/add address=172.17.0.1/24 interface=bridge-containers comment="Container gateway"
veth-интерфейс для Pi-hole
[admin@MikroTik] ># Создаём veth с фиксированным IP /interface/veth/add name=veth-pihole address=172.17.0.2/24 gateway=172.17.0.1 comment="Pi-hole container" # Добавляем в bridge /interface/bridge/port/add bridge=bridge-containers interface=veth-pihole
NAT для доступа Pi-hole в интернет
Pi-hole нужен интернет для скачивания списков фильтров и пересылки DNS-запросов на upstream:
[admin@MikroTik] >/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 out-interface-list=WAN comment="Container NAT"
Шаг 3: Подготовка переменных окружения
Pi-hole настраивается через environment variables:
[admin@MikroTik] ># Часовой пояс /container/envs/add name=pihole-env key=TZ value="Europe/Moscow" # Пароль для веб-интерфейса Pi-hole /container/envs/add name=pihole-env key=WEBPASSWORD value="YourSecurePassword123" # Upstream DNS-серверы (куда Pi-hole пересылает разрешённые запросы) /container/envs/add name=pihole-env key=PIHOLE_DNS_ value="1.1.1.1;8.8.8.8" # IP-адрес сервера (Pi-hole должен знать свой IP) /container/envs/add name=pihole-env key=FTLCONF_LOCAL_IPV4 value="172.17.0.2" # Отключаем DHCP-сервер Pi-hole (DHCP обслуживает MikroTik) /container/envs/add name=pihole-env key=PIHOLE_INTERFACE value="eth0"
Обязательно смените WEBPASSWORD на свой пароль. Этот пароль используется для входа в веб-интерфейс Pi-hole.
Шаг 4: Создание точек монтирования
Для сохранения конфигурации Pi-hole между перезагрузками:
[admin@MikroTik] ># Директории для persistent-данных /file/mkdir usb1/pihole /file/mkdir usb1/pihole/etc-pihole /file/mkdir usb1/pihole/etc-dnsmasq # Точки монтирования /container/mounts/add name=pihole-etc src=usb1/pihole/etc-pihole dst=/etc/pihole /container/mounts/add name=pihole-dnsmasq src=usb1/pihole/etc-dnsmasq dst=/etc/dnsmasq.d
Шаг 5: Загрузка и создание контейнера
[admin@MikroTik] >/container/add remote-image=pihole/pihole:latest interface=veth-pihole root-dir=usb1/pihole/root envlist=pihole-env mounts=pihole-etc,pihole-dnsmasq start-on-boot=yes hostname=pihole logging=yes comment="Pi-hole DNS filter"
Дождитесь скачивания образа (100–200 МБ, в зависимости от архитектуры):
[admin@MikroTik] ># Проверяем статус /container/print # status: extracting -> stopped -> (после start) running
Шаг 6: Запуск Pi-hole
[admin@MikroTik] ># Запуск контейнера /container/start 0 # Проверяем статус через 10-15 секунд /container/print
Проверяем, что Pi-hole отвечает на DNS-запросы:
[admin@MikroTik] ># DNS-запрос к Pi-hole /tool/dns-query name=google.com server=172.17.0.2 # Проверяем блокировку рекламного домена /tool/dns-query name=ads.doubleclick.net server=172.17.0.2 # Должен вернуть 0.0.0.0 — заблокировано
Шаг 7: Перенаправление DNS через Pi-hole
Теперь нужно заставить все устройства в сети использовать Pi-hole как DNS-сервер. Есть два подхода.
Подход 1: MikroTik DNS использует Pi-hole как upstream (рекомендуется)
MikroTik остаётся DNS-сервером для клиентов, но пересылает все запросы в Pi-hole:
[admin@MikroTik] ># MikroTik DNS пересылает запросы в Pi-hole /ip/dns/set servers=172.17.0.2 allow-remote-requests=yes cache-size=2048KiB # DHCP раздаёт клиентам IP маршрутизатора как DNS # (обычно уже настроено так по умолчанию) /ip/dhcp-server/network/set [find] dns-server=192.168.88.1
Преимущество: если Pi-hole упадёт, можно быстро переключить DNS обратно на внешний сервер.
Подход 2: Клиенты обращаются к Pi-hole напрямую
DHCP раздаёт адрес Pi-hole как DNS-сервер:
[admin@MikroTik] ># DHCP раздаёт Pi-hole как DNS /ip/dhcp-server/network/set [find] dns-server=172.17.0.2
Преимущество: Pi-hole видит реальные IP клиентов в статистике. Недостаток: при падении Pi-hole все клиенты теряют DNS.
Принудительное перенаправление DNS (защита от обхода)
Некоторые устройства (Smart TV, IoT) используют жёстко прописанные DNS-серверы (8.8.8.8, 1.1.1.1). Перенаправим все DNS-запросы через Pi-hole:
[admin@MikroTik] ># Перехват всех DNS-запросов и перенаправление на Pi-hole /ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp dst-port=53 src-address=!172.17.0.2 dst-address=!172.17.0.2 comment="Force DNS through Pi-hole" /ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=tcp dst-port=53 src-address=!172.17.0.2 dst-address=!172.17.0.2 comment="Force DNS through Pi-hole TCP"
Эти правила перенаправляют все DNS-запросы (порт 53) на Pi-hole, независимо от того, какой DNS-сервер указан на клиенте.
Шаг 8: Доступ к веб-интерфейсу Pi-hole
Pi-hole имеет веб-интерфейс для управления на порту 80. Для доступа из LAN:
[admin@MikroTik] ># Из браузера в LAN откройте: # http://172.17.0.2/admin # Логин: (пусто), пароль: тот, что указали в WEBPASSWORD
Если нужен доступ из WAN (не рекомендуется без VPN):
[admin@MikroTik] ># Проброс порта для Pi-hole dashboard (ТОЛЬКО через VPN!) /ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=80 protocol=tcp dst-port=8053 in-interface-list=WAN comment="Pi-hole dashboard (disable in production!)"
Внимание: открывать доступ к Pi-hole dashboard из WAN без VPN крайне небезопасно. Используйте WireGuard или другой VPN.
Шаг 9: Обновление списков фильтров
Pi-hole обновляет gravity-списки автоматически (раз в неделю по умолчанию). Для ручного обновления используйте веб-интерфейс или shell контейнера:
[admin@MikroTik] ># Заходим внутрь контейнера /container/shell 0 # Внутри контейнера: # pihole -g # exit
Для добавления дополнительных списков блокировки:
- Откройте Pi-hole dashboard → Group Management → Adlists.
- Добавьте URL списков (например,
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts). - Обновите gravity:
pihole -g.
Рекомендуемые списки:
- Steven Black's Unified Hosts — базовый список рекламы и трекеров;
- Firebog — куратированные списки;
- OISD — комплексный список с минимальными ложными срабатываниями.
Шаг 10: Мониторинг Pi-hole
Через веб-интерфейс
Dashboard Pi-hole показывает:
- общее количество запросов;
- процент заблокированных запросов;
- топ заблокированных доменов;
- топ клиентов по количеству запросов;
- графики по времени суток.
Через CLI Pi-hole
[admin@MikroTik] ># Заходим в контейнер /container/shell 0 # Внутри: # pihole status # pihole -c (console dashboard) # pihole -t (tail log в реальном времени) # exit
Мониторинг ресурсов из RouterOS
[admin@MikroTik] ># Общее состояние системы /system/resource/print # Статус контейнера /container/print detail # Логи контейнера в системном журнале /log/print where topics~"container"
Шаг 11: Отказоустойчивость
Если Pi-hole упадёт, все клиенты потеряют DNS. Настроим fallback:
[admin@MikroTik] ># Скрипт проверки Pi-hole и переключения на резервный DNS /system/script/add name=pihole-failover source={ :local piholeIP "172.17.0.2" :local fallbackDNS "1.1.1.1,8.8.8.8" :local normalDNS $piholeIP :do { /tool/dns-query name=google.com server=$piholeIP } on-error={ :local currentDNS [/ip/dns/get servers] :if ($currentDNS = $normalDNS) do={ /ip/dns/set servers=$fallbackDNS :log warning "Pi-hole is DOWN! Switched to fallback DNS: $fallbackDNS" # Попытка перезапуска контейнера :do { /container/start [/container/find where comment~"Pi-hole"] } on-error={} } } :do { /tool/dns-query name=google.com server=$piholeIP :local currentDNS [/ip/dns/get servers] :if ($currentDNS != $normalDNS) do={ /ip/dns/set servers=$normalDNS :log info "Pi-hole is UP! Switched back to Pi-hole DNS" } } on-error={} } /system/scheduler/add name=pihole-failover interval=1m on-event="/system/script/run pihole-failover"
Проверка
Полная проверка работоспособности
[admin@MikroTik] ># 1. Контейнер запущен /container/print # status должен быть "running" # 2. Pi-hole отвечает на DNS /tool/dns-query name=google.com server=172.17.0.2 # Должен вернуть IP-адрес # 3. Pi-hole блокирует рекламу /tool/dns-query name=ads.doubleclick.net server=172.17.0.2 # Должен вернуть 0.0.0.0 # 4. MikroTik DNS пересылает запросы через Pi-hole /ip/dns/print # servers должен содержать 172.17.0.2 # 5. DHCP раздаёт правильный DNS /ip/dhcp-server/network/print # 6. Перехват DNS работает /ip/firewall/nat/print where comment~"Force DNS" # 7. Сетевая связность контейнера /ping 172.17.0.2 count=4
Проверка с клиентского устройства
На компьютере в сети выполните:
- Windows:
nslookup ads.doubleclick.net— должен вернуть 0.0.0.0; - Linux/macOS:
dig ads.doubleclick.net— ANSWER section должен содержать 0.0.0.0; - Откройте в браузере сайт с рекламой — баннеры должны быть заблокированы.
Типичные ошибки
Ошибка 1: Недостаточно RAM — контейнер перезапускается
Симптом: Pi-hole запускается, но через некоторое время контейнер останавливается или перезапускается.
Причина: недостаточно свободной RAM. Pi-hole с gravity-списками потребляет 80–150 МБ.
Решение:
[admin@MikroTik] ># Проверяем свободную RAM /system/resource/print # free-memory должно быть больше 256 МБ # Увеличиваем лимит RAM для контейнеров /container/config/set ram-high=512M # Если RAM мало — уменьшите списки фильтров в Pi-hole # Используйте только основной список (Steven Black)
Если свободной RAM менее 200 МБ после запуска Pi-hole — рассмотрите использование AdGuard Home (потребляет меньше RAM) или DNS static на MikroTik.
Ошибка 2: Конфликт порта 53
Симптом: Pi-hole не запускается или не отвечает на DNS-запросы.
Причина: встроенный DNS-сервер MikroTik тоже слушает порт 53 на всех интерфейсах, включая bridge-containers.
Решение:
Встроенный DNS MikroTik и Pi-hole не конфликтуют напрямую, так как Pi-hole слушает порт 53 на своём IP (172.17.0.2), а MikroTik DNS — на своих интерфейсных IP. Но если возникают проблемы:
[admin@MikroTik] ># Вариант 1: Ограничьте MikroTik DNS — не слушать на container bridge # (RouterOS не позволяет указать интерфейс для DNS, но можно через firewall) /ip/firewall/filter/add chain=input action=drop protocol=udp dst-port=53 in-interface=bridge-containers src-address=!172.17.0.0/24 comment="Block external DNS to container bridge" # Вариант 2: Если используете подход 2 (клиенты -> Pi-hole напрямую): # Отключите MikroTik DNS полностью /ip/dns/set allow-remote-requests=no
Ошибка 3: Pi-hole dashboard недоступен
Симптом: http://172.17.0.2/admin не открывается.
Причина: контейнер ещё не полностью загрузился, неправильная сетевая конфигурация или firewall блокирует.
Решение:
[admin@MikroTik] ># Проверяем статус контейнера /container/print # Должен быть status: running # Проверяем сетевую связность /ping 172.17.0.2 count=4 # Проверяем HTTP-доступность /tool/fetch url="http://172.17.0.2/admin" mode=http dst-path=pihole-test.html # Проверяем, нет ли блокирующих правил firewall /ip/firewall/filter/print where dst-address=172.17.0.2
Если Pi-hole запустился недавно — подождите 1–2 минуты. Первый запуск включает скачивание gravity-списков.
Ошибка 4: Pi-hole не блокирует рекламу
Симптом: DNS работает, но реклама не блокируется.
Причина: gravity-списки не загружены, клиент использует другой DNS (DoH в браузере), или запросы не проходят через Pi-hole.
Решение:
[admin@MikroTik] ># 1. Проверяем, что Pi-hole отвечает блокировкой /tool/dns-query name=ads.doubleclick.net server=172.17.0.2 # Если возвращает реальный IP — gravity не загружен # 2. Заходим в контейнер и обновляем gravity /container/shell 0 # pihole -g # exit # 3. Проверяем, что DNS-перенаправление работает /ip/firewall/nat/print where comment~"Force DNS" # 4. Для устройств с DoH (Firefox, Chrome): # Заблокируйте DoH-серверы на уровне firewall /ip/firewall/filter/add chain=forward action=reject protocol=tcp dst-port=443 dst-address-list=doh-servers reject-with=tcp-reset comment="Block DoH bypass" # Добавьте известные DoH-серверы в address-list /ip/firewall/address-list/add list=doh-servers address=dns.google comment="Google DoH" /ip/firewall/address-list/add list=doh-servers address=cloudflare-dns.com comment="Cloudflare DoH" /ip/firewall/address-list/add list=doh-servers address=dns.quad9.net comment="Quad9 DoH"
Ошибка 5: Контейнер не запускается после перезагрузки маршрутизатора
Симптом: после reboot Pi-hole не стартует, хотя start-on-boot=yes.
Причина: USB-накопитель монтируется позже, чем система пытается запустить контейнер.
Решение:
[admin@MikroTik] ># Скрипт отложенного запуска /system/script/add name=start-pihole source={ :delay 30s :local id [/container/find where comment~"Pi-hole"] :if ([:len $id] > 0) do={ :local status [/container/get $id status] :if ($status != "running") do={ /container/start $id :log info "Pi-hole container started after boot delay" } } } /system/scheduler/add name=start-pihole on-event="/system/script/run start-pihole" start-time=startup interval=0
Ошибка 6: Высокая нагрузка на CPU
Симптом: после установки Pi-hole CPU маршрутизатора загружен на 80–100%.
Причина: слишком много DNS-запросов (большая сеть, IoT-устройства, DNS amplification), или гравитация обновляется.
Решение:
[admin@MikroTik] ># Проверяем загрузку /system/resource/print # Если CPU загружен постоянно — уменьшите количество списков фильтров # Оставьте только 1-2 основных списка # Увеличьте DNS-кэш MikroTik (если используете подход 1) /ip/dns/set cache-size=4096KiB # Ограничьте количество DNS-запросов через firewall /ip/firewall/filter/add chain=forward action=drop protocol=udp dst-port=53 dst-address=172.17.0.2 connection-limit=50,32 comment="Limit DNS queries to Pi-hole"
Обновление Pi-hole
Для обновления Pi-hole до новой версии:
[admin@MikroTik] ># 1. Остановите контейнер /container/stop [/container/find where comment~"Pi-hole"] # 2. Удалите контейнер (данные в mounts сохранятся!) /container/remove [/container/find where comment~"Pi-hole"] # 3. Пересоздайте с тем же образом (скачается новая версия) /container/add remote-image=pihole/pihole:latest interface=veth-pihole root-dir=usb1/pihole/root envlist=pihole-env mounts=pihole-etc,pihole-dnsmasq start-on-boot=yes hostname=pihole logging=yes comment="Pi-hole DNS filter" # 4. Дождитесь скачивания и запустите /container/print /container/start 0
Все настройки Pi-hole (списки, whitelist, blacklist) сохраняются в точках монтирования (pihole-etc, pihole-dnsmasq) и переживают обновление.
Клиент -> MikroTik (DNS redirect) -> Pi-hole (172.17.0.2) -> Upstream DNS (1.1.1.1)
|
Заблокировано? -> 0.0.0.0
/system/device-mode/update container=yes
# Нажмите кнопку reset на устройстве для подтверждения
# Проверяем USB-накопитель
/disk/print
# Настройка контейнерной среды
/container/config/set registry-url=https://registry-1.docker.io tmpdir=usb1/tmp ram-high=512M
# Bridge для контейнеров (если ещё не создан)
/interface/bridge/add name=bridge-containers comment="Container network"
# IP-адрес — шлюз для контейнеров
/ip/address/add address=172.17.0.1/24 interface=bridge-containers comment="Container gateway"
# Создаём veth с фиксированным IP
/interface/veth/add name=veth-pihole address=172.17.0.2/24 gateway=172.17.0.1 comment="Pi-hole container"
# Добавляем в bridge
/interface/bridge/port/add bridge=bridge-containers interface=veth-pihole
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24 out-interface-list=WAN comment="Container NAT"
# Часовой пояс
/container/envs/add name=pihole-env key=TZ value="Europe/Moscow"
# Пароль для веб-интерфейса Pi-hole
/container/envs/add name=pihole-env key=WEBPASSWORD value="YourSecurePassword123"
# Upstream DNS-серверы (куда Pi-hole пересылает разрешённые запросы)
/container/envs/add name=pihole-env key=PIHOLE_DNS_ value="1.1.1.1;8.8.8.8"
# IP-адрес сервера (Pi-hole должен знать свой IP)
/container/envs/add name=pihole-env key=FTLCONF_LOCAL_IPV4 value="172.17.0.2"
# Отключаем DHCP-сервер Pi-hole (DHCP обслуживает MikroTik)
/container/envs/add name=pihole-env key=PIHOLE_INTERFACE value="eth0"
# Директории для persistent-данных
/file/mkdir usb1/pihole
/file/mkdir usb1/pihole/etc-pihole
/file/mkdir usb1/pihole/etc-dnsmasq
# Точки монтирования
/container/mounts/add name=pihole-etc src=usb1/pihole/etc-pihole dst=/etc/pihole
/container/mounts/add name=pihole-dnsmasq src=usb1/pihole/etc-dnsmasq dst=/etc/dnsmasq.d
/container/add remote-image=pihole/pihole:latest interface=veth-pihole root-dir=usb1/pihole/root envlist=pihole-env mounts=pihole-etc,pihole-dnsmasq start-on-boot=yes hostname=pihole logging=yes comment="Pi-hole DNS filter"
# Проверяем статус
/container/print
# status: extracting -> stopped -> (после start) running
# Запуск контейнера
/container/start 0
# Проверяем статус через 10-15 секунд
/container/print
# DNS-запрос к Pi-hole
/tool/dns-query name=google.com server=172.17.0.2
# Проверяем блокировку рекламного домена
/tool/dns-query name=ads.doubleclick.net server=172.17.0.2
# Должен вернуть 0.0.0.0 — заблокировано
# MikroTik DNS пересылает запросы в Pi-hole
/ip/dns/set servers=172.17.0.2 allow-remote-requests=yes cache-size=2048KiB
# DHCP раздаёт клиентам IP маршрутизатора как DNS
# (обычно уже настроено так по умолчанию)
/ip/dhcp-server/network/set [find] dns-server=192.168.88.1
# DHCP раздаёт Pi-hole как DNS
/ip/dhcp-server/network/set [find] dns-server=172.17.0.2
# Перехват всех DNS-запросов и перенаправление на Pi-hole
/ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=udp dst-port=53 src-address=!172.17.0.2 dst-address=!172.17.0.2 comment="Force DNS through Pi-hole"
/ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=53 protocol=tcp dst-port=53 src-address=!172.17.0.2 dst-address=!172.17.0.2 comment="Force DNS through Pi-hole TCP"
# Из браузера в LAN откройте:
# http://172.17.0.2/admin
# Логин: (пусто), пароль: тот, что указали в WEBPASSWORD
# Проброс порта для Pi-hole dashboard (ТОЛЬКО через VPN!)
/ip/firewall/nat/add chain=dstnat action=dst-nat to-addresses=172.17.0.2 to-ports=80 protocol=tcp dst-port=8053 in-interface-list=WAN comment="Pi-hole dashboard (disable in production!)"
# Заходим внутрь контейнера
/container/shell 0
# Внутри контейнера:
# pihole -g
# exit
# Заходим в контейнер
/container/shell 0
# Внутри:
# pihole status
# pihole -c (console dashboard)
# pihole -t (tail log в реальном времени)
# exit
# Общее состояние системы
/system/resource/print
# Статус контейнера
/container/print detail
# Логи контейнера в системном журнале
/log/print where topics~"container"
# Скрипт проверки Pi-hole и переключения на резервный DNS
/system/script/add name=pihole-failover source={
:local piholeIP "172.17.0.2"
:local fallbackDNS "1.1.1.1,8.8.8.8"
:local normalDNS $piholeIP
:do {
/tool/dns-query name=google.com server=$piholeIP
} on-error={
:local currentDNS [/ip/dns/get servers]
:if ($currentDNS = $normalDNS) do={
/ip/dns/set servers=$fallbackDNS
:log warning "Pi-hole is DOWN! Switched to fallback DNS: $fallbackDNS"
# Попытка перезапуска контейнера
:do { /container/start [/container/find where comment~"Pi-hole"] } on-error={}
}
}
:do {
/tool/dns-query name=google.com server=$piholeIP
:local currentDNS [/ip/dns/get servers]
:if ($currentDNS != $normalDNS) do={
/ip/dns/set servers=$normalDNS
:log info "Pi-hole is UP! Switched back to Pi-hole DNS"
}
} on-error={}
}
/system/scheduler/add name=pihole-failover interval=1m on-event="/system/script/run pihole-failover"
# 1. Контейнер запущен
/container/print
# status должен быть "running"
# 2. Pi-hole отвечает на DNS
/tool/dns-query name=google.com server=172.17.0.2
# Должен вернуть IP-адрес
# 3. Pi-hole блокирует рекламу
/tool/dns-query name=ads.doubleclick.net server=172.17.0.2
# Должен вернуть 0.0.0.0
# 4. MikroTik DNS пересылает запросы через Pi-hole
/ip/dns/print
# servers должен содержать 172.17.0.2
# 5. DHCP раздаёт правильный DNS
/ip/dhcp-server/network/print
# 6. Перехват DNS работает
/ip/firewall/nat/print where comment~"Force DNS"
# 7. Сетевая связность контейнера
/ping 172.17.0.2 count=4
# Проверяем свободную RAM
/system/resource/print
# free-memory должно быть больше 256 МБ
# Увеличиваем лимит RAM для контейнеров
/container/config/set ram-high=512M
# Если RAM мало — уменьшите списки фильтров в Pi-hole
# Используйте только основной список (Steven Black)
# Вариант 1: Ограничьте MikroTik DNS — не слушать на container bridge
# (RouterOS не позволяет указать интерфейс для DNS, но можно через firewall)
/ip/firewall/filter/add chain=input action=drop protocol=udp dst-port=53 in-interface=bridge-containers src-address=!172.17.0.0/24 comment="Block external DNS to container bridge"
# Вариант 2: Если используете подход 2 (клиенты -> Pi-hole напрямую):
# Отключите MikroTik DNS полностью
/ip/dns/set allow-remote-requests=no
# Проверяем статус контейнера
/container/print
# Должен быть status: running
# Проверяем сетевую связность
/ping 172.17.0.2 count=4
# Проверяем HTTP-доступность
/tool/fetch url="http://172.17.0.2/admin" mode=http dst-path=pihole-test.html
# Проверяем, нет ли блокирующих правил firewall
/ip/firewall/filter/print where dst-address=172.17.0.2
# 1. Проверяем, что Pi-hole отвечает блокировкой
/tool/dns-query name=ads.doubleclick.net server=172.17.0.2
# Если возвращает реальный IP — gravity не загружен
# 2. Заходим в контейнер и обновляем gravity
/container/shell 0
# pihole -g
# exit
# 3. Проверяем, что DNS-перенаправление работает
/ip/firewall/nat/print where comment~"Force DNS"
# 4. Для устройств с DoH (Firefox, Chrome):
# Заблокируйте DoH-серверы на уровне firewall
/ip/firewall/filter/add chain=forward action=reject protocol=tcp dst-port=443 dst-address-list=doh-servers reject-with=tcp-reset comment="Block DoH bypass"
# Добавьте известные DoH-серверы в address-list
/ip/firewall/address-list/add list=doh-servers address=dns.google comment="Google DoH"
/ip/firewall/address-list/add list=doh-servers address=cloudflare-dns.com comment="Cloudflare DoH"
/ip/firewall/address-list/add list=doh-servers address=dns.quad9.net comment="Quad9 DoH"
# Скрипт отложенного запуска
/system/script/add name=start-pihole source={
:delay 30s
:local id [/container/find where comment~"Pi-hole"]
:if ([:len $id] > 0) do={
:local status [/container/get $id status]
:if ($status != "running") do={
/container/start $id
:log info "Pi-hole container started after boot delay"
}
}
}
/system/scheduler/add name=start-pihole on-event="/system/script/run start-pihole" start-time=startup interval=0
# Проверяем загрузку
/system/resource/print
# Если CPU загружен постоянно — уменьшите количество списков фильтров
# Оставьте только 1-2 основных списка
# Увеличьте DNS-кэш MikroTik (если используете подход 1)
/ip/dns/set cache-size=4096KiB
# Ограничьте количество DNS-запросов через firewall
/ip/firewall/filter/add chain=forward action=drop protocol=udp dst-port=53 dst-address=172.17.0.2 connection-limit=50,32 comment="Limit DNS queries to Pi-hole"
# 1. Остановите контейнер
/container/stop [/container/find where comment~"Pi-hole"]
# 2. Удалите контейнер (данные в mounts сохранятся!)
/container/remove [/container/find where comment~"Pi-hole"]
# 3. Пересоздайте с тем же образом (скачается новая версия)
/container/add remote-image=pihole/pihole:latest interface=veth-pihole root-dir=usb1/pihole/root envlist=pihole-env mounts=pihole-etc,pihole-dnsmasq start-on-boot=yes hostname=pihole logging=yes comment="Pi-hole DNS filter"
# 4. Дождитесь скачивания и запустите
/container/print
/container/start 0