Настройка systemd-resolved для локального кэширования DNS в Debian 10
Что такое systemd-resolved
systemd-resolved — это сервис systemd для локального резолвинга DNS запросов. По сути это локальный мини DNS-сервер с поддержкой кеширования, DNSSEC и DNSOverTLS. При включенном кешировании он позволяет ускорить резолвинг DNS запросов, особенно при включенном DNSSEC.
Он полезен для уменьшения задержек резолвинга при использовании нестабильных интернет-провайдеров и при недолгих падениях DNS серверов (в пределах TTL DNS записей доменов, к которым идут запросы). Также не помешает на серверах, где идет много запросов на резолвинг имен (почтовые сервера, сервера мониторинга, сервера с большим количеством задач с запросом данных с удаленных источников).
Установка и настройка systemd-resolved
В статье настройка производится на Debian 10, но будет актуальна и для других дистрибутивов с systemd (возможно с некоторыми поправками).
Этот сервис в Debian 10 уже идет из коробки вместе с systemd (как и на многих других дистрибутивах с предустановленным systemd). Устанавливать его не нужно. И по умолчанию он обычно отключен.
Для того, чтобы резолвинг DNS в софте шел через systemd-resolved, необходимо установить libnss-resolve
, плагин для механизма NSS (GNU Name Service Switch):
apt install libnss-resolve
Открываем конфиг systemd-resolved (/etc/systemd/resolved.conf
). По умолчанию все значения закомментированы и используются дефолтные значения:
[Resolve]
#DNS=
#FallbackDNS=
#Domains=
#LLMNR=yes
#MulticastDNS=yes
#DNSSEC=allow-downgrade
#DNSOverTLS=no
#Cache=yes
#DNSStubListener=yes
#ReadEtcHosts=yes
Приводим конфиг примерно к такому виду:
[Resolve]
DNS=8.8.8.8 8.8.4.4 1.1.1.1 1.0.0.1
FallbackDNS=80.80.80.80 80.80.81.81 64.6.64.6 64.6.65.6
#Domains=
#LLMNR=yes
#MulticastDNS=yes
DNSSEC=no
DNSOverTLS=no
Cache=yes
#DNSStubListener=yes
#ReadEtcHosts=yes
где:
DNS
— список основных IPv4 и IPv6 адресов DNS серверов, разделенных пробелами;FallbackDNS
— список запасных IPv4 и IPv6 адресов DNS серверов, разделенных пробелами (будут использоваться, если основные окажутся недоступными).
DNSSEC и DNSOverTLS включаем при необходимости.
Подробнее о них и информацию по настройке остальных параметров можно посмотреть в доке:
man resolved.conf
Запускаем systemd-resolved:
systemctl start systemd-resolved
Проверяем статус сервиса:
systemctl status systemd-resolved
Сервис запустился и работает.
Добавляем в автозапуск при старте системы:
systemctl enable systemd-resolved
Проверить текущие настройки резолвера можно командой:
resolvectl status
Проверка кеша DNS запросов
Для проверки работы кеша можно перевести сервис в режим отладки и проверить в журнале сервиса его работу. Для этого необходимо прописать нужный параметр в файл юнита. Чтобы не трогать его напрямую, добавим параметр через drop in юнит (дополнительный юнит, который подключается в основной и добавляет/изменяет его параметры):
systemctl edit systemd-resolved
Вставляем туда следующее:
[Service]
Environment=SYSTEMD_LOG_LEVEL=debug
Сохраняем и выходим. Юнит будет автоматически перезапущен.
Открываем журнал сервиса в живом режиме:
journalctl -f -u systemd-resolved
И ждем появления информации.
Вот пример двух запросов резолвинга домена:
Looking up RR for play.google.com IN A.
Looking up RR for play.google.com IN AAAA.
Cache miss for play.google.com IN A
Transaction 41663 for <play.google.com IN A> scope dns on */*.
Added positive unauthenticated cache entry for play.google.com IN A 268s on eth0/INET/213.133.100.100
Transaction 41663 for <play.google.com IN A> on scope dns on */* now complete with <success> from network (unsigned).
...
Looking up RR for play.google.com IN A.
Looking up RR for play.google.com IN AAAA.
Positive cache hit for play.google.com IN A
Transaction 53685 for <play.google.com IN A> on scope dns on */* now complete with <success> from cache (unsigned).
На примере выше при первом запросе идет поиск домена. Домен в кеше не найден (Cache miss
). Далее идет добавление полученной информации в кеш (Added positive unauthenticated cache entry
). Тут же можно увидеть, с какого интерфейса и с какого DNS сервера взята информация о домене. При следующем запросе уже используется информация из кеша (Positive cache hit
).
Кеш будет использоваться, пока не истечет время жизни записи в DNS (TTL).
Looking up RR for play.google.com IN A.
Looking up RR for play.google.com IN AAAA.
Removing cache entry for play.google.com IN A (expired 1s ago)
Cache miss for play.google.com IN A
Transaction 41663 for <play.google.com IN A> scope dns on */*.
Added positive unauthenticated cache entry for play.google.com IN A 268s on eth0/INET/213.133.100.100
Transaction 41663 for <play.google.com IN A> on scope dns on */* now complete with <success> from network (unsigned).
На примере выше при запросе резолвер увидел, что время жизни записи истекло, удалил значение из кеша (Removing cache entry
), запросил свежие данные с DNS сервера и добавил их в кеш.
Статистику по кешу можно посмотреть командой:
systemd-resolve --statistics
Если вдруг Вам нужно сбросить весь кеш резолвера, то это можно сделать командой:
systemd-resolve --flush-caches
Для отключения дебага проще всего воспользоваться следующей командой:
systemctl revert systemd-resolved
Резолвинг прямых DNS запросов
Приложения, которые не используют библиотечные вызовы, а обращаются к DNS серверам напрямую (ping и прочие), не будут использовать systemd-resolved. Они будут брать днс сервера из файла /etc/resolv.conf
.
Можно оставить как есть, но есть еще 2 варианта:
- Создать ссылку на
/run/systemd/resolve/resolv.conf
, который генерируется автоматически при изменении конфига systemd-resolved. В этом случае не нужно будет менять адреса DNS серверов в двух местах. Кеш прямых запросов в этом случае не будет работать. - Направить все прямые DNS запросы на адрес резолвера (
127.0.0.53
). В этом случае будет работать кеш запросов, но нужно будет следить за тем, чтобы сервис systemd-resolved всегда был активен.
1 вариант
Забекапим стандартный resolv.conf
:
mv /etc/resolv.conf /etc/resolv.conf.bkp
И в место него создадим ссылку на /run/systemd/resolve/resolv.conf
:
ln -s /run/systemd/resolve/resolv.conf /etc/
Теперь софт, использующий прямые DNS запросы, будет использовать те DNS сервера, которые указаны в конфиге systemd-resolved.
2 вариант
Перед этим убедитесь, что systemd-resolved запущен и слушает адрес 127.0.0.53
на 53
порту:
netstat -anp | grep 127.0.0.53:53
Забекапим стандартный resolv.conf
:
mv /etc/resolv.conf /etc/resolv.conf.bkp
И создадим новый:
echo 'nameserver 127.0.0.53' > /etc/resolv.conf
В этом случае все DNS запросы будут проходить через резолвер. Но если вдруг systemd-resolved упадет, то резолвинг не будет работать вообще. Поэтому нужно его мониторить на важных серверах.