The Apple Geek

Чему ты научился сегодня?

Настройка DNS-сервера в Mac OS X. Часть 1, Unix Way (BIND)

| Comments

Хочу рассказать о странном - о платной (25$) программе ”DNS Enabler” для создания DNS-сервера. Об этом меня попросил один из читателей:

Есть такая программа “DNS Enabler” (www.cutedgesystems.com). Если будет время и желание - напиши, как ею пользоваться с примерами. Думаю, маководы скажут спасибо за этот материал.

О “странном”, так как в Mac OS X и так есть DNS-сервер ISC BIND (в лицензионных условиях я сейчас разбираться не очень хочу, поэтому скажу, что это бесплатное программное обеспечение с открытыми исходными текстами).

$ named -v
BIND 9.6.0-APPLE-P2

Я хотел продемонстрировать, что BIND является очень популярным сервером DNS в Интернет, но моя демонстрация хоть и не удалась, но по крайней мере развеселила. В идеале можно узнать версию удалённого DNS-сервера с помощью команды:

$ dig @dns.server.ip.address version.bind chaos txt

Но информация о версии BIND считается небезопасной утечкой информации, и администраторы DNS отключают её выдачу, но при этом всячески развлекаются. Мне особенно понравился ответ сервера ns2.life.net: “None of your business” (грубо говоря “Не твоё собачье дело”) :-) Примеры ниже (только один сервер сообщил о своей версии):

$ dig @4.2.2.1 version.bind chaos txt
version.bind.       0   CH  TXT "If you have a legitimate reason for requesting this info, please contact hostmaster@Level3.net"

$ dig @A.ROOT-SERVERS.NET version.bind chaos txt
version.bind.       0   CH  TXT "This space intentionally left blank"

$ dig @ns2.life.ua version.bind chaos txt
version.bind.       0   CH  TXT "None of your business"

$ dig @66.244.95.20 version.bind chaos txt
version.bind.       0   CH  TXT "[secured]"

$ dig @133.145.228.6 version.bind chaos txt
version.bind.       0   CH  TXT "unknown"

$ dig @218.248.240.208 version.bind chaos txt
version.bind.       0   CH  TXT "9.2.1"

Несмотря на популярность BIND, его настройка требует навыков системного администрирования. Поэтому на Mac OS X его настройка - удел не слишком многих. Есть другое решение - в Mac OS X Server тоже используется BIND в качестве DNS-сервера, и у него есть хороший графический интерфейс. Но это сервер, и обычному пользователю он тоже вряд ли доступен. Поэтому третья альтернатива - использование под Mac OS X стороннего пакета, создающего DNS-сервер, и как раз здесь я рассмотрю ”DNS Enabler”.

Три альтернативы - три части этой статьи. Сложность идёт по убыванию. Первый раздел - самый сложный, это Unix-way. Последний - самый простой, это Mac-way. Тема получается объёмной, поэтому если не хотите сложностей, то подождите вторую и третью части статьи, они, в отличие от ещё не написанной ”Amazon Web Services, часть 3”, будут в течение следующих дней.

Задача

Для чего предназначен DNS-сервер? Если вы дочитали до этого момента, то можно об этом не рассказывать :-)

Детальное описание определений, сценариев работы, конфигурирования DNS можно узнать в книге издательства O’reilly ”DNS and BIND”.

Я расскажу о типичной конфигурация, которую я хочу реализовать. Допустим, у меня есть домен ctrld.me. Этот домен расположен на DNS-серверах провайдера. Но для дома я хочу сделать поддомен home.ctrld.me, в котором я хочу описать iPhone, iPod Touch, PS3, ноутбук и тестовый Mac OS X Server. Это будет “прямая зона”. Устройства подключены по WiFi к TimeCapsule, которая раздаёт им по DHCP закреплённые за их MAC-адресами.

Вопрос выбора имён непрост. Называть устройство просто iPhone информативно, но неинтересно. Лучше выбрать какое-либо правило, и его придерживаться. Некоторые называют хосты по именам груческих богов, некоторые - по названием гор. Главное чтобы этих названий было достаточно для того, чтобы назвать все хосты. Для этого конкретного случая я решил использовать названия островов в Венесуэле. Кроме этого в домашней сети (192.168.98.0/24, у меня отнюдь не 253 хоста, но так проще) я придерживаюсь того, что адрес .1 закреплён за маршрутизатором, адреса с .2 по .9 зарезервированы для серверов, с .10 по .99 зарезервированы для “статических” адресов, закреплённых по MAC, а после .100 выдаются любым другим устройствам, попадающим в сеть.

Раскладка такая:

  • TimeCapsule: aves.home.ctrld.me, 192.168.98.1
  • Mac OS X Server: coche.home.ctrld.me, 192.168.98.2
  • PS3: cubagua.home.ctrld.me, 192.168.98.3
  • MacBook Pro: patos.home.ctrld.me, 192.168.98.10
  • iPod Touch: toas.home.ctrld.me, 192.168.98.11
  • iPhone: zapara.home.ctrld.me, 192.168.98.12

DNS-сервер будет стоять на MacBook Pro. Плохая идея - DNS-сервер должен всегда находиться в сети, и правильно его ставить на выделенном сервере (в моём случае это 192.168.98.2). Но для теста подойдёт.

Чтобы DNS-сервер мог обслуживать запросы клиентов в сети на определение произвольных хостов (например, cnn.com), а но только тех, которые мы сконфигурировали в home.ctrld.me, нужно перенаправить эти запросы на внешний DNS. Я буду использовать для этого публичный DNS-сервер Google 8.8.8.8.

В результате мы сможем использовать наш DNS-сервер для полноценной работы.

Настройка BIND на Mac OS X

Сформулирую задачу терминами DNS. Прямая зона (соответствие между именами и IP-адресами) выглядит так:

$ORIGIN home.ctrld.me.
aves    IN  A   192.168.98.1
coche   IN  A   192.168.98.2
cubagua IN  A   192.168.98.3
patos   IN  A   192.168.98.10
toas    IN  A   192.168.98.11
zapara  IN  A   192.168.98.12

Обратная зона (соответствие между IP-адресом и именем) такая:

$ORIGIN 98.168.192.in-addr.arpa.
1       IN  PTR aves.home.ctrld.me.
2       IN  PTR coche.home.ctrld.me.
3       IN  PTR cubagua.home.ctrld.me.
10      IN  PTR patos.home.ctrld.me.
11      IN  PTR toas.home.ctrld.me.
12      IN  PTR zapara.home.ctrld.me.

Обратите внимание, что точки в конце - это отнюдь не моя любовь к непропусканию точек в конце предложения.

Настраивать bind я буду, опираясь на статью ”How To: Enable BIND - Mac OS X’s Built-in DNS Server”. Также хочу порекомендовать посмотреть инструкцию по настройке BIND на FreeBSD на одном из моих любимых блогов по Unix www.lissyara.su.

Конфигурируем rndc

rndc - это утилита для управления BIND’ом. Для начала нужно сгенерировать ключ и конфигурационный файл:

$ sudo -s
$ rndc-confgen -b 256 > /etc/rndc.conf
$ head -n5 /etc/rndc.conf | tail -n4 > /etc/rndc.key

Файл /etc/rndc.conf будет примерно такой:

# Start of rndc.conf
key "rndc-key" {
    algorithm hmac-md5;
    secret "C0p1VDGqN1m4ApoKIDze+GZORY+tbYSORw56+WjIpGg=";
};

options {
    default-key "rndc-key";
    default-server 127.0.0.1;
    default-port 953;
};
# End of rndc.conf

Файл /etc/rndc.key - это выдержка из предыдущего:

key "rndc-key" {
    algorithm hmac-md5;
    secret "C0p1VDGqN1m4ApoKIDze+GZORY+tbYSORw56+WjIpGg=";
};

Мне эти ключи не жаль, но вы свои ключи никому не показывайте.

Важно, чтобы порт для rndc в /etc/named.conf (он есть изначально) и в /etc/rndc.conf должны быть одинаковыми, иначе вы не сможете управлять BIND’ом:

# cat /etc/named.conf | grep 'inet.*\?port'
    inet 127.0.0.1 port 54 allow {any;}
# cat /etc/rndc.conf | grep '\-port'
    default-port 953;

Если они отличаются, то нужно в /etc/named.conf указать нужный порт:

# sed 's/inet 127.0.0.1 port 54/inet 127.0.0.1 port 953/' /etc/named.conf > /tmp/named.conf
# cp /etc/named.conf /etc/named.conf.dist
# mv /tmp/named.conf /etc/

Настройка автозапуска

Отключаем ключ “Disabled” в конфигурации для launchd при запуске BIND (демон называется named), для чего указываем в lauchctl опцию “-w”:

# launchctl load -w /System/Library/LaunchDaemons/org.isc.named.plist

Обратите внимание на то, что в последних Mac OS X .plist не меняется, “Now the state of the Disabled key is stored elsewhere on-disk”. И это “elsewhere” значит “/private/var/db/launchd.db/com.apple.launchd/overrides.plist”. Как я узнал? Перечитайте статью ”Слежение за изменениями файловой системы”.

Named теперь запущен и должен стартовать при перезапуске системы.

# ps ax | grep named | grep -v grep 
27718   ??  Ss     0:00.01 /usr/sbin/named -f

Ручная остановка named:

# launchctl stop org.isc.named

Ручной запуск:

# launchctl start org.isc.named

Конфигурируем named

# vim /etc/named.conf

В разделе options добавляем forwarder - адрес DNS-сервера куда будут идти транслироваться все запросы, на которые наш DNS-сервер ответить не может?

    forwarders      { 8.8.8.8; };

Желающие могут скрыть версию BIND:

    version         "for this info please contact hostmaster@ctrld.me";

В глобальной конфигурации добавляем файлы зон (прямую и обратную):

zone "home.ctrld.me" IN {
    type master;
    file "home.ctrld.me.fwd";
};

zone "98.168.192.in-addr.arpa" {
    type master;
    file "192.168.98.rev";
    allow-update { none; };
};

Файл /etc/named.conf будет выглядеть так:

include "/etc/rndc.key";

controls {
    inet 127.0.0.1 port 953 allow {any;}
    keys { "rndc-key"; };
};

options {
    directory "/var/named";
    forwarders      { 8.8.8.8; };
    version         "for this info please contact hostmaster@ctrld.me";
};

zone "." IN {
    type hint;
    file "named.ca";
};

zone "localhost" IN {
    type master;
    file "localhost.zone";
    allow-update { none; };
};

zone "0.0.127.in-addr.arpa" IN {
    type master;
    file "named.local";
    allow-update { none; };
};

zone "home.ctrld.me" IN {
    type master;
    file "home.ctrld.me.fwd";
};

zone "98.168.192.in-addr.arpa" {
    type master;
    file "192.168.98.rev";
    allow-update { none; };
};

logging {
        category default {
                _default_log;
        };

        channel _default_log  {
                file "/Library/Logs/named.log";
                severity info;
                print-time yes;
        };
};

Конфигурируем прямую зону

# cd /var/named/
# vim home.ctrld.me.fwd

Зона выглядит так:

$TTL    3600
@               IN      SOA home.ctrld.me.  hostmaster.home.ctrld.me.  (
                            2009121801      ; Serial
                            3600            ; Refresh
                            900             ; Retry
                            3600000         ; Expire
                            3600 )          ; Minimum
@               IN      NS  patos.home.ctrld.me.
$ORIGIN home.ctrld.me.
aves            IN      A   192.168.98.1
coche           IN      A   192.168.98.2
cubagua         IN      A   192.168.98.3
patos           IN      A   192.168.98.10
toas            IN      A   192.168.98.11
zapara          IN      A   192.168.98.12

NS - адрес DNS-сервера. A - соответствие имя-адрес. Важное поле - Serial, при модификации зоны нужно его увеличивать. $ORIGIN не нужен, он берётся из конфигурации зоны, но я так привык.

Конфигурируем обратную зону

# vim 192.168.98.rev

Зона:

$TTL    3600
@               IN      SOA home.ctrld.me.  hostmaster.home.ctrld.me.  (
                            2009121801      ; Serial
                            3600            ; Refresh
                            900             ; Retry
                            3600000         ; Expire
                            3600 )          ; Minimum
@               IN      NS  patos.home.ctrld.me.
$ORIGIN 98.168.192.in-addr.arpa.
1       IN      PTR aves.home.ctrld.me.
2       IN      PTR coche.home.ctrld.me.
3       IN      PTR cubagua.home.ctrld.me.
10      IN      PTR patos.home.ctrld.me.
11      IN      PTR toas.home.ctrld.me.
12      IN      PTR zapara.home.ctrld.me.

98.168.192.in-addr.arpa = 192.168.98 в обратном порядке плюс суффикс, говорящий о том, что это обратная зона.

Применение изменений

Поработали мы хорошо, перечитываем конфигурацию:

# rndc reload
server reload successful

Проверяем логи (successful не всегда обозначает отсутствие ошибок):

# tail -20 /Library/Logs/named.log
18-Dec-2009 21:29:42.366 received control channel command 'reload'
18-Dec-2009 21:29:42.366 loading configuration from '/private/etc/named.conf'
18-Dec-2009 21:29:42.367 using default UDP/IPv4 port range: [49152, 65535]
18-Dec-2009 21:29:42.367 using default UDP/IPv6 port range: [49152, 65535]
18-Dec-2009 21:29:42.369 reloading configuration succeeded
18-Dec-2009 21:29:42.369 reloading zones succeeded

Всё в порядке.

Если же где-то была ошибка, то всё будет в логах. Например, имитируем ошибку в имени файла зоны:

# mv 192.168.98.rev 192.168.98.rev_err
# > /Library/Logs/named.log
# rndc reload
# tail -20 /Library/Logs/named.log

Получили ошибку в логе:

18-Dec-2009 21:31:27.001 zone 98.168.192.in-addr.arpa/IN: loading from master file 192.168.98.rev failed: file not found

Восстанавливаем файл зоны, теперь всё в норме:

# mv 192.168.98.rev_err 192.168.98.rev
# rndc reload
# tail /Library/Logs/named.log
18-Dec-2009 21:32:39.168 reloading configuration succeeded
18-Dec-2009 21:32:39.168 reloading zones succeeded

Проверка работы named

Для проверки используем dig, запрашиваем информацию по корневой зоне (по 9.6.0-APPLE-P2 и @192.168.98.10 видим, что используется именно наш DNS):

$ dig @192.168.98.10

; DiG 9.6.0-APPLE-P2 @192.168.98.10
; (1 server found)
;; global options: +cmd
;; Got answer:
;; HEADER opcode: QUERY, status: NOERROR, id: 12368
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;.              IN  NS

;; ANSWER SECTION:
.           125343  IN  NS  K.ROOT-SERVERS.NET.
.           125343  IN  NS  M.ROOT-SERVERS.NET.
.           125343  IN  NS  C.ROOT-SERVERS.NET.
.           125343  IN  NS  H.ROOT-SERVERS.NET.
.           125343  IN  NS  B.ROOT-SERVERS.NET.
.           125343  IN  NS  E.ROOT-SERVERS.NET.
.           125343  IN  NS  J.ROOT-SERVERS.NET.
.           125343  IN  NS  L.ROOT-SERVERS.NET.
.           125343  IN  NS  F.ROOT-SERVERS.NET.
.           125343  IN  NS  D.ROOT-SERVERS.NET.
.           125343  IN  NS  I.ROOT-SERVERS.NET.
.           125343  IN  NS  A.ROOT-SERVERS.NET.
.           125343  IN  NS  G.ROOT-SERVERS.NET.

;; Query time: 9 msec
;; SERVER: 192.168.98.10#53(192.168.98.10)
;; WHEN: Fri Dec 18 21:34:22 2009
;; MSG SIZE  rcvd: 228

Смотрим нашу зону home.ctrld.me:

$ dig @192.168.98.10 home.ctrld.me soa
home.ctrld.me.      3600    IN  SOA home.ctrld.me. hostmaster.home.ctrld.me. 2009121801 3600 900 3600000 3600
home.ctrld.me.      3600    IN  NS  patos.home.ctrld.me.
patos.home.ctrld.me.    3600    IN  A   192.168.98.10

Смотрим одну из записей:

# dig @192.168.98.10 zapara.home.ctrld.me any
zapara.home.ctrld.me.   3600    IN  A   192.168.98.12

Проверяем реверсную зону:

$ dig @192.168.98.10 -x 192.168.98.2
2.98.168.192.in-addr.arpa. 3600 IN  PTR coche.home.ctrld.me.

Проверяем, что форвардер тоже работает, запрашивая внешний домен:

$ dig @192.168.98.10 cnn.com
cnn.com.        300 IN  A   157.166.255.19
cnn.com.        300 IN  A   157.166.224.25
cnn.com.        300 IN  A   157.166.224.26
cnn.com.        300 IN  A   157.166.226.25
cnn.com.        300 IN  A   157.166.226.26
cnn.com.        300 IN  A   157.166.255.18

Ещё вспоминаем о версии named и получаем именно то, что сконфигурировали в /etc/named.conf:

$ dig @192.168.98.10 version.bind chaos txt
version.bind.       0   CH  TXT "for this info please contact hostmaster@ctrld.me"

Всё работает.

Настраиваем использование нашего DNS

Для того, чтобы воспользоваться нашим свеженастроенным DNS, конфигурируем его в System Preferences/Network на активном сетевом соединении (у меня это Airport):

Нажимаем кнопку Advanced и в закладке DNS устанавливаем 192.168.98.10:

Ok, Apply. Убеждаемся, что автоматически установлен именно нужный DNS:

$ cat /etc/resolv.conf 
nameserver 192.168.98.10

Dig берёт информацию из /etc/resolv.conf, проверяем:

$ dig toas.home.ctrld.me
toas.home.ctrld.me. 3600    IN  A   192.168.98.11

Всё. DNS настроен. Идём пить чай и радоваться тому, что каждый следующий способ на порядок проще предыдущего.

To be continued…

Comments