MAATRIX / Блог / Technitium DNS в Docker Compose: готовый файл

Technitium DNS в Docker Compose: готовый файл

MAATRIX

Pi-hole и AdGuard Home закрывают только блокировку рекламы на уровне DNS, а как только нужна своя авторитетная зона, DNSSEC или приём запросов по DoH/DoT без отдельного прокси перед сервером — приходится городить второй сервис рядом. Technitium DNS Server решает всё это одним контейнером с полноценной веб-панелью: рекурсивный резолвер, блокировщик, авторитетный DNS для своих доменов и шифрование транспорта — без единой правки текстовых конфигов руками. Ниже — рабочий docker-compose.yml и порядок настройки от первого запуска до подписанной DNSSEC-зоны.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Чем Technitium отличается от Pi-hole и AdGuard Home

Pi-hole построен вокруг dnsmasq и веб-морды над ним, AdGuard Home — собственный резолвер попроще, оба хороши ровно для одной задачи: резать рекламу и трекеры по спискам доменов для домашней или VPN-сети. Technitium — это полноценный DNS-сервер общего назначения (написан на .NET, кроссплатформенный), который умеет всё то же самое, но плюс:

  • Авторитетные зоны — можно поднять собственный DNS для домена прямо на сервере, без стороннего DNS-хостинга, включая primary/secondary-зоны и зонный трансфер (AXFR/IXFR);
  • DNSSEC из коробки — подпись зон через веб-панель, без ручной генерации ключей DS/DNSKEY командами;
  • DoH, DoT и DNS-over-QUIC на приём — сервер сам умеет отвечать по зашифрованным протоколам, не нужен отдельный cloudflared или nginx перед ним;
  • API и логика через плагины — правила блокировки, условная переадресация по доменам, регэкспы, сплит-хортинг (разные ответы в зависимости от того, кто спрашивает).
ЗадачаPi-hole / AdGuard HomeTechnitium
Блокировка рекламы по спискамДа, это основная задачаДа, встроенный блок-плагин
Своя авторитетная зона (свой домен)Нет, только форвардингДа, полноценный primary/secondary DNS
DNSSEC-подпись своих зонНетДа, из веб-панели
Приём DoH/DoT/DoQ без проксиНет (нужен доп. сервис)Да, встроено
Порог входаНиже, проще для стартаВыше, но окупается на смешанных задачах

Если задача — только резать рекламу для дома, Pi-hole или AdGuard Home остаются проще. Technitium оправдан, когда нужен DNS-сервер и для блокировки, и для своих зон, и для шифрованного транспорта — одним контейнером вместо трёх.

Готовый docker-compose.yml

Создайте рабочую директорию:

mkdir -p ~/technitium && cd ~/technitium
mkdir -p config
nano docker-compose.yml

Содержимое docker-compose.yml:

services:
  technitium-dns:
    container_name: technitium-dns
    image: technitium/dns-server:latest
    hostname: dns1
    restart: unless-stopped
    environment:
      TZ: "Europe/Moscow"
      DNS_SERVER_DOMAIN: "dns1.example.com"
      DNS_SERVER_ADMIN_PASSWORD_FILE: /run/secrets/dns_admin_password
      DNS_SERVER_RECURSION: "Allow"
      DNS_SERVER_RECURSION_NETWORK_ACL: "10.13.13.0/24"
    volumes:
      - ./config:/etc/dns
    ports:
      # обычные DNS-запросы — только через адрес VPN-интерфейса
      - "10.13.13.1:53:53/udp"
      - "10.13.13.1:53:53/tcp"
      # веб-панель управления
      - "10.13.13.1:5380:5380/tcp"
      # DoT — можно оставить открытым публично, это шифрованный транспорт
      - "853:853/tcp"
      # DoH — тоже можно наружу, если нужен доступ извне VPN
      - "8443:443/tcp"
    secrets:
      - dns_admin_password

secrets:
  dns_admin_password:
    file: ./dns_admin_password.txt

Пароль администратора — не в открытой переменной окружения, а в отдельном файле, чтобы не светился в docker inspect:

openssl rand -base64 18 > dns_admin_password.txt
chmod 600 dns_admin_password.txt

Смысл разделения портов в примере: обычный незашифрованный DNS (53/udp, 53/tcp) и веб-панель биндятся только на адрес WireGuard-туннеля (10.13.13.1 — замените на свой), а DoT и DoH можно оставить смотрящими наружу — они шифрованы и не годятся для DNS-амплификации так же легко, как голый 53-й порт. Если вы разворачивали похожую схему для Pi-hole, идея биндинга на VPN-интерфейс уже знакома — здесь она работает тем же образом, подробности логики в статье про Pi-hole в Docker Compose.

Про DNS_SERVER_RECURSION_NETWORK_ACL — эта переменная разрешает рекурсивные запросы только с указанной подсети, а не всему интернету. Без неё, если 53-й порт случайно окажется публично доступен, сервер превращается в открытый резолвер — вектор для DDoS-амплификации.

./config вынесен наружу контейнера как bind-mount, а не анонимный volume, по той же логике, что разобрана в статье про типы Docker volumes: без него обновление образа стирало бы все зоны, ключи DNSSEC и настройки блокировки. Подход к паролям через secrets вместо голых переменных окружения разобран в статье про Docker secrets.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Первый запуск и вход в веб-панель

Поднимаем стек и смотрим логи:

docker compose up -d
docker compose logs -f technitium-dns

Дождитесь строки о готовности DNS-сервера (в логах видно старт HTTP-сервиса на порту 5380), после чего панель доступна по http://10.13.13.1:5380 — то есть только тем, кто подключён к вашему WireGuard. Если VPN ещё не настроен, сначала разверните его — есть пошаговый разбор WireGuard на Ubuntu 24.04, без туннеля открывать DNS-порт наружу небезопасно.

Логин по умолчанию — admin, пароль — тот, что задан через DNS_SERVER_ADMIN_PASSWORD_FILE при первом старте контейнера (переменная считывается только при первой инициализации /etc/dns, повторный запуск не перечитает её — смену пароля после первого входа делаете в самой панели).

Что проверить сразу после входа: Settings → General (домен сервера, часовой пояс логов), Settings → Web Service (TLS-сертификат для самой панели, если она должна открываться снаружи VPN по HTTPS) и Settings → Optional Protocols, где включаются DoT/DoH/DoQ — об этом отдельно ниже.

Проверка резолва с клиента, подключённого к WireGuard:

dig @10.13.13.1 example.com

Если ответ приходит — базовая часть работает, дальше настраиваем блокировку и зоны.

Блокировка рекламы и трекеров

Блокировка в Technitium делается через Settings → Blocking, логика похожа на Pi-hole и AdGuard Home, но с более гибким управлением уровнями:

  • Blocking TypeNxDomain (сервер отвечает "домен не существует") или AnyAddress (отдаёт заглушку-адрес). Для обычных клиентов NxDomain работает чище — не создаёт видимость живого сайта.
  • Block List URLs — сюда добавляются ссылки на списки в формате hosts или AdBlock. Подходят те же источники, что и для Pi-hole/AdGuard Home:
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
https://big.oisd.nl/
  • Local Domains / Allowed — точечные исключения, если список блокировки задел легитимный сервис (частая история с виджетами оплаты или капчей).

После добавления списков — Update Now в том же разделе, обновление списков по расписанию настраивается там же через Update Interval (в часах), крон на хосте городить не нужно — это встроено в сам сервер.

Отдельно есть Advanced Blocking (Apps → Install → Advanced Blocking) — плагин для блокировки по группам клиентов (разные списки для гостевой сети и рабочих устройств) или по расписанию, вместо одного общего списка на весь сервер.

Своя авторитетная зона

Здесь Technitium уходит в сторону от простых DNS-блокировщиков — сервер может быть авторитетным для собственного домена, то есть отвечать на запросы к нему сам, без обращения к внешним DNS-провайдерам.

Создание зоны — Zones → Add Zone:

  1. Тип — Primary Zone, вводите имя домена (например, example.com).
  2. После создания зоны добавляете записи через Add Record: A/AAAA для адресов, CNAME для алиасов, MX для почты, TXT для верификаций (SPF/DKIM в том числе).
  3. Если домен зарегистрирован у стороннего регистратора, на его стороне в NS-записях домена нужно указать этот сервер (например, dns1.example.com) как авторитетный — регистратор должен об этом знать, иначе запросы к домену продолжат идти на старый DNS.

Для отказоустойчивости имеет смысл вторая нода — Secondary Zone на другом сервере, тянущая данные с primary через зонный трансфер; настройка отдельного экземпляра в рамках этой статьи не разбираем. Сама возможность — то, чего нет у Pi-hole и AdGuard Home и что в классическом BIND9 через Docker Compose пришлось бы собирать текстовыми зонными файлами руками, а здесь — кликами в панели.

DoH и DoT — приём зашифрованных запросов

Обычный DNS по 53-му порту ходит открытым текстом — провайдер или любой на маршруте видит, какие домены вы резолвите. DoH (DNS-over-HTTPS) и DoT (DNS-over-TLS) шифруют этот трафик, и Technitium умеет принимать оба протокола сам, без отдельного reverse-proxy перед собой.

Включается в Settings → Optional Protocols:

  • DNS-over-TLS (DoT) — порт 853 в примере compose-файла выше уже проброшен наружу. Клиенты (например, Android с системной настройкой Private DNS) подключаются к dns1.example.com напрямую.
  • DNS-over-HTTPS (DoH) — порт 443 внутри контейнера, наружу в примере выброшен на 8443, чтобы не конфликтовать с другими веб-сервисами на том же сервере, если они есть. Клиенты обращаются по адресу вида https://dns1.example.com:8443/dns-query.

Для обоих протоколов нужен TLS-сертификат — Technitium поддерживает и импорт готового PFX/PEM-файла, и (в части версий) встроенный ACME-клиент для автовыпуска через Let's Encrypt прямо из Settings → Web Service. Если предпочитаете привычный отдельный инструмент — есть разбор Let's Encrypt SSL на VPS, сертификат затем импортируется в панель файлом.

После включения полезно проверить, что запросы реально идут шифрованным каналом, а не резервным незащищённым путём — методика из статьи про проверку DNS leak через VPN применима и здесь.

DNSSEC для своих зон

DNSSEC защищает от подмены DNS-ответов на маршруте — резолвер клиента проверяет цифровую подпись ответа и отбрасывает подделку. Для авторитетной зоны, которую вы держите на своём Technitium, включение — несколько кликов вместо ручной возни с dnssec-keygen и файлами ключей, как это делается в классическом BIND:

  1. Zones → [ваша зона] → DNSSEC → Sign Zone.
  2. Выбираете алгоритм — по умолчанию подходит ECDSAP256SHA256, современный и компактный по размеру подписей.
  3. После подписи панель покажет DS-запись (Delegation Signer) — её нужно вручную добавить в панели регистратора домена, в разделе DNSSEC. Без этого шага подпись зоны существует, но родительская зона (.com, .io и так далее) не знает, что доверять DNSSEC для вашего домена — цепочка доверия обрывается.
  4. Проверка после прописывания DS-записи (может занять время на распространение у регистратора):
dig +dnssec example.com @10.13.13.1

В ответе должны появиться записи RRSIG рядом с обычными A/MX-записями.

Отдельно стоит включить DNSSEC-валидацию на сам рекурсивный резолвер (Settings → DNSSEC, отдельная опция от подписи своих зон) — тогда сервер сам отбрасывает поддельные ответы при резолве чужих доменов, а не только защищает исходящие ответы по своей зоне.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Technitium подходит как замена Pi-hole для простой блокировки рекламы дома?

Технически да, но это оверинжиниринг для такой задачи — AdGuard Home проще ставится и понятнее в интерфейсе, если нужна только блокировка. Technitium оправдан, когда вдобавок нужна своя зона, DNSSEC или встроенный приём DoH/DoT.

Нужен ли отдельный домен для веб-панели и DoH, если авторитетную зону поднимать не планирую?

Нет, DNS_SERVER_DOMAIN — просто имя, под которым сервер представляется (используется в hostname сертификата и внутренних проверках), зону поднимать не обязательно.

Что будет с DNSSEC-подписанной зоной при перевыпуске ключей?

Панель поддерживает ротацию ключей (KSK/ZSK) в том же разделе DNSSEC, но конкретные тайминги стоит сверять с официальной документацией на момент настройки — логика ротации могла обновиться между релизами.

Обязательно ли ограничивать 53-й порт VPN-интерфейсом, если сервер и так за фаерволом?

Да, биндинг на конкретный адрес — защита на уровне приложения, а не только сетевого экрана. Даже если правило ufw случайно снимут, порт 53 просто не будет слушать на публичном интерфейсе.

Можно ли использовать Technitium как единственный DNS для инфраструктуры компании?

Можно (secondary-зоны, зонный трансфер, API для автоматизации записей), но для продакшена стоит поднимать минимум два экземпляра — primary и secondary — на разных серверах, чтобы отказ одного не клал резолв целиком.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →