Установка Bind DNS + DNSSEC на FreeBSD

Есть своя сеть с белыми IP (111.222.333.0) и доменом (mydomain.ru). Требуется поднять DNS который смотрит в интернет.
Загружаем образ FreeBSD 10.0

Устанавливаем, назначаем сетевому интерфейсу адрес 111.222.333.2

Настраиваем синхронизацию времени раз в сутки. добавляем в crontab:

1       6       *       *       *       root    ntpdate -s 0.freebsd.pool.ntp.org

Устанавливаем bind 9.9 из репозитория:

pkg install bind99

Правим конфиг /usr/local/etc/namedb/named.conf
В начале конфига прописываем правила для allow-recursion allow-transfer allow-query

acl "recursion-ip" {
127.0.0.1;
111.222.333.0/24;
};

acl "trusted-dns" {
111.111.111.111;
222.222.222.222;
};

acl "query-ip" {
127.0.0.1;
111.222.333.0/24;
};

В секции options прописываем:

// разрешаем рекурсивные запросы
allow-recursion { recursion-ip; };
// разрешаем передачу зоны доверенным DNS серверам
// (указывает ns сервера регистратора домена)
allow-transfer { trusted-dns; };
// разрешаем подавать запросы нашему серверу
allow-query { query-ip; };
// скрываем версию нашего сервера
version "MyDNS";

Указываем на каких интерфейсах работать.

listen-on       { 127.0.0.1; 111.222.333.2; };

В конце файла прописываем прямую и обратную зону:

zone "mydomain.ru" {
        type master;
        file "/usr/local/etc/namedb/master/mydomain.ru-forward.db";
};
zone "333.222.111.in-addr.arpa" {
        type master;
        file "/usr/local/etc/namedb/master/mydomain.ru-333.222.111-reverse.db";
};

Теперь создаем файлы зон. Прописываем в файл mydomain.ru-forward.db

$TTL    3600
@       IN      SOA     ns1.mydomain.ru.   root.ns1.mydomain.ru.      (
2014040101      ; Serial
3600            ; Refresh
900             ; Retry
360000          ; Expire
3600            ; Neg. cache TTL
)

IN      A               111.222.333.1 ; по этому адресу будет резолвиться наш домен mydomain.ru
IN      NS              ns1.mydomain.ru.
IN      NS              ns1-your_registrator.ru. ; ns  сервера вашего регистратора
IN      NS              ns2-your_registrator.ru.
IN      MX      10      mail.mydomain.ru. ; если есть почта в домене

ns1             IN      A       111.222.333.2 ; IP адрес нашего DNS
first           IN      A       111.222.333.10 ; далее пойдут домены
second          IN      A       111.222.333.11 ; третьего уровня нашей сети

Затем прописываем в файл обратной зоны mydomain.ru-333.222.111-reverse.db следущее:

$TTL    3600
@       IN      SOA     ns1.mydomain.ru.   root.ns1.mydomain.ru.      (
2014032801      ; Serial
3600            ; Refresh
900             ; Retry
360000          ; Expire
3600            ; Neg. cache TTL
)

IN      NS      ns1.mydomain.ru.
IN      NS      ns1-your_registrator.ru.
IN      NS      ns2-your_registrator.ru.

2       IN      PTR     ns1.mydomain.ru.
10      IN      PTR     first.mydomain.ru.
11      IN      PTR     second.mydomain.ru.

Значение Serial (Серийный номер версии файла зоны) нужно увеличивать при каждом изменении в зоне.
По этому значению вторичный сервер обнаруживает, что надо обновить информацию.

Теперь проверим файлы зон:

named-checkzone mydomain.ru mydomain.ru-forward.db
named-checkzone 333.222.111.in-addr.arpa mydomain.ru-333.222.111-reverse.db

Вывод команды должен быть вида:

zone mydomain.ru/IN: loaded serial 2014040101
OK

Настроим логирование.
Прописываем в конфиг bind (/usr/local/etc/namedb/named.conf)

logging {
        channel default_ch {
        file "/var/log/named/named.log" versions 3 size 500k;
        severity info;
        print-time yes;
        print-category yes;
        };
        channel security_ch {
        file "/var/log/named/named-security.log" versions 3 size 500k;
        severity info;
        print-time yes;
        print-category yes;
        };
        channel transfer_ch {
        file "/var/log/named/named-transfer.log" versions 3 size 500k;
        severity info;
        print-time yes;
        print-category yes;
        };
        channel lame_ch {
        file "/var/log/named/named-lamers.log" versions 3 size 500k;
        severity info;
        print-time yes;
        print-category yes;
        };
        category default { default_ch; }; // все, для чего нет собственного канала
        category security { security_ch; }; // события безопасности
        category xfer-in { transfer_ch; }; // отдача зон
        category xfer-out { transfer_ch; }; // прием зон
        category notify { transfer_ch; }; // уведомления и факты регистрации
        category lame-servers { lame_ch; }; // события от "кривых" DNS-серверов
};

Выставим владельца на директорию /var/log/named

chown bind:bind /var/log/named

Проверяем правильность конфига named.conf командой

named-checkconf

Если результатом выполнения этой команды «ничего» то все ОК.
Теперь загрузим актуальный файл корневой зоны (named.root).

fetch ftp://ftp.internic.net/domain/named.root

Поместим его в каталог /usr/local/etc/namedb с заменой существующего.
Желательно периодически повторять эту процедуру, или настроить эту операцию посредством cron.
Все почти готово! Настроим утилиту управления — rndc
Переходим в каталог /usr/local/etc/namedb
Удаляем файл rndc.conf
Выполняем:

rndc-confgen -a

Меняем владельца:

chown bind:bind rndc.key

Задействуем автостарт сервера имен.
В файл /etc/rc.conf пропишем:

named_enable="YES"
# если нужен только IPv4, то
named_flags="-4"

Настроим DNSSEC.
Создадим каталог keys для файлов ключей.
Создадим мастер ключ — Key Signing Key (KSK) и ключ для зоны — Zone Signing Key (ZSK).

Команда создания KSK ключа:

dnssec-keygen -f KSK -a RSASHA256 -b 2048 -n ZONE mydomain.ru

Команда для создания ZSK ключа:

dnssec-keygen -a RSASHA256 -b 2048 -n ZONE mydomain.ru

удостоверьтесь что ваш регистратор  домена поддерживает алгоритм RSASHA256

выставляем права на файлы ключей:

chown bind:bind Kmydomain.ru*

Включим логирование. В конфиг /usr/local/etc/namedb/named.conf в секцию logging добавим:

channel dnssec_ch {
        file "/var/log/named/named-dnssec.log" versions 3 size 500k;
        severity info;
        print-time yes;
        print-category yes;
};
category dnssec { dnssec_ch; };

и добавим в описание зоны:

key-directory "/usr/local/etc/namedb/keys";
inline-signing yes;
auto-dnssec maintain;

теперь зона mydomain.ru выглядит так:

zone "mydomain.ru" {
        type master;
        file "/usr/local/etc/namedb/master/mydomain.ru-forward.db";
        key-directory "/usr/local/etc/namedb/keys";
        inline-signing yes;
        auto-dnssec maintain;
};

ДОБАВЛЕНО: В новых версиях bind выводит предупреждение:

named.conf: option 'auto-dnssec' is deprecated
named.conf: 'auto-dnssec' option is deprecated and will be removed in BIND 9.19. Please migrate to dnssec-policy

Для перехода на dnssec-policy добавте в named.conf:

dnssec-policy "myident" {
    keys {
       ksk lifetime unlimited algorithm RSASHA256 2048;
       zsk lifetime unlimited algorithm RSASHA256 2048;
    };
};

А в зоне поменяйте

auto-dnssec maintain;

на

dnssec-policy myident;

Для поддержки проверки DNSSEC на стороне резолвера добавте в секцию options:

dnssec-enable yes;
dnssec-validation yes;

После растарта демона в каталоге зон появятся файлы с расширением: .jbk, .jnl и .signed

Если вы используете DNSSEC Look-aside Validation (опцию dnssec-lookaside auto;), то можете наблюдать в логе множественные сообщения вида: got insecure response; parent indicates it should be secure. Чтобы предотвратить это установите значение dnssec-validation auto; и используйте в качестве forwarders серверов DNS с поддержкой DNSSEC, например от Google — 8.8.8.8

Чтобы заработал процесс верификации регистратору вашего домена нужно заверить созданный KSK ключ и подтвердить свое доверие.
для этого нужно прописать DS записи в панели управления доменом.
DS записи создаются на основе KSK ключа командой:

dnssec-dsfromkey имя_файла_KSK_ключа

записи выданные этой командой прописываем в панели управления регистратора домена.

mydomain.ru. IN DS 54808 5 1 0FC489EFD28C2...28EA985CAFBBC1
mydomain.ru. IN DS 54808 5 2 03B685D8003834B492F6...B134ABF9D41A28193171352F0280

У некоторых регистраторах также требуется прописать DSKEY из файла KSK ключа.

mydomain.ru. IN DNSKEY 257 3 5 YthgRbNKP5P8e5cDJhYsCwFr7AK17m+SeV5pgW...bLVa2A0/dWXkPwi1TZ3lNfkjhhYFGR

И в заключении настроим файервол.
Создадим файл /etc/ipfw.my_rules следующего содержания:

#!/bin/sh

cmd="/sbin/ipfw -q add"        # команда добавления правил
oint="vmx0"                    # интерфейс на котором запушен named
ipo="111.222.333.2"            # IP адрес этого интерфейса

# Сбрасываем все правила:
/sbin/ipfw -f flush

# Проверяем на соответствие пакета динамическим правилам:
${cmd} check-state
# Разрешаем весь траффик по внутреннему интерфейсу lo0
${cmd} allow ip from any to any via lo0
# отсекаем попытки лезть от lo0 и к нему
${cmd} deny ip from any to 127.0.0.0/8
${cmd} deny ip from 127.0.0.0/8 to any
# блокируем частные сети и автоконфигурационную т.к. интерфейс смотрит в интернет.
${cmd} deny ip from any to 10.0.0.0/8 in via ${oint}
${cmd} deny ip from any to 172.16.0.0/12 in via ${oint}
${cmd} deny ip from any to 192.168.0.0/16 in via ${oint}
${cmd} deny ip from any to 0.0.0.0/8 in via ${oint}
${cmd} deny ip from any to 169.254.0.0/16 in via ${oint}
# блокируем мультикастовые пакеты
${cmd} deny ip from any to 240.0.0.0/4 in via ${oint}
# блокируем широковещательный и фрагментированный icmp
${cmd} deny icmp from any to any frag
${cmd} deny log icmp from any to 255.255.255.255 in via ${oint}
${cmd} deny log icmp from any to 255.255.255.255 out via ${oint}
# траффик к частным сетям
${cmd} deny ip from 10.0.0.0/8 to any out via ${oint}
${cmd} deny ip from 172.16.0.0/12 to any out via ${oint}
${cmd} deny ip from 192.168.0.0/16 to any out via ${oint}
${cmd} deny ip from 0.0.0.0/8 to any out via ${oint}
# автоконфигуреную частную сеть
${cmd} deny ip from 169.254.0.0/16 to any out via ${oint}
# мультикастовые рассылки
${cmd} deny ip from 224.0.0.0/4 to any out via ${oint}
${cmd} deny ip from 240.0.0.0/4 to any out via ${oint}
# разрешаем установленные соединения
${cmd} allow tcp from any to any established
# разрешаем исходящий траффик от сервера
${cmd} allow ip from ${ipo} to any out xmit ${oint}
# разрешаем синхронизацию времени через ntpdate
${cmd} allow udp from any 123 to any via ${oint}
# разрешаем DNS
${cmd} allow udp from any 53 to any via ${oint}
# разрешаем входящий DNS (протокол tcp нужен для трансфера зон)
${cmd} allow udp from any to any 53 via ${oint}
${cmd} allow tcp from any to any 53 via ${oint}
# разрешаем ICMP - эхо-запрос, эхо-ответ, время жизни пакета истекло
${cmd} allow icmp from any to any icmptypes 0,8,11
# разрешаем 22 порт для определенного адреса и пишем в лог попытки соединиться с отличных адресов
${cmd} allow tcp from 111.222.333.3 to ${ipo} 22 via ${oint}
${cmd} deny log tcp from any to me 22 in via ${oint}

Для автостарта фаервола пропишем в файл /etc/rc.conf строки:

firewall_enable="YES"
firewall_script="/etc/ipfw.my_rules"
firewall_logging="YES"

Логи будут писаться в файл /var/log/security

На этом все!

1 Comment on "Установка Bind DNS + DNSSEC на FreeBSD"

  1. Спасибо! Неплохая статья. Помогла в некоторых моментах.
    Есть замечания по фаейрволу…
    /*
    # блокируем частные сети и автоконфигурационную т.к. интерфейс смотрит в интернет.
    ${cmd} deny ip from any to 10.0.0.0/8 in via ${oint}
    ${cmd} deny ip from any to 172.16.0.0/12 in via ${oint}
    ${cmd} deny ip from any to 192.168.0.0/16 in via ${oint}
    ${cmd} deny ip from any to 0.0.0.0/8 in via ${oint}
    ${cmd} deny ip from any to 169.254.0.0/16 in via ${oint}
    */
    Если последней строчкой прописать:
    ${cmd} deny log all from any to any in
    то не придётся явно запрещать входящий трафик.
    Какая политика у ipfw?
    Так как:
    # разрешаем исходящий траффик от сервера
    ${cmd} allow ip from ${ipo} to any out xmit ${oint}
    то есть смысл, явно запретить хождение самого сервака на «серость».
    Такое ощущение, что это чаcть ipfw с маршрутизатора 😉

Leave a comment

Your email address will not be published.