1. Введение. Недавно в одной из организаций, с которой я сотрудничаю было принято решение перейти на режим терминальной работы с заменой всех компьютеров в сети на бездисковые рабочие станции (терминалы). Сразу встал вопрос - каким образом организовать разграничение доступа в Интернет для пользователей будущего сервера терминалов? Ранее эта проблема легко решалась на шлюзе под управлением FreeBSD с помощью IPFW и NetAMS, благо каждый пользователь сети однозначно идетифицировался по собственному IP. Но в новых условиях работы все пользователи будут выходить в интернет с одного физического адреса, а именно сервера терминалов. Долгое гугление дало одно-единственное решение - proxy-сервер с авторизацией. Статья SQUID+AD на этом сайте помогла сделать окончательный выбор. Не могу сказать, что я пришел в восторг от перспективы создания домена, да еще на Мастдае, но другой альтернативы нет. Но первое же "лабораторное" тестирование будущей схемы (на VMWARE) принесло еще один неприятный сюрприз - для подъема Active Directory жизненно необходим DDNS (Dynamic DNS) сервер. Таковой у меня имелся на том же шлюзе - "старый добрый" BIND, но Мастдай наотрез отказался с ним работать, ссылаясь на маловразумительные ошибки типа "SERVER_FAILURE", при этом, разумеется, в логах BIND никаких ошибок не было. Если же поднимать DNS на самом контроллере домена, ситуация искривлялась еще больше - появлялись два DNS сервера, обслуживающих одну и ту же зону, при этом обновлять ее РЕАЛЬНЫМИ ДАННЫМ мог только BIND (именно ему DHCP сообщал свои данные при выдаче новых адресов, да и TFTPD для загрузки по PXE тоже находится на FreeBSD). Замаячила совсем уж безрадостная перспектива подъема на Мастдае DHCP и TFTP. Но на это я, как говорил герой одной замечательной комедии, "пойтить не могу"!. Новое гугление принесло еще больше неразберихи - кто-то утверждал, что ему удалось заточить BIND для обслуживания запросов Active Directory, другие в один голос утверждали, что это невозможно, более того, возникший вследствие такого решения букет проблем превратит жизнь админа-испытателя в сущий ад, а закончится все неминуемым падением домена и полным разрушением Active Directory вообще :). Ну, как говорится, "глаза боятся, а руки делают", тем более я то пока буду "тренироваться на кошках". 2. Как же она работает или для чего Active Directory DNS? На верный путь наставила статья "Dynamic DNS and Windows 2000 at Yale University"
(
http://babs.its.yale.edu/yalead/ddns.asp ) .
В ней достаточно подробно описано почему наличие DDNS так необходимо Мастдаю, что именно ему требуется от него, какие данные он там хранит и как использует. Если вкратце - для запуска многих служб (LDAP, Kerberos, Global Catalog и т.д.) ему необходимо иметь информацию, на каких серверах домена они запускаются и работают. Для этого в DNS заносятся соответствующие "SRV" записи. Но это еще не все: по идеологии мелкомягких локальная зона обязана содержать еще ряд вложенных зон (_msdcs, _tcp и прочие). Именно эти зоны он и апдейтит для занесения туда нужных ему сведений. Ну тут все понятно - парни из Редмонда готовы спать на потолке и брюки одевать через голову, лишь бы быть не такими как все остальные. Одни имена подзон чего стоят, если вспомнить, что underscore "_" в именах доменов вообще-то запрещены RFC :). Вобщем, ничего "военного" масдайный DNS в себе не несет, а значит мы вполне сможем без него обойтись.
3. Настраиваем BIND. Вообще-то для безопасного обновления зон в BIND предусмотрен механизм ключей (hmac-md5), которыми BIND обменивается с желающими обновить ту или иную зону. Разумеется, гордая птица Мастдай выше все этого и ничего подобного делать не станет. Поэтому разрешения на обновления зон будет выдавать на определенный(ные) IP, на что BIND будет разумеется ругаться.
Предположим, что у меня есть зона TEST.LOCAL с подсетью 192.168.10.0/24. BIND установлен на хосте с именем squid.test.local. Терминальный сервер иметт IP 192.168.10.10 и называется t-server.test.local.
В named.conf она описана как:
zone "test.local" { type master ; file "dynamic/test.local" ; }; zone "10.168.192.in-addr.arpa" { type master ; file "dynamic/10.168.192.in-addr.arpa" ; };
Нам нужно создать ACL для обновления зон и указать в нем адрес контроллера домена. А так же создать следующие подзоны для корректной работы Active Directory:_msdcs _tcp _udp _sites DomainDnsZones ForestDnsZones Вот как это будет выглядеть в named.conf:
acl AD- Server { 192.168.10.10 ; }; // Active Directory - _msdcs zone "_msdcs.test.local" { type master ; allow - update { AD - Server ;}; check - names ignore ; file "dynamic/_msdcs.test.local" ; }; // Active Directory - _sites zone "_sites.test.local" { type master ; allow - update { AD - Server ;}; check - names ignore ; file "dynamic/_sites.test.local" ; }; // Active Directory - _tcp zone "_tcp.test.local" { type master ; allow - update { AD - Server ;}; check - names ignore ; file "dynamic/_tcp.test.local" ; }; // Active Directory - _udp zone "_udp.test.local" { type master ; allow - update { AD - Server ;}; check - names ignore ; file "dynamic/_udp.test.local" ; }; // Active Directory - DomainDnsZones zone "DomainDnsZones.test.local" { type master ; allow - update { AD - Server ;}; check - names ignore ; file "dynamic/DomainDnsZones.test.local" ; }; // Active Directory - ForestDnsZones zone "ForestDnsZones.test.local" { type master ; allow - update { AD - Server ;}; check - names ignore ; file "master/ForestDnsZones.test.local" ; };
Параметр "check-names ignore" заставит BIND на обращать внимание на "_". И на всякий случай разрешить обновление нашей зоны TEST.LOCAL
zone "test.local" { type master ; allow - update { AD - Server ;}; file "dynamic/test.local" ; }; zone "10.168.192.in-addr.arpa" { type master ; allow - update { AD - Server ;}; file "dynamic/10.168.192.in-addr.arpa" ; };
Затем в каталоге dynamic создаем сами файлы зон следующего содержания: файл _msdcs.test.local
$ORIGIN . $TTL 86400 ; 1 day _msdcs . test . local IN SOA squid . test . local . root . test . local . ( 200110230 ; serial 28800 ; refresh ( 8 hours ) 7200 ; retry ( 2 hours ) 2419200 ; expire ( 4 weeks ) 86400 ; minimum ( 1 day ) ) NS squid . test . local . $ORIGIN _msdcs . test . local .
файл _sites.test.local
$ORIGIN . $TTL 86400 ; 1 day _sites . test . local IN SOA squid . test . local . root . test . local . ( 200110223 ; serial 28800 ; refresh ( 8 hours ) 7200 ; retry ( 2 hours ) 2419200 ; expire ( 4 weeks ) 86400 ; minimum ( 1 day ) ) NS squid . test . local . $ORIGIN _tcp .Default- First - Site - Name . _sites . test . local .
файл _tcp.test.local
$ORIGIN . $TTL 86400 ; 1 day _tcp . test . local IN SOA squid . test . local . root . test . local . ( 200110224 ; serial 28800 ; refresh ( 8 hours ) 7200 ; retry ( 2 hours ) 2419200 ; expire ( 4 weeks ) 86400 ; minimum ( 1 day ) ) NS squid . test . local . $ORIGIN _tcp . test . local .
файл _udp.test.local
$ORIGIN . $TTL 86400 ; 1 day _udp . test . local IN SOA squid . test . local . root . test . local . ( 200110222 ; serial 28800 ; refresh ( 8 hours ) 7200 ; retry ( 2 hours ) 2419200 ; expire ( 4 weeks ) 86400 ; minimum ( 1 day ) ) NS squid . test . local . $ORIGIN _udp . test . local .
файл DomainDnsZones.test.local
$ORIGIN . $TTL 86400 ; 1 day DomainDnsZones . test . local IN SOA squid . test . local . root . test . local .( 200110220 ; serial 28800 ; refresh ( 8 hours ) 7200 ; retry ( 2 hours ) 2419200 ; expire ( 4 weeks ) 86400 ; minimum ( 1 day ) ) NS squid . test . local . $ORIGIN DomainDnsZones . test . local .
файл DomainDnsZones.test.local
$ORIGIN . $TTL 86400 ; 1 day ForestDnsZones . test . local IN SOA squid . test . local . root . test . local .( 200110220 ; serial 28800 ; refresh ( 8 hours ) 7200 ; retry ( 2 hours ) 2419200 ; expire ( 4 weeks ) 86400 ; minimum ( 1 day ) ) NS squid . test . local . $ORIGIN ForestDnsZones . test . local .
Проверям, что владельцем всех файлов в каталоге dynamic является bind #chown bind * и делаем BIND-у рестарт #/etc/rc.d/named restart И бежим смотреть в логи:
Jul 16 14:27:31 squid named[1182]: starting BIND 9.3.4-P1 -t /var/named -u bind Jul 16 14:27:31 squid named[1182]: zone 'test.local' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: zone '10.168.192.in-addr.arpa' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: zone '_msdcs.test.local' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: zone '_sites.test.local' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: zone '_tcp.test.local' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: zone '_udp.test.local' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: zone 'DomainDnsZones.test.local' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: zone 'ForestDnsZones.test.local' allows updates by IP address, which is insecure Jul 16 14:27:31 squid named[1182]: command channel listening on 192.168.10.1#953 Jul 16 14:27:32 squid named[1182]: running
Как и ожидалось есть ругань в сторону безопасности, но в целом все путём и BIND готов. Теперь можно поднимать Active Directory. Мастер dcpromo на определенном этапе проверит указанный ему DNS и никаких изъянов в нем не обнаружит :) Через некоторое время в папке dynamic появятся файлы *.jnl (логи BIND), а еще через некоторое время в файлах зон появятся записи навроде этих:
$TTL 600 ; 10 minutes c17a065c-5d3c-40dc-97e8-234a6d973edb CNAME t-server.test.local. $ORIGIN _tcp.Default-First-Site-Name._sites.dc._msdcs.test.local. _kerberos SRV 0 100 88 t-server.test.local. _ldap SRV 0 100 389 t-server.test.local. $ORIGIN _tcp.dc._msdcs.test.local. _kerberos SRV 0 100 88 t-server.test.local. _ldap SRV 0 100 389 t-server.test.local. $ORIGIN _msdcs.test.local. _ldap._tcp.77b49ee2-e89c-43a7-b609-6161feeef8e5.domains SRV 0 100 389 t-server.test.local. gc A 192.168.10.10 $ORIGIN gc._msdcs.test.local. _ldap._tcp.Default-First-Site-Name._sites SRV 0 100 3268 t-server.test.local. _ldap._tcp SRV 0 100 3268 t-server.test.local. $ORIGIN _msdcs.test.local. _ldap._tcp.pdc SRV 0 100 389 t-server.test.local.
Вот собственно и все :).4. Заключение. Не смотря на то, что с BIND проблему решить удалось, я все таки остался недоволен всей схемой решения в целом. Ну не люблю я, образно говоря, ковырять в зубах спичкой, если под рукой есть зубочистка :) Это я про то, что proxy-сервер в моем понимании должен заниматься ПРОКСИРОВАНИЕМ, а не контролем доступа или квотированием трафика. Есть для этого гораздо более удобные и функциональные инструменты, как, например, уже упомянутые выше NetAMS и IPFW. Да и само по себе поднятие домена только ради избирательной раздачи Интернета (в случае работы всех пользователей в терминале все можно прекрасно разрулить локальными политиками) - тоже пальба из пушки по воробьям. PS: сейчас я прорабатываю одну схемку, которая позволит мне обойтись без домена, прокси, ntlm аутентификации и всего этого кордебалета. Точнее говоря, будет использована старая добрая схема фильтрации по IP, но с учетом особенности работы в терминале. Если получится - обязательно напишу еще одну статью.