Настройка DNS-сервера в Linux: BIND, dnsmasq и systemd-resolved — пошаговые руководства для DevOps и сисадминов | AdminWiki

Настройка DNS-сервера в Linux: BIND, dnsmasq и systemd-resolved — пошаговые руководства для DevOps и сисадминов

28 июля 2026 10 мин. чтения

Выбор DNS-сервера для Linux сводится к трем основным инструментам: BIND для управления собственными зонами, dnsmasq для легковесного кэширования и systemd-resolved для современных дистрибутивов с systemd. Каждый из них решает конкретную задачу, и неверный выбор приводит к избыточному потреблению ресурсов или неработающей конфигурации. В этой статье мы разберем все три решения с готовыми конфигурациями, которые вы сможете применить сразу после прочтения.

Инструкции проверены на Debian 12, Ubuntu 24.04 LTS и Rocky Linux 9. Вы получите точные команды для установки, настройки и диагностики, а также рекомендации по безопасности и отказоустойчивости. Материал ориентирован на системных администраторов и DevOps-инженеров, которым нужно быстро развернуть надежный DNS-сервер без риска допустить критическую ошибку в production-среде.

Какой DNS-сервер выбрать: сравнение BIND, dnsmasq и systemd-resolved

BIND (Berkeley Internet Name Domain) - это полноценный авторитетный DNS-сервер, способный обслуживать собственные зоны и выполнять рекурсивные запросы. Его демон named управляет зонами прямого и обратного просмотра, поддерживает DNSSEC, репликацию master/slave и тонкую настройку через ACL. BIND выбирают, когда нужно поднять внутренний DNS для домена компании или организовать публичный авторитетный сервер.

dnsmasq - легковесный кэширующий DNS-форвардер, часто совмещенный с DHCP-сервером. Он потребляет минимум ресурсов и идеально подходит для локального кэширования запросов, ускорения разрешения имен и фильтрации нежелательных доменов. Типичный сценарий: кэширующий сервер на шлюзе или в небольшой офисной сети, где не нужны собственные зоны.

systemd-resolved - встроенный резолвер, который управляет DNS-настройками через systemd. Он предоставляет поканальную конфигурацию DNS, кэширование и валидацию DNSSEC. Этот инструмент уже установлен в большинстве современных дистрибутивов и заменяет статический /etc/resolv.conf динамически управляемой заглушкой.

Критерий BIND dnsmasq systemd-resolved
Сложность настройки Высокая Низкая Средняя
Потребление RAM 50-200 МБ 5-20 МБ 10-30 МБ
Авторитетные зоны Да Нет Нет
Кэширование Да Да Да
DHCP-сервер Нет Да Нет
DNSSEC Полная поддержка Ограниченная Валидация
Типовой сценарий Внутренняя зона компании Локальный кэш/форвардер Управление DNS на хосте

Рекомендация простая. Нужна собственная зона с A, CNAME, PTR-записями - ставьте BIND. Требуется ускорить разрешение имен и снизить нагрузку на внешние серверы - берите dnsmasq. Работаете с systemd и хотите гибко управлять DNS-серверами на уровне интерфейсов - используйте systemd-resolved. Подробнее о кэшировании и его влиянии на производительность читайте в руководстве по оптимизации DNS-кеширования.

Настройка dnsmasq как кэширующего DNS-сервера

dnsmasq разворачивается за пять минут и сразу дает прирост скорости разрешения повторных запросов. При первом обращении к домену запрос уходит на upstream-сервер и занимает 20-50 мс. После кэширования ответ возвращается за 0-2 мс. Конфигурация состоит из одного файла, а логика работы прозрачна для отладки.

Установка и базовая конфигурация dnsmasq

Установка на Debian/Ubuntu:

sudo apt update && sudo apt install dnsmasq -y

Установка на Rocky Linux/AlmaLinux:

sudo dnf install dnsmasq -y

Перед редактированием конфигурации сохраните оригинал:

sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.backup

Минимальная рабочая конфигурация в /etc/dnsmasq.conf:

# Порт для приема DNS-запросов
port=53
# Слушать на localhost и внутреннем интерфейсе
listen-address=127.0.0.1
listen-address=192.168.1.1
# Не принимать запросы с других интерфейсов (кроме указанных в listen-address)
bind-interfaces
# Размер кэша (по умолчанию 150, увеличиваем для сервера)
cache-size=1000
# Upstream DNS-серверы
server=1.1.1.1
server=8.8.8.8
# Не пересылать запросы для коротких имен (без точки)
domain-needed
# Не пересылать запросы для приватных диапазонов (RFC 1918)
bogus-priv
# Логирование запросов
log-queries
log-facility=/var/log/dnsmasq.log

Параметр bind-interfaces заставляет dnsmasq слушать только интерфейсы, явно указанные в listen-address. Без него демон по умолчанию принимает запросы на всех интерфейсах, включая внешние, что создает открытый резолвер и риск участия в DNS-амплификационных атаках.

После сохранения конфигурации перезапустите сервис и добавьте его в автозагрузку:

sudo systemctl restart dnsmasq
sudo systemctl enable dnsmasq

Проверьте статус:

sudo systemctl status dnsmasq

Если порт 53 занят другим процессом (часто systemd-resolved), освободите его. Остановите systemd-resolved и отключите его заглушку:

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo rm /etc/resolv.conf
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

Затем укажите ваш dnsmasq в /etc/resolv.conf:

nameserver 127.0.0.1

Проверка работы кэширующего DNS

Первый запрос к домену всегда медленнее - данные берутся с upstream-сервера. Измерьте время:

dig @127.0.0.1 example.com | grep "Query time"

Повторите команду. Второй ответ должен вернуться за 0-2 мс, так как запись уже в кэше. Для массовой проверки используйте цикл:

for i in {1..3}; do dig @127.0.0.1 example.com | grep "Query time"; done

Логи dnsmasq показывают, какие запросы кэшированы, а какие ушли на upstream:

sudo tail -f /var/log/dnsmasq.log

Типичная ошибка - dnsmasq не стартует с сообщением failed to bind listening socket. Причина: порт 53 уже занят. Найдите процесс:

sudo ss -tulpn | grep :53

Вторая частая проблема - клиенты не получают ответы. Проверьте, что в listen-address указан IP интерфейса, доступного клиентам, и что файрвол разрешает входящие соединения на порт 53:

sudo firewall-cmd --add-service=dns --permanent
sudo firewall-cmd --reload

Развертывание авторитетного DNS-сервера с BIND для внутренней зоны

BIND управляет зонами через текстовые файлы, которые описывают соответствие доменных имен IP-адресам. Конфигурация разделена на несколько файлов: главный named.conf подключает остальные, named.conf.options содержит глобальные настройки, named.conf.local описывает локальные зоны, а файлы зон хранят сами записи.

Установка на Debian/Ubuntu:

sudo apt update && sudo apt install bind9 bind9utils bind9-doc -y

Установка на Rocky Linux/AlmaLinux:

sudo dnf install bind bind-utils -y

Глобальные настройки в /etc/bind/named.conf.options (Debian) или /etc/named.conf (Rocky):

options {
    directory "/var/cache/bind";
    # Кто может делать рекурсивные запросы
    allow-recursion { localhost; 192.168.1.0/24; };
    # Кто может запрашивать кэш
    allow-query-cache { localhost; 192.168.1.0/24; };
    # Пересылка внешних запросов
    forwarders {
        1.1.1.1;
        8.8.8.8;
    };
    forward only;
    # DNSSEC-валидация
    dnssec-validation auto;
    # Слушать на всех интерфейсах
    listen-on { any; };
    listen-on-v6 { any; };
};

ACL allow-recursion определяет, каким клиентам BIND будет выполнять рекурсивные запросы. Указание конкретных подсетей вместо any предотвращает использование вашего сервера как открытого резолвера для DDoS-атак.

Создание и настройка зоны прямого просмотра

Опишите локальные зоны в named.conf.local:

zone "example.local" {
    type master;
    file "/etc/bind/db.example.local";
};

Создайте файл зоны /etc/bind/db.example.local:

$TTL 86400
@   IN  SOA ns1.example.local. admin.example.local. (
        2026072801  ; Serial (YYYYMMDDNN)
        3600        ; Refresh
        1800        ; Retry
        604800      ; Expire
        86400       ; Minimum TTL
)
@       IN  NS  ns1.example.local.
@       IN  A   192.168.1.10
ns1     IN  A   192.168.1.10
web     IN  A   192.168.1.20
db      IN  A   192.168.1.30
mail    IN  CNAME   web
app     IN  A   192.168.1.40

Запись SOA (Start of Authority) содержит метаданные зоны. Серийный номер (Serial) нужно увеличивать при каждом изменении - стандартный формат YYYYMMDDNN исключает путаницу. TTL 86400 секунд (24 часа) означает, что кэширующие серверы будут хранить записи сутки. Для внутренней зоны с частыми изменениями уменьшите TTL до 300-600 секунд.

Проверьте синтаксис зоны перед загрузкой:

sudo named-checkzone example.local /etc/bind/db.example.local

Ожидаемый вывод: zone example.local/IN: loaded serial 2026072801 OK. Если есть ошибки, named-checkzone укажет строку и характер проблемы.

Настройка обратной зоны и проверка разрешения имен

Обратная зона сопоставляет IP-адреса именам (PTR-записи). Добавьте в named.conf.local:

zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/db.192.168.1";
};

Файл /etc/bind/db.192.168.1:

$TTL 86400
@   IN  SOA ns1.example.local. admin.example.local. (
        2026072801
        3600
        1800
        604800
        86400
)
@       IN  NS  ns1.example.local.
10      IN  PTR ns1.example.local.
20      IN  PTR web.example.local.
30      IN  PTR db.example.local.
40      IN  PTR app.example.local.

Проверьте обратную зону:

sudo named-checkzone 1.168.192.in-addr.arpa /etc/bind/db.192.168.1

Проверьте главный конфиг:

sudo named-checkconf

Если команда не выдает ошибок, конфигурация корректна. Перезапустите BIND:

sudo systemctl restart named   # Rocky Linux
sudo systemctl restart bind9   # Debian/Ubuntu
sudo systemctl enable named

Тестирование прямой зоны:

dig @127.0.0.1 web.example.local

Тестирование обратной зоны:

dig @127.0.0.1 -x 192.168.1.20

Оба запроса должны вернуть корректные ответы. Для интеграции BIND с другими платформами обратитесь к руководству по DNS-маршрутизации в смешанных средах.

Управление DNS через systemd-resolved в современных дистрибутивах

systemd-resolved заменяет классический подход с /etc/resolv.conf на динамическое управление через D-Bus. Демон поддерживает поканальную конфигурацию: для каждого сетевого интерфейса можно задать свои DNS-серверы и домены поиска. Это удобно при работе с VPN, когда трафик должен разрешаться через корпоративные серверы, а остальные запросы - через публичные.

Проверьте текущее состояние:

resolvectl status

Вывод покажет глобальные DNS-серверы, настройки для каждого интерфейса и состояние DNSSEC. Если вы видите 127.0.0.53 в /etc/resolv.conf, значит systemd-resolved активен и управляет разрешением имен через свою заглушку.

Изменение DNS-серверов с помощью resolvectl

Установка глобальных DNS-серверов (применяются ко всем интерфейсам, где нет явной конфигурации):

sudo resolvectl dns eth0 1.1.1.1 8.8.8.8

Настройка DNS только для VPN-интерфейса:

sudo resolvectl dns wg0 10.0.0.1 10.0.0.2
sudo resolvectl domain wg0 "~corp.local"

Символ тильды (~) перед доменом указывает, что это домен только для маршрутизации DNS-запросов - он не будет добавляться в список поиска. Запросы для *.corp.local пойдут через DNS-серверы интерфейса wg0, остальные - через глобальные.

Включение DNSSEC-валидации в /etc/systemd/resolved.conf:

[Resolve]
DNS=1.1.1.1 8.8.8.8
DNSSEC=allow-downgrade
Cache=yes
DNSStubListener=yes

Параметр DNSSEC=allow-downgrade включает проверку подлинности ответов, но разрешает работу, если upstream-сервер не поддерживает DNSSEC. Для строгой валидации используйте DNSSEC=yes, но учтите, что часть доменов может перестать разрешаться.

Примените изменения:

sudo systemctl restart systemd-resolved

Проверка DNSSEC:

dig @127.0.0.53 cloudflare.com +dnssec | grep flags

Флаг ad (authenticated data) в ответе подтверждает, что запись прошла валидацию.

Обеспечение безопасности и отказоустойчивости DNS-сервера

DNS-сервер, открытый для неограниченной рекурсии, становится инструментом для амплификационных DDoS-атак. Злоумышленник отправляет запрос размером 60 байт, а сервер возвращает ответ на 3000 байт, умножая трафик в 50 раз. Защита начинается с ACL, ограничивающих рекурсию только доверенными подсетями.

Для BIND настройте ACL в named.conf.options:

acl "trusted" {
    localhost;
    192.168.1.0/24;
    10.0.0.0/8;
};
options {
    allow-recursion { trusted; };
    allow-query { trusted; };
    recursion yes;
};

Репликация зон master/slave обеспечивает отказоустойчивость. На master-сервере укажите IP slave в директиве allow-transfer:

zone "example.local" {
    type master;
    file "/etc/bind/db.example.local";
    allow-transfer { 192.168.1.11; };
    also-notify { 192.168.1.11; };
};

На slave-сервере зона описывается как type slave с указанием IP мастера:

zone "example.local" {
    type slave;
    file "/var/cache/bind/db.example.local";
    masters { 192.168.1.10; };
};

Директива also-notify заставляет мастер немедленно уведомлять slave об изменениях зоны, вместо ожидания следующего цикла обновления по таймеру Refresh.

Настройка DNSSEC-валидации в BIND и systemd-resolved

DNSSEC добавляет цифровую подпись к DNS-ответам, исключая подмену записей (DNS spoofing). В BIND валидация включается одной строкой в named.conf.options:

dnssec-validation auto;

BIND автоматически загрузит корневые ключи и начнет проверять подписи для всех рекурсивных запросов. Проверка:

dig @127.0.0.1 sigok.verteiltesysteme.net +dnssec

Ответ должен содержать флаг ad. Для настройки DNSSEC на уровне всей сети, включая DoT и DoH, используйте готовые конфигурации Unbound и BIND9 с автоматизацией через OpenDNSSEC.

В systemd-resolved DNSSEC настраивается в /etc/systemd/resolved.conf параметром DNSSEC=allow-downgrade. После перезапуска демона проверьте статус:

resolvectl status | grep DNSSEC

Диагностика и решение типичных проблем при настройке DNS

Сервер не запускается. Первое действие - проверка логов:

sudo journalctl -u named -n 50 --no-pager   # BIND
sudo journalctl -u dnsmasq -n 50 --no-pager  # dnsmasq

Синтаксические ошибки в конфигурации - самая частая причина. Для BIND всегда запускайте named-checkconf и named-checkzone перед перезапуском. Для dnsmasq проверьте конфиг явным запуском в foreground-режиме:

sudo dnsmasq --test

Имена не разрешаются. Проверьте цепочку: клиент → ваш DNS → upstream. Используйте dig с явным указанием сервера на каждом этапе:

dig @192.168.1.10 example.com    # запрос к вашему BIND/dnsmasq
dig @1.1.1.1 example.com         # запрос напрямую к upstream

Если прямой запрос к upstream работает, а через ваш сервер - нет, проблема в конфигурации форвардинга или ACL. Проверьте, что upstream-серверы указаны верно и доступны по сети.

Медленные ответы при первом запросе - норма. Медленные ответы при повторных запросах указывают на то, что кэширование не работает. Проверьте размер кэша в dnsmasq (cache-size) или настройки BIND (max-cache-size). Для анализа текущего состояния кэша воспользуйтесь руководством по мониторингу и анализу кэша DNS-серверов.

Захват трафика для отладки:

sudo tcpdump -i eth0 port 53 -n

Эта команда покажет все DNS-запросы и ответы на интерфейсе eth0. Вы увидите, уходят ли запросы на upstream, возвращаются ли ответы и какие коды ошибок приходят.

Конфликт systemd-resolved с другими DNS-серверами решается остановкой systemd-resolved и восстановлением статического /etc/resolv.conf. Альтернативный вариант - настроить systemd-resolved на пересылку запросов вашему локальному серверу через параметр DNS=127.0.0.1 в resolved.conf. Выбор зависит от того, нужна ли вам поканальная конфигурация DNS или достаточно глобального сервера.

Поделиться:
Сохранить гайд? В закладки браузера