воскресенье, 24 августа 2008 г.

DNS \ Microsoft Zones и SLES\Suse с LDAP

Небольшое вступление

Сейчас рассмотрим связку DNS и LDAP.
Отдельный вопрос Microsoft zones - они нужны при использовании не-мелкосовтовского DNS сервера в домене. Отличительная особенность, как и всего мелкософтовского - игнорирование стандартов rfc. О рекомендациях мелкософта можно прочитать у них-же на сайте тут.
Еще один интересный момент - Novell SLES (ну и скорее всего SLED\OpenSuSe). Интересоваться сегодня будем идущем в комплекте bind9, а так-же отсутствием документации о наложенных патчах :)

Файлы конфигураций

Конфигурации bind9 (named) штатно расположены так:
/etc/named.conf - основной файл конфигурации
/etc/sysconfig/named - файл конфигурации демона
/etc/named.conf.include и /etc/named.d/* - доп. файлы конфигураций
/var/lib/named - директория chroot
/usr/share/bind/ - тут лежат 2 интересных скрипта, идущих в пакете сервера (ldapdump и createNamedConfInclude)

ldap: будем считать, что ldap сервер и клиент у нас запущены и расположены на этом-же сервере.

Домен, для примера, обзовем domain.ru
Хосты: пусть у нас есть следующие сервера
spbdc00.domain.ru - сервер домена
spbdc01.domain.ru - наш сервер с LDAP & DNS
spbca00.domain.ru - сервер CA

DNS классически, без привязки к LDAP

Рассмотрим для примера что-же должно быть без всякого ldap.

Нам нужно описать в /etc/named.conf наши зоны:

# domain.ru zone declaration
#################################################
zone "domain.ru" in {
type master;
file "master/domain.ru";
};

# Reverse 1.168.192.in-addr.arpa zone declaration
#################################################
zone "1.168.192.in-addr.arpa" {
type master;
file "dyn/domain.ru.reverse";
};

# Active Directory Declarations
#############################################
zone "_tcp.domain.ru" IN {
type master;
file "master/_tcp.domain.ru";
check-names ignore;
};
zone "_msdcs.domain.ru" IN {
type master;
file "master/_msdcs.domain.ru";
check-names ignore;
};
zone "_sites.domain.ru" IN {
type master;
file "master/_sites.domain.ru";
check-names ignore;
};
zone "_udp.domain.ru" IN {
type master;
file "master/_udp.domain.ru.db";
check-names ignore;
};

Теперь создадим сами файлы зон в /var/lib/named/master/ и обратную в /var/lib/named/dyn/

/var/lib/named/dyn/1.168.192.in-addr.arpa

$TTL 172800
@ IN SOA spbdc01.domain.ru. root.spbdc01.domain.ru. (
2008082201
10800
3600
604800
86400)
IN NS spbdc01.domain.ru.
15 IN PTR spbdc00.domain.ru
16 IN PTR spbdc01.domain.ru
17 IN PTR spbca00.domain.ru

/var/lib/named/master/_msdcs.domain.ru

$TTL 172800
@ IN SOA spbdc01.domain.ru. root.spbdc01.domain.ru. (
2008082201
10800
3600
604800
432000)
IN NS spbdc01.domain.ru.
_ldap._tcp.dc IN SRV 0 0 389 spbdc01.domain.ru.
_kerberos._tcp.dc IN SRV 0 0 88 spbdc01.domain.ru.

/var/lib/named/master/_sites.domain.ru

$TTL 172800
@ IN SOA spbdc01.domain.ru. root.spbdc01.domain.ru. (
2008082201
10800
3600
604800
432000)
IN NS spbdc01.domain.ru.

/var/lib/named/master/_tcp.domain.ru

$TTL 172800
@ IN SOA spbdc01.domain.ru. root.spbdc01.domain.ru. (
2008082201
10800
3600
604800
432000)
IN NS spbdc01.domain.ru.
_ldap IN SRV 0 0 389 spbdc01.domain.ru.
_kerberos IN SRV 0 0 88 spbdc01.domain.ru.

/var/lib/named/master/_udp.domain.ru

$TTL 172800
@ IN SOA spbdc01.domain.ru. root.spbdc01.domain.ru. (
2008082201
10800
3600
604800
432000)
IN NS spbdc01.domain.ru.

/var/lib/named/master/domain.ru

$TTL 172800
@ IN SOA spbdc01.domain.ru. root.spbdc01.domain.ru. (
2008082201
10800
3600
604800
86400)
IN NS spbdc01.domain.ru.
spbca00 IN A 192.168.1.17
spbdc01 IN A 192.168.1.16
spbdc00 IN A 192.168.1.15

Теперь рестартуем демон и проверяем работоспособность...
Мы сделали всю конфигурацию (более-менее).

DNS с хранением данных в LDAP

Теперь мы перенесем все в наш LDAP. Но будем делать не штатными средствами (Yast) а вручную.
Погуглив, можно найти упоминание патча, который похоже Novell и стала использовать, однако ничего ни в документации, ни в аннотации к пакету не указано.
На самом деле это действительно этот патч и мы будем пользоваться его мануалом.

Нам нужно сделать ldif измененийи влить его в ldap.
Экспериментально стало ясно, что bind ищет в каталоге по ZoneName и relativeDomainName.
По нашему же желанию создадим следующую структуру (навеяно интернет-статьями):


# Zone domain.ru
dn: zoneName=domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: domain.ru
relativeDomainName: domain.ru

# SOA-record for zone domain.ru
dn: relativeDomainName=@,zoneName=domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: domain.ru
relativeDomainName: @
NSRecord: spbdc01.domain.ru.
SOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 1D

# spbdc01 A 192.168.1.15
dn: relativeDomainName=spbdc01,zoneName=domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: domain.ru
relativeDomainName: spbdc01
DNSClass: IN
ARecord: 192.168.1.16

# ns CNAME spbdc01
dn: relativeDomainName=ns,zoneName=domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: domain.ru
relativeDomainName: ns
DNSClass: IN
CNAMERecord: spbdc01

# Revers Zone 1.168.192.in-addr.arpa
dn: zoneName=1.168.192.in-addr.arpa,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: 1.168.192.in-addr.arpa
relativeDomainName: 1.168.192.in-addr.arpa

# SOA-record for zone 1.168.192.in-addr.arpa
dn: relativeDomainName=@,zoneName=1.168.192.in-addr.arpa,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: 1.168.192.in-addr.arpa
relativeDomainName: @
NSRecord: spbdc01.domain.ru.
SOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 1D

# 15 PTR spbdc01.domain.ru.
dn: relativeDomainName=16,zoneName=1.168.192.in-addr.arpa,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: 1.168.192.in-addr.arpa
relativeDomainName: 16
PTRRecord: spbdc01.domain.ru.

# Zone _tcp.domain.ru
dn: zoneName=_tcp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _tcp.domain.ru
relativeDomainName: _tcp.domain.ru

# SOA-record for zone
dn: relativeDomainName=@,zoneName=_tcp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _tcp.domain.ru
relativeDomainName: @
NSRecord: spbdc01.domain.ru.
SOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D

# _ldap._tcp.domain.ru. SRV 0 0 389 spbdc01.domain.ru.
dn: relativeDomainName=_ldap,zoneName=_tcp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _tcp.domain.ru
relativeDomainName: _ldap
DNSClass: SRV
SRVRecord: 0 0 389 spbdc01.domain.ru.

#_kerberos._tcp.domain.ru. SRV 0 0 88 spbdc01.domain.ru.
dn: relativeDomainName=_kerberos,zoneName=_tcp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _tcp.domain.ru
relativeDomainName: _kerberos
DNSClass: SRV
SRVRecord: 0 0 80 spbdc01.domain.ru.

# Zone _udp.domain.ru
dn: zoneName=_udp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _udp.domain.ru
relativeDomainName: _udp.domain.ru

# SOA-record for zone
dn: relativeDomainName=@,zoneName=_udp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _udp.domain.ru
relativeDomainName: @
NSRecord: spbdc01.domain.ru.
SOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D

# Zone _sites.domain.ru
dn: zoneName=_sites.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _sites.domain.ru
relativeDomainName: _sites.domain.ru

# SOA-record for zone
dn: relativeDomainName=@,zoneName=_sites.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _sites.domain.ru
relativeDomainName: @
NSRecord: spbdc01.domain.ru.
SOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D

# Zone _msdcs.domain.ru
dn: zoneName=_msdcs.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _msdcs.domain.ru
relativeDomainName: _msdcs.domain.ru

# SOA-record for zone
dn: relativeDomainName=@,zoneName=_msdcs.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _msdcs.domain.ru
relativeDomainName: @
NSRecord: spbdc01.domain.ru.
SOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D

# _ldap._tcp.dc._msdcs.domain.ru. SRV 0 0 389 spbdc01.domain.ru.
dn: relativeDomainName=_ldap._tcp.dc,zoneName=_msdcs.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _msdcs.domain.ru
relativeDomainName: _ldap._tcp.dc
DNSClass: SRV
SRVRecord: 0 0 389 spbdc01.domain.ru.

#_kerberos._tcp.dc._msdcs.domain.ru. SRV 0 0 88 spbdc01.domain.ru.
dn: relativeDomainName=_kerberos._tcp.dc,zoneName=_msdcs.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: top
objectClass: dNSZone
zoneName: _msdcs.domain.ru
relativeDomainName: _kerberos._tcp.dc
DNSClass: SRV
SRVRecord: 0 0 80 spbdc01.domain.ru.

теперь добавим эти изменения в каталог (ou=DNS у нас уже д.б. создан, учетная запись администратора - Admin )

# ldapadd -W -x -D "cn=Admin,dc=domain,dc=ru" -f наш_файл.ldif

Теперь изменим конфигурацию DNS в /etc/named.conf

все строки содержащие указание хранения зоны file "директория/имя_зоны";
изменим на

database "ldap ldap://127.0.0.1/ou=DNS,dc=domain,dc=ru 178600";

где говорится, что зоны лежат в базе данных, путь до которой - в LDAP в ou=DNS и по умолчанию TTL выставить в 178600
Имя зоны, как видно здесь не указано.

Дополнительно - необходимо включить схему dnszones.schema и индексирование в /etc/openldap/slapd.conf

include /etc/openldap/schema/dnszone.schema

index zoneName eq
index relativeDomainName eq

Перезапускаем, проверяем, смотрим лог.
Все работает.
Мы переделали конфигурацию на хранение данных в LDAP.
НО! это не правильный путь :)
Правильный рассмотрим далее...

Правильный DNS и LDAP

Итак, почему-же предыдущий способ не правильный? Все просто - изменения не правильны, и разработчиками дистрибутива предусмотрена другая схема работы.
Рассмотрим подробнее.

У на средствами Yast настроены LDAP сервер и LDAP клиент, теперь мы настоем DNS сервер.

/sbin/yast2 dns-server &




На первой вкладке включаем запуск, открываем порт на firewall и включаем поддержку ldap.
на вкладке DNS Zones создаем зоны.
Однако ни Microsoft зоны, ни revers зону с PTR записями так создать не получится.

MS зоны не соответствуют rfc т.к. содержат символ "_", а PTR записи через Yast просто нельзя создать (сразу).
Создадим только прямую зону domain.ru и изучем её :)

Теперь берем и создаем файл изменений:

dn: zoneName=_tcp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: dNSZone
dNSClass: IN
dNSTTL: 172800
nSRecord: spbdc01.domain.ru.
relativeDomainName: @
sOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D
zoneName: _tcp.domain.ru

dn: relativeDomainName=_ldap,zoneName=_tcp.domain.ru,ou=DNS,dc=domain,dc=ru
SRVRecord: 0 0 389 spbdc01.domain.ru.
dNSClass: SRV
dNSTTL: 172800
objectClass: dNSZone
relativeDomainName: _ldap
zoneName: _tcp.domain.ru

dn: relativeDomainName=_kerberos,zoneName=_tcp.domain.ru,ou=DNS,dc=domain,dc=ru
SRVRecord: 0 0 88 spbdc01.domain.ru.
dNSClass: SRV
dNSTTL: 172800
objectClass: dNSZone
relativeDomainName: _kerberos
zoneName: _tcp.domain.ru

dn: zoneName=_udp.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: dNSZone
dNSClass: IN
dNSTTL: 172800
nSRecord: spbdc01.domain.ru.
relativeDomainName: @
sOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D
zoneName: _udp.domain.ru

dn: zoneName=_sites.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: dNSZone
dNSClass: IN
dNSTTL: 172800
nSRecord: spbdc01.domain.ru.
relativeDomainName: @
sOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D
zoneName: _sites.domain.ru

dn: zoneName=_msdcs.domain.ru,ou=DNS,dc=domain,dc=ru
objectClass: dNSZone
dNSClass: IN
dNSTTL: 172800
nSRecord: spbdc01.domain.ru.
relativeDomainName: @
sOARecord: spbdc01.domain.ru. root.spbdc01.domain.ru. 2008080101 3H 1H 1W 5D
zoneName: _msdcs.domain.ru

dn: relativeDomainName=_ldap._tcp.dc,zoneName=_msdcs.domain.ru,ou=DNS,dc=domain,dc=ru
SRVRecord: 0 0 389 spbdc01.domain.ru.
dNSClass: SRV
dNSTTL: 172800
objectClass: dNSZone
relativeDomainName: _ldap._tcp.dc
zoneName: _msdcs.domain.ru

dn: relativeDomainName=_kerberos._tcp.dc,zoneName=_msdcs.domain.ru,ou=DNS,dc=domain,dc=ru
SRVRecord: 0 0 88 spbdc01.domain.ru.
dNSClass: SRV
dNSTTL: 172800
objectClass: dNSZone
relativeDomainName: _kerberos._tcp.dc
zoneName: _msdcs.domain.ru

внесем изменения в каталог

# ldapadd -W -x -D "cn=Admin,dc=domain,dc=ru" -f /etc/openldap/наш_файл.ldif


теперь добавим в /etc/named.conf записи о зонах

zone "domain.ru" in {
file "master/domain.ru";
type master;
};
zone "_tcp.domain.ru" in {
file "master/_tcp.domain.ru";
type master;
};
zone "_udp.domain.ru" in {
file "master/_udp.domain.ru";
type master;
};
zone "_sites.domain.ru" in {
file "master/_sites.domain.ru";
type master;
};
zone "_msdcs.domain.ru" in {
file "master/_msdcs.domain.ru";
type master;
};
zone "1.168.192.in-addr.arpa" in {
file "master/1.168.192.in-addr.arpa";
type master;
};

перезапустим Yast и вуаля - все встало на свои места.
НО! у Yast есть несколько недостатков, во первых работа с обратными зонами мне показалась очень странной (SLES 10SP2 i386), во вторых он производит изменения в конфигах без предупреждений и бэкапов, т.е. с легкостью уберет такие директивы, как например "check-names ignore;"
И еще в таком методе есть нюанс - DNS записи хранятся в LDAP и в файлах одноврименно, каждый раз когда из Yast нажимается кнопка применить и сохранить в конфигурации DNS - будет произведена запись в LDAP и дамп в файлы.

На этом вроде все. Главное - пользуйтесь последним, правильным способом, но не забывайте о первых двух :)



2 комментария:

Анонимный комментирует...

почему вместо слова "связики" нельзя упоминать нормальные слова ?

Sun Cho комментирует...

Эммм... проверил еще раз, "связиков" нету, попробуйте протереть монитор :)
шутка.