MAATRIX / Блог / Как установить и настроить BIND9 на VPS

Как установить и настроить BIND9 на VPS

MAATRIX

Если вы администрируете больше одного-двух доменов или устали от того, что регистратор медленно применяет изменения записей, рано или поздно встаёт вопрос о собственном DNS-сервере. BIND9 — самый проверенный вариант: он стоит в интернете с 1980-х, задаёт стандарты протокола и есть в репозиториях любого дистрибутива. Дальше — реальная установка на VPS, обе рабочие роли (авторитетный сервер и кэширующий резолвер) и настройки, без которых открытый DNS превращается в инструмент DDoS-атак на чужие сети.

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

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

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

Когда нужен свой BIND9: авторитетный сервер vs кэширующий резолвер

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

Авторитетный сервер (authoritative) хранит зональные файлы ваших доменов и отвечает на вопросы «какой IP у example.com» напрямую, без похода в интернет. Это то, что вы прописываете в NS-записях у регистратора. Нужен, если:

  • вы держите десятки доменов и хотите быстро менять записи без панели регистратора;
  • нужен собственный geo-DNS или сложная логика ответов (подробнее об этом — в статье про гео-DNS);
  • важна независимость от чужого DNS-хостинга при миграции или смене площадки — тема разобрана в материале о проблемах с DNS после переезда.

Кэширующий рекурсивный резолвер (recursive/caching) ничего не хранит — он ходит в интернет по цепочке от корневых серверов и кэширует ответы для ваших клиентов. Это то, что обычно прописывают в /etc/resolv.conf на серверах внутри вашей инфраструктуры, чтобы не дёргать 8.8.8.8 при каждом запросе.

Важно: никогда не совмещайте обе роли на сервере, который смотрит в открытый интернет без ограничений. Открытый рекурсивный резолвер (open resolver) — это классический вектор DNS-амплификации: злоумышленник подделывает адрес источника и заставляет ваш сервер заваливать жертву многократно увеличенным трафиком. Ниже разберём, как этого избежать через ACL.

Установка BIND9 на VPS

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

Ubuntu 24.04 / Debian 12:

sudo apt update
sudo apt install bind9 bind9utils bind9-doc dnsutils -y
systemctl status named

На Debian/Ubuntu служба обычно называется named, но иногда завязана на bind9.service — проверьте оба варианта:

systemctl status bind9 2>/dev/null || systemctl status named

AlmaLinux 9 / RHEL-семейство:

sudo dnf install bind bind-utils -y
sudo systemctl enable --now named

Если вы разворачиваете сервер с нуля и ещё не настраивали файрвол — сделайте это в первую очередь, до открытия 53-го порта наружу. Базовые шаги описаны в статье про установку UFW.

Проверьте версию и убедитесь, что демон стартовал без ошибок:

named -v
sudo journalctl -u named -n 30 --no-pager

Основные пути конфигурации на Debian/Ubuntu:

ФайлНазначение
/etc/bind/named.confглавный конфиг, подключает остальные
/etc/bind/named.conf.optionsглобальные опции (forwarders, listen-on, ACL)
/etc/bind/named.conf.localописание ваших зон
/var/cache/bind/зональные файлы и кэш

На AlmaLinux/RHEL всё аналогично, но лежит в /etc/named.conf и /var/named/.

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

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

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

Авторитетная зона: настройка своего домена с нуля

Допустим, вы хотите, чтобы BIND9 сам отвечал за зону example.com (замените на свой домен и IP сервера — 203.0.113.10).

Опишите зону в /etc/bind/named.conf.local:

zone "example.com" {
    type master;
    file "/var/cache/bind/db.example.com";
    allow-transfer { none; };
    also-notify { };
};

allow-transfer { none; } запрещает зональный трансфер всем — это критично, иначе любой сможет скачать полный список ваших поддоменов через dig axfr.

Создайте зональный файл:

sudo cp /etc/bind/db.empty /var/cache/bind/db.example.com
sudo nano /var/cache/bind/db.example.com

Пример содержимого:

$TTL    3600
@       IN      SOA     ns1.example.com. admin.example.com. (
                          2026090101 ; Serial (год-месяц-день-номер)
                          3600       ; Refresh
                          900        ; Retry
                          604800     ; Expire
                          3600 )     ; Negative TTL

        IN      NS      ns1.example.com.
        IN      NS      ns2.example.com.

ns1     IN      A       203.0.113.10
ns2     IN      A       203.0.113.11
@       IN      A       203.0.113.10
www     IN      A       203.0.113.10
mail    IN      A       203.0.113.10
        IN      MX  10  mail.example.com.

Serial обязательно увеличивайте при каждом изменении — иначе вторичные серверы не подтянут обновление. Формат ГГГГММДДNN — привычная практика.

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

sudo named-checkconf
sudo named-checkzone example.com /var/cache/bind/db.example.com
sudo systemctl reload named

Пропишите у регистратора NS-записи (ns1.example.com, ns2.example.com с соответствующими glue-записями) — без второго физического сервера в другой сети зона формально валидна, но нарушает рекомендацию иметь как минимум два независимых авторитетных сервера. Для полноценной отказоустойчивости имеет смысл держать вторичный (type slave) BIND9 на другом VPS, желательно в другой локации.

Кэширующий рекурсивный резолвер: настройка и защита от open resolver

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

В /etc/bind/named.conf.options задайте ACL и forwarders:

acl trusted {
    127.0.0.1;
    ::1;
    10.0.0.0/8;        // ваша приватная сеть/VPC
};

options {
    directory "/var/cache/bind";

    recursion yes;
    allow-recursion { trusted; };
    allow-query { trusted; };
    allow-query-cache { trusted; };

    listen-on { 127.0.0.1; 10.0.0.5; };   // не слушайте 0.0.0.0 без нужды
    listen-on-v6 { none; };

    forwarders {
        1.1.1.1;
        9.9.9.9;
    };
    forward first;

    dnssec-validation auto;
};

Ключевой момент: allow-recursion и allow-query-cache должны ограничивать список ровно тем, кому резолвер реально нужен. Проверить, что сервер не отвечает произвольным адресам из интернета, можно с внешней машины:

dig @ваш_ip google.com +short

Если сервер настроен правильно (порт закрыт файрволом или ACL не пускает чужих), ответа не будет — таймаут. Это нормально и ожидаемо.

Если резолвер должен обслуживать несколько VPS в разных подсетях одного проекта, добавьте их диапазоны в acl trusted, а на уровне файрвола держите 53/udp и 53/tcp закрытыми для всех, кроме этих подсетей — двойная защита переживёт опечатку в конфиге BIND.

Безопасность и harden: ACL, rate-limit, systemd sandboxing

DNS-сервер на белом IP — цель по умолчанию. Вот минимальный набор мер, которые стоит применить в любом случае, независимо от роли.

1. Запуск от непривилегированного пользователя. Пакетная установка на Ubuntu/Debian уже настраивает запуск от bind, проверить можно:

ps aux | grep named

2. Скрыть версию BIND — иначе она видна любому через dig @ip version.bind chaos txt, что упрощает подбор эксплойта под конкретный релиз:

options {
    version "not disclosed";
};

3. rate-limit — защита от использования вашего сервера в DNS-амплификации. Актуально даже для авторитетного сервера, который обязан отвечать всем:

options {
    rate-limit {
        responses-per-second 10;
        window 5;
        log-only no;
    };
};

Параметр responses-per-second подбирайте под легитимную нагрузку — если у вас высоконагруженная зона с тысячами уникальных клиентов, значение придётся поднять; ориентируйтесь по логам, а не берите цифру наугад.

4. TSIG-ключи для зонального трансфера, если вторичный сервер всё же нужен:

tsig-keygen -a hmac-sha256 transfer-key

Полученный ключ добавьте в named.conf на обоих серверах и используйте вместо allow-transfer { none; } направленный allow-transfer { key transfer-key; };.

5. systemd-хардеинг. Современные unit-файлы BIND9 на Ubuntu уже включают часть ограничений (ProtectSystem, NoNewPrivileges). Проверить и дополнить:

sudo systemctl edit named
[Service]
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/cache/bind

6. Файрвол. Откройте 53/udp и 53/tcp только там, где это реально нужно — для авторитетного сервера всему интернету, для резолвера только доверенным сетям. Пример через UFW:

sudo ufw allow from 10.0.0.0/8 to any port 53 proto udp
sudo ufw allow 53/tcp    # только если авторитетный сервер отдаёт зоны наружу

Для защиты SSH-порта на том же сервере пригодится fail2ban — его же можно натравить на логи BIND, если увидите повторяющиеся попытки зонального трансфера с одного адреса.

DNSSEC и диагностика

DNSSEC подписывает зону криптографически, чтобы резолверы могли убедиться — ответ не подделан по пути (защита от cache poisoning).

Включение валидации на стороне резолвера — одна строка, уже указанная выше: dnssec-validation auto;.

Подписание собственной авторитетной зоны сложнее и делается через dnssec-policy (BIND 9.16+, есть в Ubuntu 24.04):

dnssec-policy "default-policy" {
    keys {
        ksk lifetime unlimited algorithm ecdsap256sha256;
        zsk lifetime P30D algorithm ecdsap256sha256;
    };
};

zone "example.com" {
    type master;
    file "/var/cache/bind/db.example.com";
    dnssec-policy "default-policy";
    inline-signing yes;
};

После rndc reload BIND сам сгенерирует ключи и подпишет зону. DS-запись для регистратора получите так:

sudo rndc signing -list example.com
cat /var/cache/bind/dsset-example.com.

Эту DS-запись нужно вручную добавить в панели регистратора, в раздел DNSSEC — без этого шага подпись зоны существует, но цепочка доверия не замыкается и валидации не происходит.

Базовая диагностика на каждый день:

sudo named-checkconf                          # синтаксис конфига
sudo named-checkzone example.com /path/to/zone # синтаксис зоны
sudo rndc reload                              # применить изменения без рестарта
sudo rndc flush                               # сбросить кэш резолвера
dig @127.0.0.1 example.com                    # проверить ответ локально
dig +trace example.com                        # пройти всю цепочку от корня

Логи по умолчанию идут в syslog/journal; для отдельного файла добавьте в конфиг канал logging { channel ... } с ротацией через logrotate, иначе на активном резолвере лог-файл может неожиданно вырасти за пару недель.

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

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

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

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

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

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

BIND9 или dnsmasq/Unbound — что выбрать для VPS?

Если нужен полноценный авторитетный сервер с DNSSEC и сложными зонами — BIND9. Если нужен только компактный кэширующий резолвер без своих доменов — Unbound легче настраивается и потребляет меньше памяти. Dnsmasq хорош для локальных сетей и совмещения с DHCP, но для продакшен-DNS в интернете обычно не выбирают.

Сколько памяти нужно BIND9 на VPS?

Для одного-двух десятков зон без большого кэша хватает 512 МБ–1 ГБ. Кэширующему резолверу под нагрузкой стоит закладывать 2 ГБ и выше — размер кэша растёт с количеством уникальных запросов.

Как перенести существующие зоны с другого DNS-хостинга?

Экспортируйте зону в формате BIND (dig axfr с разрешения текущего провайдера или ручной экспорт через панель), проверьте named-checkzone, разместите файл и не забудьте увеличить Serial перед первым rndc reload.

Почему мои изменения в зоне не подхватываются?

Чаще всего забыт rndc reload после правки файла, либо не увеличен Serial — вторичные серверы и кэши считают, что зона не менялась.

Обязательно ли DNSSEC?

Нет, но для доменов с почтой (DKIM/SPF цепочки, защита от спуфинга) и любых зон, где важна целостность ответа, включение оправдано — процедура разовая, а риск подмены DNS-ответа при MITM снижается заметно.

Как проверить, что мой резолвер не открыт наружу как open resolver?

Запустите dig @ваш_ip.открытый CH TXT version.bind или воспользуйтесь публичными сканерами открытых резолверов — если ответ приходит от произвольного внешнего IP без ACL, немедленно закрывайте allow-recursion и порт файрволом.

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

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

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