|
www.lissyara.su
—> статьи
—> FreeBSD
—> программы
—> DNS сервер Unbound
Установка и настройка DNS сервера Unbound
Автор: terminus.
Версия статьи 2.2.1
В предыдущей заметке мною был описан процесс установки авторитарного DNS сервера NSD. В этой статье хочу описать установку и настройку кеширующего DNS сервера Unbound. Установка проводилась на FreeBSD 7.0. Мотив написания обоих заметок — это попытка отказаться от необходимости использования гламурного BIND, и поиск новых решений на смену устаревающих.
В случае с обслуживанием рекурсивных клиентских запросов в качестве альтернативы BIND'у можно рассматривать тот же самый djbdns (dnscache) со всеми его традиционными плюсами и минусами. Но, как ни крути — это и есть то самое устаревающее решение. Поэтому захотел расширить свои знания освоив Unbound.
Unbound это кеширующий DNS сервер который обслуживает исключительно рекурсивные запросы. Во время работы сервера кеш целиком распологается в памяти, а его размер ограничен указанным объемом. Unbound поддерживает расширения DNSSEC и может работать как "validator" (в конце статьи будет пример настройки Unbound в роли "validator iterator" для тех кто захочит задействовать функциональность проверки DNSSEC сигнатур). В качестве плюсов Unbound по сравнению с BIND надо отметить все те же скромные размеры и скорость. На официальном сайте проекта приведена следующая сравнительная информация по скорости работы популярных DNS серверов:
Server Queries/sec (10 clients)
Unbound 8 276
MaraDNS 3 068
BIND 3 003
dnscache 2 928
PowerDNS Recursor 2 074
| Результаты были получены для версии Unbound 1.0. Как видно, имеет место почти трехкратное превосходство над BIND - за те же деньги и на том же железе можно прокачать через себя в три раза больше клиентских запросов!
Детальный список фич и возможностей unbound после установки можно будет прочитать в файле /usr/local/share/doc/unbound/FEATURES.
Установка
Описание установки и настройки приводится для версии unbound 1.2.0. На всякий случай упомяну процедуру обновления портов перед установкой. Для FreeBSD начиная с 6.2, это удобно делать через portsnap:
# portsnap fetch
# portsnap extract
| После обновления портов, ставим Unbound традиционным методом:
# cd /usr/ports/dns/unbound
# make install clean
| При первой установке, порт предлагал выбрать такие опции конфигурации:
Options for unbound-1.2.0
[ ] LIBEVENT is useful when using many (10000) outgoing ports
[X] THREADS build with threads support
| Необходимо детально описать о чем идет речь.
При проведении разрешения имен которых еще нет в кеше сервера, а значит при необходимости обращаться к внешним авторитарным DNS серверам, Unbound отсылает исходящие запросы используя множество UDP портов из разрешенного диапазона. Это сделано для обеспечения дополнительной безопасности чтобы было труднее угадать с какого порта был отправлен запрос и затруднить возможность атак с целью отравления записей в кеше. Позже, в примере файла конфигурации это будет отражено - опция outgoing-range: 512 указывает, сколько UDP портов для этой цели разрешено использовать одному потоку (thread) сервера.
Каждый открытый сервером UDP или TCP порт, потребляет один файловый дескриптор. Серверу Unbound необходимо иметь возможность работать со всеми открытыми дескрипторами. Сам Unbound содержит в себе некий builtinmini-event обработчик, который и используется для этого. Встроенный обработчик способен обслуживать максимум 1024 открытых файловый дескрипторов на один процесс сервера.
Предлагаемая по умолчанию опция конфигурации THREADS указывает, что необходимо скомпилировать Unbound с поддержкой потоков. При этой конфигурации запускается один материнский процесс у которого рождаются подпроцессы-потомки. Плюс данной конфигурации в том, что все дочерние потоки имеют возможность использовать общий кеш материнского процесса - снижаются требования к памяти выделяемой серверу Unbound.
Если же отказаться от опции THREADS, то сервер будет собран без потоков (фактически с одним потоком на процесс) и будет происходить форканье процессов, что есть практически параллельный запуск нового сервера со своим собственным кешем. Минус такого подхода - это увеличение требований к памяти. Плюс этого метода работы - увеличение скорости на 10-20 %.
Таким образом, если наш сервер будет собран с поддержкой потоков THREADS, и мы захотим использовать восемь потоков (опция конфигурации num-threads: 8), то при установленных outgoing-range: 512, в сумме это даст 512*8=4096 одновременно открытых файловых дескрипторов, что превышает возможности встроенного обработчика. Unbound не захочет стартовать и выведет сообщение об ошибке. Проблема. (Кривое решение проблемы - это снизить значение outgoing-range, но делать этого не стоит так как это уменьшает секюрность). Для правильного решения этой проблемы, разработчики Unbound предлагают использовать специальные сторонние обработчики, такие как например libevent или libev. Выбор опции LIBEVENT приведет к установке дополнительного порта libevent 1.4.8 и линковке с ним Unbound.
Если же мы откажемся от использования потоков и соберем Unbound без THREADS, и без ненужного теперь LIBEVENT, то при использовании той же опции конфигурации num-threads: 8, мы получим восемь процессов Unbound каждый из которых будет иметь свой кеш и использовать только 512 файловых дескрипторов управляемых встроенным обработчиком.
До выхода unbound 1.2.0 в нем сушествовала неприятная ошибка - при одновременном использовании модели на основе потоков и обработчика libevent между потоками сервера могло возникнуть состояние гонки (race condition). Это приводило к нестабильной работе и даже падениям сервера. К счатью эту ошибку нашли и исправили, и теперь ничто не мешает использовать все преимущества связки unbound+libevent.
Таким образом, возврашаясь к выбору опций предлагаемых портом - оптимальным является вариант использования потоков в связке с libevent. Это позволит без проблем масштабировать производительность сервера и экономить выделенные ресурсы оперативной памяти.
Выбираем опции:
Options for unbound-1.2.0
[X] LIBEVENT is useful when using many (10000) outgoing ports
[X] THREADS build with threads support
| На машине Pentium4 2,53GHz сборка порта заняла три-четыре минуты.
Файлы установленные портом:
/usr/local/man/man1/unbound-host.1.gz
/usr/local/man/man3/libunbound.3.gz
/usr/local/man/man5/unbound.conf.5.gz
/usr/local/man/man8/unbound.8.gz
/usr/local/man/man8/unbound-control.8.gz
/usr/local/man/man8/unbound-checkconf.8.gz
/usr/local/etc/unbound/unbound.conf.sample
/usr/local/include/unbound.h
/usr/local/lib/libunbound.so.0
/usr/local/lib/libunbound.so
/usr/local/lib/libunbound.la
/usr/local/lib/libunbound.a
/usr/local/sbin/unbound
/usr/local/sbin/unbound-checkconf
/usr/local/sbin/unbound-control
/usr/local/sbin/unbound-control-setup
/usr/local/sbin/unbound-host
/usr/local/share/doc/unbound/CREDITS
/usr/local/share/doc/unbound/Changelog
/usr/local/share/doc/unbound/FEATURES
/usr/local/share/doc/unbound/LICENSE
/usr/local/share/doc/unbound/README
/usr/local/share/doc/unbound/README.svn
/usr/local/share/doc/unbound/README.tests
/usr/local/share/doc/unbound/TODO
/usr/local/share/doc/unbound/control_proto_spec.txt
/usr/local/share/doc/unbound/ietf67-design-02.odp
/usr/local/share/doc/unbound/ietf67-design-02.pdf
/usr/local/share/doc/unbound/requirements.txt
/usr/local/etc/rc.d/unbound
| Кроме того в систему была добавлена библиотека libevent-1.4.8
Управление запуском, перезапуском и остановкой будет вестись через стандартный rc.d скрипт установленный вместе с портом. Для проверки правильности синтаксиса unbound.conf удобно применять unbound-checkconf. Кроме того, начиная с версии 1.1.0 в состав unbound вошел дополнительный инструмент unbound-control для удаленного управления сервером и снятия статистики.
В процессе установки порта, в систему автоматически добавляется новый пользователь из-под которого будет запускаться демон unbound:
unbound:*:59:1:unbound dns resolver:/nonexistent:/usr/sbin/nologin
| Настройка
Традиционно подразумевается необходимость внимательного прочтения man unbound.conf и осознания прочитанного в свете личных требований. Опций много. Я выбирал и помещал в свой конфиг только те которые считал нужными себе, и оставлял с настройками по умолчанию остальные. В комментариях придется описать некоторые наиболее интересные.
Unbound позволяет запускать себя в chroot окружении. Я решил использовать эту возможность чтобы не замарачиваться с настройкой jail.
Для обеспечения полноценной работы в chroot, придется сделать один дополнительный маневр. Дело в том, что unbound необходим доступ к /dev/random. Я посчитал, что правильным решением будет ограниченное монтирование devfs в подкаталог ./dev в каталоге unbound.
В директории /usr/local/etc/unbound создаем новую поддиректорию ./dev:
drwxr-xr-x 3 unbound wheel 512 5 июл 17:54 .
drwxr-xr-x 37 root wheel 1536 3 июл 20:53 ..
dr-xr-xr-x 4 root wheel 512 5 июл 20:00 dev
| В файле /etc/devfs.rules прописываем новый devfs releset:
[unbound_ruleset=20]
add hide
add path null unhide
add path zero unhide
add path crypto unhide
add path random unhide
add path urandom unhide
| В файле /etc/fstab прописываем монтирование devfs:
devfs /usr/local/etc/unbound/dev devfs rw 0 0
| В файле /etc/rc.conf прописываем применение созданного devfs releset к точке монтирования:
devfs_set_rulesets="/usr/local/etc/unbound/dev=unbound_ruleset"
| В результате всех этих танцев с бубном, после каждой перезагрузки в подкаталоге ./dev будет:
[root@dns /usr/local/etc/unbound/dev]# ls -la
total 0
crw-rw-rw- 1 root wheel 0, 13 5 июл 20:22 null
crw-rw-rw- 1 root wheel 0, 19 5 июл 20:00 random
lrwxr-xr-x 1 root wheel 6 5 июл 17:00 urandom -> random
crw-rw-rw- 1 root wheel 0, 14 5 июл 17:00 zero
| Если не проблема перезапустить сервер то перезагружаем FreeBSD и проверяем, что devfs красиво подмонтировалась в /usr/local/etc/unbound/dev со всеми ограничениями как положено.
Если же не хочеться перезапускать машину, то монтирование можно выполнить и на ходу:
# mount /usr/local/etc/unbound/dev
# /etc/rc.d/devfs restart
| Далее продолжаем настройку unbound:
Переходим в /usr/local/etc/unbound и скачиваем туда свежий hint-файл named.cache с информацией об адресах корневых серверов:
# cd /usr/local/etc/unbound
# fetch ftp://FTP.INTERNIC.NET/domain/named.cache
| Генерируем связку ключей необходимых для работы unbound-control:
# unbound-control-setup
setup in directory /usr/local/etc/unbound
generating unbound_server.key
Generating RSA private key, 1024 bit long modulus
..++++++
...............................................++++++
e is 65537 (0x10001)
generating unbound_control.key
Generating RSA private key, 1024 bit long modulus
...................++++++
..................++++++
e is 65537 (0x10001)
create unbound_server.pem (self signed certificate)
create unbound_control.pem (signed client certificate)
Signature ok
subject=/CN=unbound-control
Getting CA Private Key
Setup success. Certificates created. Enable in unbound.conf file to use
| Корректируем права доступа для созданных ключей (это важно!):
# chown unbound:wheel ./unbound_*
# chmod 440 ./unbound_*
| Дело в том, что сразу же после генерации ключей права доступа для них по умолчанию выставляются так, что любой локальный пользователь может их прочитать. Это плохо так как локальный контроль доступа у утилиты unbound-control происходит только на основе разрешений файловой системы для этих ключей. Разработчики unbound предлагают при генерации использовать sudo или su и генерировать ключи работая из-под пользователя unbound, но мне такой метод кажется все равно геморойным. Таким образом после выполнения данных шагов локальный доступ к unbound-control будет только у root и пользователей из группы wheel.
Если хотите производить мониторинг работы сервера с помошью cacti, то сразу сейчас надо будет создать еще одну директорию в которой будет хранится статистика. В конце статьи есть ссылочка на архив со скриптом и шаблонами для cacti.
На работающем сервере каталог /usr/local/etc/unbound будет выглядеть так:
[root@dns /usr/local/etc/unbound]# ls -la
total 21
drwxr-xr-x 3 unbound wheel 512 24 янв 15:24 .
drwxr-xr-x 34 root wheel 1536 21 янв 18:55 ..
dr-xr-xr-x 4 root wheel 512 24 янв 14:30 dev
-rw-r--r-- 1 root wheel 2879 4 фев 2008 named.cache
drwxr-xr-x 2 root wheel 512 29 янв 21:15 statistics
-rw-r--r-- 1 root wheel 1848 14 янв 20:39 unbound.conf
-rw-r--r-- 1 unbound daemon 5 24 янв 12:30 unbound.pid
-r--r----- 1 unbound wheel 887 24 янв 15:17 unbound_control.key
-r--r----- 1 unbound wheel 627 24 янв 15:17 unbound_control.pem
-r--r----- 1 unbound wheel 887 24 янв 15:17 unbound_server.key
-r--r----- 1 unbound wheel 619 24 янв 15:17 unbound_server.pem
| При работающем скрипте unbound_cacti каталог /usr/local/etc/unbound/statistics будет выглядеть так:
[root@dns /usr/local/etc/unbound/statistics]# ls -la
total 12
drwxr-xr-x 2 root wheel 512 29 янв 21:15 .
drwxr-xr-x 4 unbound wheel 512 1 фев 13:21 ..
-rw-r--r-- 1 root wheel 107 8 фев 00:40 answers_to_queries
-rw-r--r-- 1 root wheel 257 8 фев 00:40 cache_hits
-rw-r--r-- 1 root wheel 88 8 фев 00:40 histogram
-rw-r--r-- 1 root wheel 106 8 фев 00:40 memory_usage
-rw-r--r-- 1 root wheel 130 8 фев 00:40 queues_by_flags
-rw-r--r-- 1 root wheel 141 8 фев 00:40 queues_by_type
| Конфиг unbound.conf:
server:
verbosity: 0
#statistics-interval: 300
num-threads: 4
interface: 0.0.0.0
port: 53
outgoing-range: 512
num-queries-per-thread: 1024
msg-cache-size: 16m
rrset-cache-size: 32m
#key-cache-size: 10m
msg-cache-slabs: 4
rrset-cache-slabs: 4
infra-cache-slabs: 4
#key-cache-slabs: 4
cache-max-ttl: 86400
infra-host-ttl: 60
infra-lame-ttl: 120
infra-cache-numhosts: 10000
infra-cache-lame-size: 10k
do-ip4: yes
do-ip6: no
do-udp: yes
do-tcp: yes
do-daemonize: yes
access-control: 0.0.0.0/0 refuse
access-control: 192.168.1.0/24 allow
access-control: 127.0.0.0/8 allow
access-control: ::0/0 refuse
access-control: ::1 allow
access-control: ::ffff:127.0.0.1 allow
chroot: "/usr/local/etc/unbound"
username: "unbound"
directory: "/usr/local/etc/unbound"
#logfile: "/usr/local/etc/unbound/unbound.log"
logfile: ""
use-syslog: no
pidfile: "/usr/local/etc/unbound/unbound.pid"
root-hints: "/usr/local/etc/unbound/named.cache"
identity: "DNS"
version: "1.0"
hide-identity: yes
hide-version: yes
harden-glue: yes
do-not-query-address: 127.0.0.1/8
do-not-query-address: ::1
do-not-query-localhost: yes
module-config: "iterator"
#extended-statistics: yes
#local-zone: "mail.ru." transparent
# local-data: "www.mail.ru. 300 IN A 10.10.10.10"
# local-data: "ftp.mail.ru. 300 IN A 172.16.1.2"
#stub-zone:
# name: "times.lv."
# stub-addr: 193.108.185.34
#forward-zone:
# name: "."
# forward-addr: 195.122.12.242
remote-control:
control-enable: yes
control-interface: 127.0.0.1
control-port: 953
server-key-file: "/usr/local/etc/unbound/unbound_server.key"
server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
control-key-file: "/usr/local/etc/unbound/unbound_control.key"
control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
| Замечание 1
В процессе обсуждения статьи, выявилось несколько важных моментов конфигурации, на которые необходимо обратить внимание. Для пользователей FreeBSD 7 это может быть не актуально, но если у вас FreeBSD 6 или другая система то стоит проверить все ли ОК.
Первое, что надо учитывать в конфигурациях расчитанных на большие нагрузки - максимальное количество файловых дескрипторов которые разрешено открыть процессу (ulimit -n) и общее количество сокетов. Во FreeBSD эти значения можно узнать через
# sysctl -a | grep kern.maxfiles
# sysctl -a | grep kern.ipc.maxsockets
|
Регулируется они через установки sysctl. На моей машине с FreeBSD 7 по умолчанию эти значения были такие:
kern.maxfiles: 12328
kern.maxfilesperproc: 11095
kern.ipc.maxsockets: 12328
| Указаная выше конфигурация unbound.conf приведет к появлению четырех потоков у процесса unbound. Каждый из четырех потоков сможет открыть 512 дескрипторов для UDP (по числу outgoing-range: ), кроме того каждый поток открывает 10 дискрипторов для обслуживания входящих и 10 дискрипторов для обслуживания исходящих TCP соединений (эти значения регулируются через опции outgoing-num-tcp: и incoming-num-tcp: которые по умолчанию выставлены в 10).
В сумме получается 512*4 + 20*4 = 2128 а значит на FreeBSD 7 проблем это вызвать не должно... Если же окажеться, что необходимо увеличить лимиты, то сделать это можно так:
Выставляем на ходу
# sysctl kern.maxfiles=20328
# sysctl kern.maxfilesperproc=20095
# sysctl kern.ipc.maxsockets=20328
| и не забываем занести их в /etc/sysctl.conf
kern.maxfiles=20328
kern.maxfilesperproc=20095
kern.ipc.maxsockets=20328
| Замечание 2
Второе на что необходимо обратить внимание - это общий обьем памяти доступной для аллокации одному процессу - "data seg size" (ulimit -d). По умолчанию, на FreeBSD 7.0 этот объем равен 512M:
ulimit -d
data seg size (kbytes, -d) 524288
| Указаная выше конфигурация unbound.conf потребляет 16+32 = примерно 50M, а значит об этом моменте можно не беспокоится. Но, если размеры кешей будут значительны, то будет необходимо увеличить лимиты. Значение ulimit -d выставляется в файле /boot/loader.conf Размер указывается в байтах
Спасибо камраду seacat23, участвовавшему в обсуждении статьи, за наводку на проблему нехватки файловых дескрипторов и лимита памяти доступной процессу Unbound!
Замечание 3
В последних версиях Unbound появились новые настройки отвечающие за резервирование русурсов сервера для более плавной обработки пиков запросов. Это настройки указывают на то, какой объем буфера резервировать для приема и передачи UDP пакетов:
so-rcvbuf: 4m
so-sndbuf: 4m
| подробней можно прочитать в мане unbound.conf - в качестве стартового значения рекомендовано начинать с 4m. Кроме выставления этих параметров имеет смысл так же увеличить максимальный размер буфера сокетов через sysctl.conf - увеличиваем значение с 262144 по-умолчанию, до 16m.
kern.ipc.maxsockbuf=16777216
|
Прописываем в /etc/rc.conf:
В общем-то на этом все. Запускаем unbound-checkconf и, если нет сообщений об ошибках, то можно запускать сервер:
# /usr/local/etc/rc.d/unbound start
| После этого проверяем, что все успешно запустилось:
# ps auxw | grep unbound
unbound 26674 0,0 0,7 20608 6964 ?? Is 15:42 0:00,06 /usr/local/sbin/unbound
# netstat -an | grep 53
tcp4 0 0 *.53 *.* LISTEN
udp4 0 0 *.53 *.*
# netstat -an | grep 953
tcp4 0 0 *.953 *.* LISTEN
| А так же с помошью nslookup проверим наш новый ресольвер и убедиться, что он отвечает:
# nslookup
> server 127.0.0.1
Default server: 127.0.0.1
Address: 127.0.0.1#53
> www.lissyara.su.
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
www.lissyara.su canonical name = hosting.lissyara.su.
Name: hosting.lissyara.su
Address: 77.221.149.162
>
| Если в будущем понадобиться менять какие-либо параметры в unbound.conf то, для того чтобы сервер перечитал свой конфиг, достаточно выполнения традиционного:
/usr/local/etc/rc.d/unbound reload
| unbound-control
Что касается инструмента unbound-control:
# unbound-control
[Usage: unbound-control [options] command
Remote control utility for unbound server.
Options:
-c file config file, default is /usr/local/etc/unbound/unbound.conf
-s ip[@port] server address, if omitted config is used.
-h show this usage help.
Commands:
start start server; runs unbound(8)
stop stops the server
reload reloads the server
(this flushes data, stats, requestlist)
stats print statistics
stats_noreset peek at statistics
status display status of server
verbosity <number> change logging detail
log_reopen close and open the logfile
local_zone <name> <type> add new local zone
local_zone_remove <name> remove local zone and its contents
local_data <RR data...> add local data, for example
local_data www.example.com A 192.0.2.1
local_data_remove <name> remove local RR data from name
dump_cache print cache to stdout
load_cache load cache from stdin
lookup <name> print nameservers for name
flush <name> flushes common types for name from cache
types: A, AAAA, MX, PTR, NS,
SOA, CNAME, DNAME, SRV, NAPTR
flush_type <name> <type> flush name, type from cache
flush_zone <name> flush everything at or under name
from rr and dnssec caches
flush_stats flush statistics, make zero
flush_requestlist drop queries that are worked on
dump_requestlist show what is worked on
set_option opt: val set option to value, no reload
get_option opt get option value
list_stubs list stub-zones and root hints in use
list_forwards list forward-zones in use
list_local_zones list local-zones in use
list_local_data list local-data RRs in use
forward [off | addr ...] without arg show forward setup
or off to turn off root forwarding
or give list of ip addresses
Version 1.4.6
BSD licensed, see LICENSE in source package for details.
Report bugs to unbound-bugs@nlnetlabs.nl
| Как видете все опции интуитивно понятны. Много интересных возможностей.
Для того чтобы управлять каким-либо удаленным сервером unbound через локальную версию unbound-control необходимо чтобы на машину с которой производится управление были скопированы сгенерированный на сервере публичные *.pem ключи, а так же чтобы они были прописаны в конфиг файле. Вызов unbound-control -с ./config.conf -s 1.2.3.4
Мониторинг работы
В коплект поставки unbound входят плагины для системы мониторинга под названием munin. Я ради интереса их посмотрел, но что-то мне этот munin не понравился... Решил вот для cacti что-нибудь придумать. Предлагаемый скрипт unbound_cacti надо использовать в тандеме с cron и net-snmp. Если в настройке крона ни у кого проблем возникнуть не должно, то вот с настройкой net-snmp я сильно помочь не могу - я его осилил "на скорую руку" и дошел только до волшебной команды snmpconf которая помогает генерировать snmpd.conf, чего и могу порекомендовать всем кто его раньше не использовал. У меня был установлен net-snmp-5.4.2.1_1 из портов.
unbound_cacti.tar.gz содержит скрипт для извлечения статистики из unbound-control и шаблоны для cacti
|
файл
|
скачан
|
размер
|
размещён
|
примечание
|
|
2140
|
70.5kb
|
2009-02-01
|
Скрипт для снятия статистики и шаблоны для cacti
ver. 0.7.1 (обновлен/last change: 09.01.2010)
|
|
Внутри архива скрипт для снятия статистики, кое-какие пошаговые руководства как все это правильно установить, и готовые шаблоны для импорта в Cacti.
P.S
Примеры для наглядности. Графики сняты с реальной машины обслуживающей сеть из 4K+ абонентов (спасибо Руслану за эти красивые графики):
Почти на всех графиках выводятся значения вида запрос/секунда. Это значит, что если сервер обрабатывает 600 запросов за 5 мин то на графике будет 2. График-гистограмма для времени ответов не отображает "общего" значения - столбики расположенны по принципу стека (один над другим) для того чтобы было удобнее оценивать масштабы.
За одно и стандартные cacti графики по нагруженности сервера и по трафику. Графики были сняты с того же самого сервера:
Использование DNSSEC
Сначала приведу небольшой обзор-введение о самой теме. DNSSEC это инфраструктура для обеспечения контроля за целостностью данных передаваемых в сообщениях протокола DNS. DNSSEC построенна на базе шифрования с открытым ключем и работает примерно по такому же принципу как и SSL - отправитель сообщения имеет возможность подписать его своим закрытым ключем, а получатель проверить правильность передачи имея публичный ключ отправителя.
При использовании DNSSEC на стророне авторитарного DNS сервера (отправителя) происходит хеширование групп записей зоны и "подписивание" хешей с помошью закрытого ключа. Эти дополнительные данные сохраняются в файле зоны в виде записей типа RRSIG. Публичные ключи используемые при подписывании данных так же сохраняются в зоне в виде записей типа DNSKEY. Сторона-получатель имея в своем распоряжении правильный/надежный публичный ключ отправителя может самостоятельно выполнить проверку полученныйх данных. Авторитарные сервера используют два типа ключей для подписи данных в зонах - это ZSK (Zone Signing Keys) ключи, и KSK (Key Signing Keys) ключи. Подобная схема применяется с целью ускорения процесса проверки подписей валидаторами DNS, так как, следуя рекомендациям, ZSK ключи выберают меньшего размера чем KSK ключи. Для обеспечения безопасности системы администраторы авторитарных серверов производят ротацию ZSK ключей примерно раз в месяц, в то время как KSK ключи (из-за их большей длины, а значит и устойчивости к подбору) меняют реже - примерно раз в год. KSK ключами подписывают ZSK ключи. Для того чтобы кеш сервер/валидатор с поддержкой DNSSEC мог бы произвести проверку полученных данных, ему необходимо сначала убедиться в достоверности KSK ключа, а затем, запросив данные о ZSK ключах непосредственно из записей зоны, провести их валидацию, и уже потом провести валидацию данных зоны подписанных этими ZSK ключами.
В идеале инфраструктура DNSSEC должна быть внедрена начиная с корневых серверов. В таком случае (как и при использование SSL сертификатов), клиенту для поведения проверки правильности данных необходимо иметь в своем распоряжении лишь ограниченное число "корневых" сертификатов которым он верит.
До недавнего времени DNSSEC можно было использовать ограничено. Для того чтобы иметь возможность проверять подписи какой-либо зоны, надо было устанавливать у себя ее публичные ключи - то есть для каждой зоны свой отдельный ключ. Это неприменимо для масштабов интернета. Летом 2010 года на корневых серверах была внедрена поддержка DNSSEC. В данный момент корневая зона подписана, а это значит, что для построения цепи доверия достаточно иметь в распоряжениии только публичный ключ IANA!
Unbound поддерживает использование DNSSEC (а так же инфраструктуры DLV). Для задействования этой возможности надо проделать следующие шаги:
Включение DNSSEC
Надо скачать с сайта IANA( https://data.iana.org/root-anchors/root-anchors.xml ) публичный ключ которым подписана корневая зона. Из файла root-anchors.xml надо извлеч секции
<KeyTag>
19036
</KeyTag>
<Algorithm>
8
</Algorithm>
<DigestType>
2
</DigestType>
<Digest>
49..[тут остальные символы]..B5
</Digest>
| и преобразовать их к виду:
. IN DS 19036 8 2 49..[тут остальные символы]..B5
| эти данные надо сохранить в файле /usr/local/etc/unbound/root.key
Файл root.key надо сделать доступным для записи процессу unbound:
# chown unbound:wheel /usr/local/etc/unbound/root.key
|
Надо изменит unbound.conf:
module-config: "validator iterator"
auto-trust-anchor-file: "/usr/local/etc/unbound/root.key"
|
И перезапустить Unbound:
# /usr/local/etc/rc.d/unbound restart
|
Замечания
При использовании DNSSEC надо обращать свое внимание на следующие моменты:
Переодически происходит ротация ключа которым подписана корневая зона. Администратор Unbound сервера должен об этом помнить. В состав сервера unbound интегрирована отдельная компонента под названием autotrust. В ее задачи входит автоматизация ротации ключей. Использованная нами ранее директива "auto-trust-anchor-file" как раз активирует autotrust. Если сервер работает беспрерывно то autotrust самостоятельно отследит ротацию ключа и перезапишет файл root.key новыми данными. Если же сервер не работал продолжительное время, то может понадобиться вручную обновить root.key.
Вид root.key на роботающем сервере. Видна работа autotrust - были добавлены дополнительные служебные записи:
cat ./root.key
; autotrust trust anchor file
;;id: . 1
;;last_queried: 1283605654 ;;Sat Sep 4 13:07:34 2010
;;last_success: 1283605654 ;;Sat Sep 4 13:07:34 2010
;;next_probe_time: 1283646085 ;;Sun Sep 5 00:21:25 2010
;;query_failed: 0
;;query_interval: 43200
;;retry_time: 8640
. 86400 IN DNSKEY 257 3 8 AwEAAagA
IKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF
FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2
MTJRkxoXbfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/Q
Zxkjf5/Efucp2gaDX6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9
dlzEheX7ICJBBtuA6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6
DoBQzgul0sGIcGOYl7OyQdXfZ57relSQageu+ipAdTTJ25A
sRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulqQxA+
Uk1ihz0= ;{id = 19036 (ksk), size = 2048b}
;;state=2 [ VALID ] ;;count=0
;;lastchange=1283605654 ;;Sat Sep 4 13:07:34 2010
|
IP/UDP пакеты протокола DNS с данными DNSSEC могут достигать больших размеров, в следствии чего, при прохождении через интернет они будут фрагментироваться. Если где-нибудь используется фаервол который неадекватно обрабатывает большие фрагментированные пакеты, то могут начаться проблемы. Например при использовании keep-state правил в ipfw из FreeBSD 7.2 и ниже. Такая конфигурация ipfw не работает:
add check-state
add allow icmp from me to any out keep-state
add allow tcp from me to any out keep-state
add allow udp from me to any out keep-state
add deny ip from any to any
| Для решения этой проблемы можно либо разрешить прохождение через фаервол фрагментов IP пакетов перед keep-state правилами:
allow ip from any to me frag
add check-state
add allow icmp from me to any out keep-state
add allow tcp from me to any out keep-state
add allow udp from me to any out keep-state
add deny ip from any to any
| либо наложить на FreeBSD 7.2 и ниже патч бекпортированный из FreeBSD 8.0-CURRENT который реализует функциональность дефрагментации IP на отдельном reass правиле. Патч здесь ( http://people.freebsd.org/~piso/ipfw-reass-7x.diff ). Пример правил с его применением:
add reass ip from any to any in
add check-state
add allow icmp from me to any out keep-state
add allow tcp from me to any out keep-state
add allow udp from me to any out keep-state
add deny ip from any to any
|
Комментарии
Опции unbound.conf:
- Рекомендуется выставлять количество потоков по количеству процессоров (ядер процессора).
msg-cache-slabs: 4
rrset-cache-slabs: 4
infra-cache-slabs: 4
key-cache-slabs: 4
| При использовании модели на основе потоков, значения этих параметров рекомендуется выставлять как значение степени двойки которое наиболее близко к значению num-threads. Параметры влияют на эффективность совместного использования потоками общего кеша. Если используется модель на основе форков процессов, то можно выставить эти значения в 1.
outgoing-range: 512
#outgoing-port-avoid: 0-32767
#outgoing-port-avoid: 65001-65535
| - Эти опции указывают на то, сколько различных случайных портов может использовать при проведении запросов, и на то из какого диапазона можно брать эти порты (закомментировано). По умолчанию, для исходящих запросов используется диапазон 1024 - 65535 из которого автоматически исключаются номера известных сервисов назначенных IANA. Если вдруг это понадобиться, то чтобы ограничить этот диапазон, скажем до 32768 - 65000 надо добавить в конфиг оба outgoing-port-avoid. Каждый новый запрос к авторитарным DNS серверам отправляется со своего порта — это сделано для секюрности.
msg-cache-size: 16m
rrset-cache-size: 32m
key-cache-size: 10m
cache-max-ttl: 86400
| - Эти опции указывают на то, каким будет размер кеша полученных DNS ответов (msg-cache) и, собственно, кеша DNS записей (rrset-cache). Рекомендуется устанавливать размер rrset-cache в два раза больше чем размер msg-cache. Опция cache-max-ttl указывает на максимальный срок жизни записей в кеше даже не смотря на их оригинальный TTL (86400 = 24 часа). Параметр key-cache-size указывает на размер памяти выделенной для хранения DNSSEC ключей (если unbound работает в режиме "validator iterator")
num-queries-per-thread: 1024
| - Указывает сколько одновременных клиентских запросов сможет обработать один поток.
infra-host-ttl: 60
infra-lame-ttl: 120
| - Установка этих значений указывает срок жизни записей из внутреннего кеша "неработающих" и "неправильных" DNS серверов. По умолчанию эти значения выставлены в 900 секунд (15 мин). Имеет смысл все же снизить их значения. Так, например, если применяется схема форвардинга запросов через установку forward-zone: то в случае кратковременного прерывания связи с сервером на который происходит форвардинг, такой сервер может попасть в кеш неработающих серверов и доступ к нему будет возобновлен только через 15 минут, что не есть хорошее решение :) После установки этих значений, следующая попытка обращения к серверу из черного списка будет предпринята уже через 60 сек. Эта настройка связана с безопасностью (в большей мере параноидальной безопасностью :)
access-control: 192.168.1.0/24 allow
| - Кому разрешено посылать рекурсивные запросы (пользоваться кешем)
statistics-interval: 300
logfile: ""
use-syslog: no
| - Полное отключение любого логирования. Мне не нужно. Если надо — можно включить и установить уровень verbosity от 1 до 4. В отличии от NSD, Unbound пишет в свои логи очень много разной статистики. При вербозности 4, вывод в лог по насыщенности практически напоминает tcpdump. statistics-interval - вывод в лог переодических отчетов о работе серврера.
module-config: "iterator"
| - Устанавливает режим работы как исключительно DNS кеша. Еще один вариант этой настройки "validator iterator". В таком случае появляется возможность использовать DNSSEC расширения.
- Возможность "засорить" кеш своими данными приоритет которых будет выше чем у данных оригинальной зоны. Параметр устанавливаемый после имени local-zone указывает на режим как надо отвечать на данные которые предварительно не были указаны. Варианты:
deny - serves local data (if any), else, drops queries.
refuse - serves local data (if any), else, replies with error.
static - serves local data, else, nxdomain or nodata answer.
transparent - serves local data, else, resolves normally .
direct - serves the zone data for any subdomain in the zone.
nodefault - can be used to normally resolve AS112 zones.
|
- Перенаправление всех запросов к этой зоне на указанный авторитарный сервер. Запросы отсылаются как итерационные.
- Перенаправление всех запросов к этой зоне на указанный кеширующий сервер. Запросы отсылаются как рекурсивные. Это способ форвардинга запросов. Если указать здесь:
forward-zone:
name: "."
forward-addr 192.168.2.1
| То все запросы направляемые на наш сервер, будут перенаправляться на 192.168.2.1 который уже будет проводить всю рекурсию и возвращать ответ.
#extended-statistics: yes
remote-control:
control-enable: yes
control-interface: 127.0.0.1
control-port: 953
| - Данная секция включает возможность удаленного управления сервером через unbound-control. Указывается само разрешение удаленного управления, на каком IP и на каком TCP порту сервер будет ожидать подключений. Включение опции extended-statistics значительно расширяет диапазон выводимой статистики (например, начинает выводиться статистика по количеству отдельных типов DNS запросов), но это так же снижает скорость работы сервера.
Конфигурация для больших нагрузок
В mail-листах unbound было несколько обсуждений в которых поднимался вопрос об оптимальных настройках для серверов рассчитаных на большие нагрузки. Перепишу здесь основные мысли.
Главные опции влияющие на производительность сервера - это num-queries-per-thread, outgoing-range, а так же размеры кешей msg-cache-size и rrset-cache-size.
num-queries-per-thread - устанавливает размер "очереди" запросов ждущих разрешения. Это максимальное количество одновременных рекурсий которое разрешено принять от клиетов и обработать одному процессу. Если очередь переполняется, то вновь пришедшие клиентские запросы все еще могут быть обслужанны, но только на основании тех данных, что уже находятся в кеше сервера. Если нужной информации в кеше нет то запрос может быть дропнут.
outgoing-range - устанавлиевает максимальное число одновременно инициированнных рекурсий к внешним серверам. Как много может быть паралельных разрешений имен которых еще нет в кеше.
Значения этих двух параметров надо держать близко друг к другу. Если размер num-queries-per-thread слишком большой, и при этом outgoing-range маленький, то это приведет к потерям в очереди запросов - запросы не будут обслужаны из-за задержек. В статистике такая ситуация будет видна так:
[1223529704] unbound[24517:0] info: server stats for thread 0: 42804
queries, 21012 answers from cache, 21792 recursions
[1223529704] unbound[24517:0] info: server stats for thread 0:
requestlist max 1031 avg 811.488 exceeded 10926
| exceeded 10926 - столько раз очередь num-queries-per-thread "переполнялась" - следовательно столько запросов небыло разрешено. Клиентами это будет ощущаться как то, что DNS сервер не ответил на запрос.
Для того чтобы иметь возможность устанавливать большие значения outgoing-range необходимо использовать libevent.
размещено: 2008-07-09,
последнее обновление: 2011-04-23,
автор: terminus
|
|
Комментарии пользователей [32 шт.]