Выбор 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 или достаточно глобального сервера.