ИГОРЬ ПОЛЯНСКИЙ
Единая учетная запись для Windows и UNIX
в Active Directory
В данной статье речь пойдет о том, как управлять единой учетной записью пользователя посредством MS Active Directory вне зависимости от того, на какой платформе он работает, будь то Windows или UNIX-подобные системы. Забегая вперед, скажу, что если с Windows-клиентами все ясно, то интеграция с каталогом от Microsoft тем способом, который будет здесь описан, подходит не для всех UNIX-подобных операционных систем. Так уж сложилось – все они разные, да и Active Directory вовсе не идеальная среда для интеграции разнородных систем. Тогда зачем я все это пишу? А за тем, что очень многие организации изначально ориентированы на платформу Windows и в качестве каталога применяют Active Directory, а когда в сети начинает появляться UNIX, то встает вопрос об интеграции, и не всегда хорошие коммерческие решения подходят, либо из-за стоимости, либо в силу других причин. Я изначально рассматривал вариант с ведением второго каталога для UNIX-клиентов на базе OpenLdap, но хотелось все-таки управлять учетными записями из единой точки, а именно из Active Directory, потому что этот каталог широко используется у нас в сети.
Вариант Samba + winbind меня не устраивал, поскольку по роду задач samba вообще не нужна, к тому же это лишние службы на каждой машине, использование которых все-таки не решает проблем с централизованным управлением пользовательскими данными, поэтому это решение мне показалось неразумным и неизящным.
Более всего привлекал вариант с использованием сервера NIS, который входит в продукт, известный как Services For Unix от компании Microsoft и синхронизация записей Active Directory to NIS. Зайдя на microsoft.com в надежде скачать SFU3.5, которая в отличие от предыдущей версии SFU3.0 бесплатна, я набрел на ряд интересных статей, прочитав которые, пошел по другому пути.
Как уже говорилось в начале, не все UNIX-подобные системы могут проходить аутентификацию и запрашивать данные о пользователе в Active Directory описанным здесь способом, а только те, которые умеют работать с PAM и pam-модулями. Как вы, наверное, догадались, я буду описывать способ взаимодействия с ldap-сервером, входящим в Active Directory через модули pam_ldap и nss_ldap.
Итак, начнем. В качестве подопытных будут выступать MS Windows 2000 Server Standart с установленной Active Directory (в дальнейшем AD), Linux Manrdake 10.0, Solaris 9 x86, FreeBSD 4.10. Над Windows 2000/XP опыты ставить бессмысленно – все и так работает. Как минимум понадобится DNS-сервер, который может быть установлен на том же Windows 2000 Server. Свежеустановленная AD не имеет традиционной ldap-схемы для UNIX: userid, grouid, login shell, home directory. Нам нужно её расширить, и для этого я воспользуюсь SFU3.5. Вообще-то существует несколько способов это сделать: вручную создав ldif-файл с нужной схемой и импортировав его при помощи каких-либо программ сторонних разработчиков, например такой, как AD4Unix (www.padl.com/download/MKSADPlugins.msi), или с помощью SFU от Microsoft. Первый способ я оставляю гуру, вышеозначенную программу MKSADPlugins.msi вам установить вряд ли удастся, если Windows 2000 Server работает с альтернативной локалью, отличной от US, что для России уместно. В пользу же SFU, на мой взгляд, говорит то, что она сделана в том же КБ, где Windows и AD, плюс в своем составе имеет много утилит от UNIX.
Пройдя добровольно-принудительную процедуру получения .NET Passport, вы сможете бесплатно скачать и использовать SFU3.5 (www.microsoft.com/windows/sfu). Размер программы примерно 230 Мб. Прежде чем устанавливать SFU, нужно инсталлировать Active Directory Schema MMC snap-in следующей командой:
regsvr32 с:WINNTsystem32schmmgmt.dll
Для расширения схемы AD достаточно установить только NIS-сервер из состава SFU. Для успешного завершения установки необходимо быть либо членом групп Domain Admins и Schema Admins, либо работать с правами Администратора. После установки будет предложено перегрузить машину. NIS-сервер как таковой не понадобится и его можно остановить и благополучно забыть о нём. В свойствах пользователя, группы, компьютера в Active Directory Users and Computers добавится вкладка UNIX Attributes.
Как видите, теперь у каждого пользователя есть атрибуты, применяемые в UNIX-системах. Первое поле «NIS Domain» будет содержать краткую форму имени нашего домена. Этот параметр нужен для службы NIS, и хотя в нашем случае она не применяется, без нее не активируются другие поля. С остальными полями, я думаю, затруднений не возникнет, может быть, за исключением GID. Прежде чем выбрать из этого поля группу, её надо создать или в свойствах уже имеющейся задать UNIX-атрибуты. Проблема с группами заключается в том, что нельзя задать одно и то же имя для пользователя и группы, а в мире UNIX такой подход весьма распространен. В таком случае можно использовать только численное представление, правда, я сомневаюсь, что это хороший выход из создавшейся ситуации. Ещё потребуется создать учетную запись, которая будет применяться для взаимодействия UNIX-машин с ldap-сервером. Это своего рода дыра в безопасности, поэтому сей аккаунт не должен принадлежать кому-либо и доступ к важным ресурсам ему должен быть запрещен. Тем не менее он должен иметь право на поиск объектов в каталоге. На этом этапе вы готовы управлять единой учетной записью при помощи Active Directory.
Переходим к настройке клиентских машин. Я использовал Linux Mandrake 10.0 Official и всё необходимое ПО устанавливал из rpm-пакетов, входивших в состав дистрибутива. Понадобится установить pam_ldap и nss_ldap. После установки этих пакетов нужно отредактировать несколько конфигурационных файлов. Pam_ldap и nss_ldap для настроек используют один и тот же файл ldap.conf. Также нужно будет отредактировать nsswitch.conf и как минимум один файл, находящийся в /etc/pam.d, а именно system-auth. Не забудьте сделать копии оригинальных файлов. Итак, файл ldap.conf должен содержать следующее:
# Базовые настройки, необходимые для подключения к AD. domain, loc и server.domain.loc вы должны изменить
# в соответствии со своими настройками
base dc=domain,dc=loc
scope sub
uri ldap://server.domain.loc
port 389
ldap_version 3
# Тот самый аккаунт, как видите, он был создан в контейнере Users с именем ldap и паролем qwerty
binddn cn=ldap,cn=Users,dc=domain,dc=loc
bindpw qwerty
# Когда вы будете вводить имя пользователя и пароль, будут применяться следующие объекты и атрибуты из AD:
pam_filter objectclass=User
pam_login_attribute sAMAccountName
pam_password ad
# Эти записи нужны для ускорения поиска. Можете их вообще не вставлять. Обратите внимание, все пользователи в этом
# примере хранятся в «Organization Unit –> firma»
nss_base_passwd ou=firma,dc=domain,dc=loc?sub
nss_base_shadow ou=firma,dc=domain,dc=loc?sub
nss_base_group ou=firma,dc=domain,dc=loc?sub
# Эти записи относятся к модулю nss_ldap, преображают объекты и атрибуты AD к виду, принятому в LDAP
nss_map_objectclass posixAccount User
nss_map_objectclass shadowAccount User
nss_map_attribute uid sAMAccountName
nss_map_attribute uidNumber msSFU30UidNumber
nss_map_attribute gidNumber msSFU30GidNumber
nss_map_attribute cn sAMAccountName
nss_map_attribute uniqueMember member
nss_map_attribute homeDirectory msSFU30HomeDirectory
nss_map_attribute loginShell msSFU30LoginShell
nss_map_attribute gecos name
nss_map_objectclass posixGroup Group
Далее на очереди файл nsswitch.conf, тут всё просто – находите строчки:
passwd: files nisplus nis
shadow: files nisplus nis
group: files nisplus nis
и меняете их на:
passwd: files ldap
shadow: files ldap
group: files ldap
Редактируем файл /etc/pam.d/system-auth:
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_unix.so likeauth nullok
auth sufficient /lib/security/pam_ldap.so use_first_pass
auth required pam_deny.so
account required pam_unix.so
account [default=bad success=ok user_unknown=ignore service_err=ignore system_err=ignore] lib/security/pam_ldap.so
password required pam_cracklib.so retry=3 minlen=2 dcredit=0 ucredit=0 ucredit=0
password sufficient pam_unix.so nullok use_authtok md5 shadow
password sufficient /lib/security/pam_ldap.so use_authtok
password required pam_deny.so
session required pam_limits.so
session required pam_unix.so
session required /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022
session optional /lib/security/pam_ldap.so
В этом примере строчки, содержащие модуль pam_ldap.so, были добавлены в соответствии с рекомендациями Microsoft. Суть их такова, что сначала система применяет правила для локального пользователя, если такой учетной записи нет, то информация берется из AD. Но есть одна маленькая проблема, которая может стать большой. Дело в том, что домашний каталог автоматически не создается и по умолчанию таковым считается /. Вам придется создавать домашние каталоги руками на каждой машине, что не очень удобно. Для этого можно использовать модуль pam_mkhomedir. При регистрации в данной системе модуль смотрит, есть ли домашний каталог, если нет, то он его создает и копирует туда файлы из /etc/skel. Вы можете в соответствии со своими требованиями менять и порядок модулей, и их опции для разных служб. В таких перестановках надо быть осторожным, потому как можно прийти к неожиданным результатам вплоть до невозможности регистрироваться в системе даже под учетной записью root. Для начала логично почитать что-нибудь о PAM. После этих манипуляций можно попробовать зарегистрироваться на Linux-машине пользователем, который не упоминается в файлах passwd, shadow, group, но его UNIX-атрибуты присутствуют в AD.
Если всё прошло отлично, то при первом входе среди прочих надписей увидим следующее:
Creating directory "/home/test".
Creating directory "/home/test/tmp".
|
Посмотрим, кем нас считает система:
[test@linux-pc test]$ id
uid=10000(test) gid=10000(testgroup) groups=10000(testgroup) |
Настраиваем Solaris 9 x86. В Solaris есть свои модули pam_ldap и nss_ldap, только вот незадача – они не совсем совместимы с Active Directory, поэтому Microsoft рекомендует использовать модули от PADL (www.padl.com), те же, что применяются в Linux. Чтобы скомпилировать эти модули, потребуется установить ряд GNU-утилит, получить их можно на www.sunfreeware.com. Оглашаю весь список:
- autoconf-2.57-sol9-intel-local.gz
- automake-1.7.2-sol9-intel-local.gz
- gcc-3.2.1-sol9-intel-local.gz
- m4-1.4-sol9-intel-local.gz
- make-3.80-sol9-intel-local.gz
Плюс к этому берем с сайта www.blastwave.org пакет berkeleydb3-3.11-i386-CSW.pkg.gz.
Перед тем как собирать pam_ldap и nss_ldap, создадим символическую ссылку в /usr/local/bin на perl:
ln -s /usr/bin/perl /usr/local/bin/perl
На файлы из каталогов /opt/csw/bin, /opt/csw/lib, /opt/csw/include, созданные в процессе инсталляции berkeleydb3-3.11-i386-CSW.pkg.gz, сделаем символические ссылки в аналогичные каталоги, расположенные в /usr. Сделаем резервную копию оригинальных модулей pam_ldap и nss_ldap:
cp /usr/lib/security/pam_ldap.so.1 /usr/lib/security/pam_ldap.so.1.bak;
cp /usr/lib/nss_ldap.so.1 /usr/lib/nss_ldap.so.1.bak
Объявим переменные среды:
PATH=/usr/local/bin:$PATH
LD_LIBRARY_PATH=/usr/local/lib
export LD_LIBRARY_PATH
Это сработает для оболочек, совместимых по синтаксису с sh, например, bash, ksh. Если вы пользуетесь другим интерпретатором, посмотрите документацию к нему.
Соберем модули от PADL, перейдя в соответствующие директории, созданные в процессе разархивации файлов, полученных с www.padl.com/download:
cd pam_ldap-176
./configure
make
make install
cd nss_ldap-226
./configure --enable-schema-mapping
make
make install
Если все прошло удачно, редактируем ldap.conf и nsswitch.conf аналогично Linux, за исключением строчки:
uri ldap://server.domain.loc
которую заменим на:
host server.domain.loc
Linux воспринимает оба формата, Solaris почему-то только host. Настройки PAM в Solaris хранятся в файле /etc/pam.conf. На этом этапе, следуя советам Microsoft, я получил неработоспособную систему, поэтому кое-что поменял и добавил (представлены фрагменты с внесенными изменениями):
# login service (explicit because of pam_dial_auth)
login auth requisite pam_authtok_get.so.1
login auth required pam_dhkeys.so.1
login auth sufficient pam_unix_auth.so.1
login auth required pam_dial_auth.so.1
login auth sufficient pam_ldap.so.1 use_first_pass
# Default definitions for Authentication management
# Used when service name is not explicitly mentioned for authenctication
other auth requisite pam_authtok_get.so.1
other auth required pam_dhkeys.so.1
other auth sufficient pam_unix_auth.so.1
other auth sufficien pam_ldap.so.1 use_first_pass
# Default definition for Session management
# Used when service name is not explicitly mentioned for session management
other session required pam_unix_session.so.1
other session sufficient pam_mkhomedir.so skel=/etc/skel/ umask=0022
# Default definition for Password management
# Used when service name is not explicitly mentioned for password management
other password required pam_dhkeys.so.1
other password requisite pam_authtok_get.so.1
other password requisite pam_authtok_check.so.1
other password required pam_authtok_store.so.1
other password sufficient pam_ldap.so.1 use_authtok
Здесь смысл примерно такой же, как и в случае с Linux. Pam_mkhomedir для Solaris не существует, но его можно собрать самостоятельно. Я следовал инструкциям на http://keutel.de/pam_mkhomedir и получил работоспособный модуль, проделав следующие шаги на машине с Solaris:
/usr/local/bin/gcc -D_REENTRANT -g -O2 -Wall -fPIC -c -ILinux-PAM-0.77/libpam/include -ILinux-PAM-0.77/libpamc/include
-ILinux-PAM-0.77/modules/pammodutil/include -DPAM_DYNAMIC pam_mkhomedir.c -o pam_mkhomedir.o
- Получил готовый модуль следующей командой:
/usr/ccs/bin/ld -o pam_mkhomedir.so -B dynamic -G -lc pam_mkhomedir.o
К сожалению, FreeBSD 4.x не умеет работать с nss_ldap и значит запрашивать данные о пользователе в AD, плюс не может менять пароль стандартными средствами с помощью pam_ldap. Но всё же доступ к машине, как с консоли, так и к службам ssh, ftp и т. д. можно получить, пройдя аутентификацию в Active Directory. Для этого установите pam_ldap, отредактируйте два файла – ldap.conf и pam.conf. В ldap.conf достаточно внести следующий фрагмент:
base dc=domain,dc=loc
scope sub
uri ldap://server.domain.loc
port 389
ldap_version 3
binddn cn=ldap,cn=Users,dc=domain,dc=loc
bindpw qwerty
pam_filter objectclass=User
pam_login_attribute sAMAccountName
pam_password ad
В этом случае пароль из AD будет запрашиваться при входе с консоли, ftp и ssh, если пароль отвергнут, поиск будет продолжен в локальных файлах.
login auth sufficient /usr/local/lib/pam_ldap.so
login auth sufficient pam_skey.so
login auth sufficient pam_opie.so no_fake_prompts
#login auth requisite pam_opieaccess.so
login auth requisite pam_cleartext_pass_ok.so
#login auth sufficient pam_kerberosIV.so try_first_pass
#login auth sufficient pam_krb5.so try_first_pass
login auth required pam_unix.so try_first_pass
login account required pam_unix.so
login password required pam_permit.so
login session required pam_permit.so
# Same requirement for ftpd as login
ftpd auth sufficient /usr/local/lib/pam_ldap.so
ftpd auth sufficient pam_skey.so
ftpd auth sufficient pam_opie.so no_fake_prompts
#ftpd auth requisite pam_opieaccess.so
ftpd auth requisite pam_cleartext_pass_ok.so
#ftpd auth sufficient pam_kerberosIV.so try_first_pass
#ftpd auth sufficient pam_krb5.so try_first_pass
ftpd auth required pam_unix.so try_first_pass
# OpenSSH with PAM support requires similar modules.
# The session one is a bit strange, though...
sshd auth sufficient /usr/local/lib/pam_ldap.so
sshd auth sufficient pam_skey.so
sshd auth sufficient pam_opie.so no_fake_prompts
#sshd auth requisite pam_opieaccess.so
#sshd auth sufficient pam_kerberosIV.so try_first_pass
#sshd auth sufficient pam_krb5.so try_first_pass
sshd auth required pam_unix.so try_first_pass
sshd account required pam_unix.so
sshd password required pam_permit.so
sshd session required pam_permit.so
Локально пароль можно вообще не хранить. Для этого при помощи команды vipw отредактируйте файл паролей. Сотрите зашифрованный пароль во втором поле и поставьте там * (звёздочка).
По сведениям, взятым на http://www.padl.com/OSS/nss_ldap.html, FreeBSD 5.1 и выше уже работает с nss_ldap, но проверить это лично не удалось по причине отсутствия дистрибутива.
Осталось прикрутить SSL. Хотя это вовсе не обязательно, наверняка вы захотите использовать шифрование по двум причинам. Первая – безопасность, ведь запросы к ldap, в том числе пароли, передаются в открытом виде, вторая – возможность пользователю самому менять пароль в AD посредством стандартной команды passwd. Необходимо проделать некоторые операции, как на Windows-сервере, так и на клиентских машинах.
На сервере:
- Убедиться, что поддерживается шифрование 128 bit, иначе вы не сможете удаленно поменять пароль. Windows 2000 sp2 и выше это умеет, в противном случае установите Encryption pack.
- Установить сервис сертификатов, входящий в дистрибутив. Без этого сервер не будет принимать соединения по протоколу ldaps. В процессе инсталляции сервиса сертификатов будет предложено создать корневой сертификат. Заполнив поля (можно не все), вы получите файл сертификата, лежащий в директории с:. Делать с ним ничего не придется. В журнале событий (event viewer) должна появиться запись о возможности принятия соединений LDAPS (прим.: у меня это сообщение появилось на следующий день, может, потому, что я не перегружал машину, а до этого все попытки коннекта на ldaps:636 терпели неудачу). Проверить, что сервер работает корректно, можно простым способом. С любой Windows-машины в домене или на самом сервере выполните «Start –> Search –> For People».
В свойствах укажите адрес сервера, порт 636, контейнер для поиска.
В данном примере мы ищем объекты в контейнере Users. Если поиск завершился успехом, значит ваш сервер настроен на прием запросов по протоколу LDAPS порт 636.
На клиенте:
Самым простым решением для меня оказалось использование программы stunnel. После установки stunnel нужно поправить два файла stunnel.conf и ldap.conf. Stunnel.conf может выглядеть так:
chroot = /var/tmp/stunnel
pid = /stunnel.pid
setuid = stunnel
setgid = stunnel
# Some debugging stuff
debug = 7
output = /var/log/stunnel.log
# Use it for client mode
client = yes
# Service-level configuration
[ldap]
accept = 127.0.0.1:389
connect = server.domain.loc:636
Из данного примера мы видим – stunnel работает в клиентском режиме, слушает запросы на 127.0.0.1 порт 389 и пересылает их на Windows-сервер порт 636 уже в зашифрованном виде. В зависимости от операционной системы вам придется вручную создать пользователя stunnel и каталог /var/tmp/stunnel с возможностью записи для этого пользователя. В файле ldap.conf просто поменяем строчку:
ri ldap://server.domain.loc
на
host 127.0.0.1
Перегружаем машину, регистрируемся, пробуем менять пароль. Параллельно tcpdump на другом терминале можно наблюдать наши SSL-соединения.
В результате мы имеем централизованную систему управления пользователями средствами Active Directory, что значительно облегчает работу администратора. Интеграция таким способом позволяет внедрить UNIX-системы в существующую структуру Windows-сетей и при этом отказаться от ведения дополнительных каталогов или хранения пользовательских данных на каждой машине.