Книги, научные публикации

1 LDAP Start Москва октябрь-декабрь 2006 Алексей Барабанов.

Размещение пользовательских бюджетов в LDAP.

Эта тема имеет столько способов реализации, сколько авторов. Но типичные ошибки повторяются от раза к разу. Попробуем построить среду для хранения пользовательских бюджетов в LDAP оптимальным образом.

Считается, что в данном вопросе уже нет ничего неясного. Счет вариантов настройки, предлагаемых, например, на www.opennet.ru, давно уже идет на десятки. Все авторы торопливо пробегают базовые элементы установок сервера и клиента и с триумфом подают главное блюдо - настройку приложений для работы с LDAP. Но, хотя приложения меняются, но именно основные настройки, копируемые авторами друг у друга, содержат спорные решения, которые никто и не пытается совершенствовать. Не говоря уже о том, что в базовых настройках надо выдержать тот минимум управляющих директив, который ни на йоту не уменьшит безопасность системы, основанной на LDAP, и, одновременно, не будет содержать каких-либо излишеств.

Рассмотрим все это подробнее. В качестве рабочей среды выберем openSUSE 10.1 и 10.2, и будем использовать все пакеты, в них включенные. Например, под LDAP далее станем понимать реализацию OpenLDAP, поставляемую в указанных дистрибутивах, а именно openldap2-2.3.19-18.10 для openSUSE 10.1 и openldap2-2.3.27-25 для openSUSE 10.2. Если нет возможности или желания мигрировать в SUSE, тем не менее, можно воспользоваться описанием, потому что во всех современных дистрибутивах LDAP настраивается примерно одинаково с учетом поправок на состав утилит. Для сравнения предлагаю обратиться к одному из самых светлых документов на эту тему [1]. Светлых потому, что это руководство принадлежит к тому небольшому числу работ, где видно, что авторы очень хорошо понимают, о чем идет речь. Но и их мы тоже немножечко по ходу изложения поправим.

Определим исходное состояние. Предположим, что уже выполнена базовая установка openSUSE. В качестве аутентификационной базы используются стандартные файлы с парольными хешами, что собственно является единственно возможным решением при инсталляции изолированной системы. И вот с этого места начнем работу.

Зачем нужен LDAP.

Или, точнее, без чего он не нужен! Это не праздный вопрос. Многие понимают LDAP как дополнительное хранилище бюджетов виртуальных пользователей. Часто этим увлекаются разработчики почтовых серверов. В какой-то степени это верно. LDAP - это, в сущности, простая база данных весьма причудливого формата. Но в рассматриваемом случае предполагается в ней хранить бюджеты пользователей. Так в чем преимущество перед традиционной средой хранения учетных записей? В скорости? Нет! Первое преимущество в том, что в такой базе можно разместить дополнительную информацию, связанную с теми же пользовательскими бюджетами. Например, такая информация необходима для работы Samba.

И второе преимущество - так как LDAP является сетевым сервисом, то с его помощью можно создать масштабируемую среду аутентификации и авторизации (далее АиА) пользователей. Но так как LDAP сам по себе не может функционировать, поскольку даже его 2 LDAP Start запуск происходит под контролем традиционной файловой системы АиА, то настройки подобной службы должны удовлетворять ряду требований.

Во-первых, LDAP должен хранить всю необходимую информацию о бюджетах, которая используется в системе и в процессах аутентификации и авторизации. Это значит, что все поля файловой базы бюджетов следует повторить и в LDAP как минимум.

Во-вторых, функциональное расширение LDAP должно предоставляться системным службам прозрачным образом. То есть после подключения LDAP ранее определенные бюджеты останутся действующими и к ним добавятся новые, размещенные в LDAP. И все подсистемы, использующие службы АиА, не заметив подмены, будут получать информацию о бюджетах, как хранимых в LDAP, так и размещенных в файловой базе аутентификации.

В-третьих, использование LDAP не должно привести ни к снижению надежности, ни к снижению безопасности. Иначе говоря, если по какой-нибудь причине произойдет отказ системы АиА в той её части, что обеспечивается за счет LDAP, то файловая система АиА должна работать, как и прежде, и, тем самым, обеспечить аварийный режим для восстановления функциональности в полном объеме.

И, в-четвертых, подключение LDAP не должно привести к изменению процедуры работы с пользовательскими бюджетами. То есть, в управлении такой композитной базой бюджетов будут задействованы стандартные утилиты, предназначенные для работы с обычными бюджетами, размещенными в файловой базе АиА.

Только соблюдение всех перечисленных условий позволит утверждать, что подключение LDAP может привести к расширению функциональности, увеличению масштабируемости и всем прочим 24-м удовольствиям, приписываемым этому подходу. В противном случае, LDAP так и останется чужеродным элементом, обслуживающим сиюминутный каприз системного администратора, решившегося на малообоснованную авантюру.

Теперь, после того как известна и отправная точка, и цель работы, можно приступить к настройке серверной части.

Установка сервера OpenLDAP.

На этом этапе надо убедиться, что все необходимые для работы пакеты установлены в систему. Это можно сделать следующим образом:

# L="" ;

\ P="openldap2 openldap2-client samba-client samba smbldap-tool perl-ldap nss_ldap pam_ldap" ;

\ for i in $P ;

\ do rpm -qa | grep $i || L="$L $i" ;

done ;

\ [ -z "$L" ] || echo yast2 -i $L Если что-то не будет найдено, то запустится YaST для установки недостающих пакетов и тех, что связаны с ними зависимостями. К сожалению, на доступном сейчас openSUSE GM 10. нет пока smbldap-tools, и это пакет придется заимствовать из дистрибутива openSUSE версии 10.1 и доставить ортодоксальным способом rpm -ivh....

Все команды, приведенные в статье, специально адаптированы так, чтобы было удобно их использовать для автоматического построения среды хранения бюджетов в LDAP. Команды и скрипты параметризованы и все переменные вынесены в начало текстов, то есть все 3 LDAP Start подготовлено для объединения их в единый сценарий. Вы сами можете построить таковой на основе предлагаемых материалов.

Итак, понадобится openldap2 и его клиент, библиотеки и модули для настройки работы системной АиА на основе LDAP - nss_ldap, pam_ldap, и samba3 вместе с парой дополнительных пакетов, которые упростят настройку самой базы LDAP и обеспечат дальнейшую интеграцию с samba. Perl-ldap необходим для smbldap-tools.

Бывает так, что ситуация имеет прямо противоположный характер, то есть уже есть и как-то работает LDAP с настройками, которые следует изменить. Тогда надо остановить процесс slapd и удалить старую базу из /var/lib/ldap:

# rcldap stop # I=/var/lib/ldap ;

\ for i in $(ls -1 $I | grep -v ^DB_CONFIG) ;

\ do rm -f $I/$i ;

done Кстати, то же самое можно сделать, если что-то не понравится после установки, выполненной по рекомендациям настоящей статьи.

Теперь все готово к настройке. Все используемые сервером конфигурационные файлы лежат в /etc/openldap. Здесь самое время вспомнить о первом требовании к хранилищу бюджетов.

Используемая в АиА база данных должна содержать все необходимые для работы поля. То есть надо в перечне включаемых схем указать те, что содержат требуемые структуры.

Прежде всего, core.schema и cosine.schema - это минимум-миниморум для работы LDAP, на определения этих схем ссылаются практически все остальные. Далее rfc2307bis.schema, которая, собственно, содержит определения для класса posixAccount, содержащего эквиваленты всем используемым в стандартной АиА полям. Эта схема пришла на смену ранее используемой nis.schema. Затем то, что позволит добавить дополнительные данные к определениям бюджетов - inetorgperson.schema. Немного полезного для работы почтового сервера - misc.schema. И, наконец, поместим в базу поля, требуемые для работы samba3 - samba3.schema, так как далее это позволит с помощью smbldap-tools провести инициализацию базы. Конечно же, все подключенные схемы должны быть доступны в момент старта сервера, например, размещены в /etc/openldap/schema или в другом месте, что, конечно же, должно быть отражено в файле конфигурации сервера.

На данном этапе надо принять соглашение о корне используемой базы. Так называемый суффикс. Поскольку база LDAP имеет древовидную структуру, то все размещенные внутри её объекты будут размещаться ниже по дереву LDAP, и их отличительные имена будут включать путь от объекта до корня последовательно и завершаться самим корнем, как суффиксом (Рисунок 1). Корень может иметь совершенно произвольное название. Но надо хоть приблизительно прогнозировать дальнейшую судьбу создаваемой базы и учитывать окружение, в котором будут использоваться данные, которые неизбежно в такой базе станут скапливаться. Практически верным следует считать правило выбирать в качестве корня искусственно придуманное имя внутреннего домена. Единственно, это имя должно быть уникальным внутри локальной системы и не иметь аналогов за ее пределами примерно так же, как и всякий внутренний домен DNS не должен пересекаться с внешними, чтобы не маскировать их. Например, очень удобно выбрать для построения корня имя office.localnet.

Тогда суффиксом будет dc=office,dc=localnet. Некоторыми источниками, особенно описывающими настройку ActiveDirectory, куда LDAP входит как составная часть, предлагается использовать в качестве суффикса реальный домен Интернета, например 4 LDAP Start почтовый - kontora.ru. Это совершенно не верно. Внутренняя среда, определяемая значением корня, должна быть искусственно изолированной от внешней, а все пути трансляции прямо указываться и контролироваться. Такое построение исключит случайности и строго ограничит контакты, что увеличит безопасность внутренней системы. Никаких проблем с приемом почты или с резолвингом доменных имен в таком случае не возникнет. Напротив, предотвратит случайное их пересечение, которое может создать трудно устраняемые ошибки.

Рисунок 1. Структура дерева LDAP.

Для разграничения доступа к полям базы LDAP используются специально заданные правила.

Эти правила, так же как и права доступа к файлам традиционной системы АиА, таким как /etc/passwd, /etc/shadow и другим, защищают данные от неправомерного доступа. При этом такая система подразумевает, что определение прав происходит по принадлежности запроса определенному пользователю. То есть сначала пользователь пройдет этап аутентификации, и тогда его запрос будет должным образом авторизован. Но тут заключена логическая проблема. Поскольку сама система LDAP предназначена для использования в механизме АиА, то на начальном этапе, пока база пуста, ни одно заданное правило ограничения доступа не может быть выполнено в принципе. И поэтому, для раскручивания базы LDAP на этапе инициализации используется так называемый rootdn - псевдопользователь, который имеет абсолютный доступ ко всем полям и всем записям базы вне зависимости от настроек ограничений доступа. Существование этого пользователя вшито в бинарные файлы. Его учетную запись не надо специально создавать в базе и его нельзя запретить. Но так как существование подобного абсолютного пользователя является прямым нарушением иерархии разграничения доступа, то есть единственная возможность заблокировать его работу - не указывать его отличительное имя и пароль, чтобы сервер LDAP не смог провести 5 LDAP Start аутентификацию, если даже такой запрос поступит. Но на начальном этапе без rootdn практически не обойтись и пусть его отличительное имя будет cn=ldaproot,dc=office,dc=localnet.

Поскольку, после завершения инициализации rootdn будет заблокирован, то для регулярной работы надо предусмотреть специальные LDAP-бюджеты. Эти бюджеты будут использоваться лишь для организации работы подсистем, запрашивающих данные из базы LDAP, в рамках выделенных для них полномочий. Например, предусмотрим специального искусственного пользователя, от имени которого могут работать утилиты АиА ldapadmin c отличительным именем cn=ldapadmin,dc=office,dc=localnet, которому дадим права читать и изменять все поля базы, включая парольные хеши. Если нужно организовать для какой-то иной подсистемы особый доступ, например позволить службе DHCP беспрепятственно модифицировать отведенную ей часть базы LDAP, то точно также, как и для АиА, надо будет зарегистрировать особого пользователя и дать ему соответствующие права.

Остальные элементы конфигурационного файла сервера LDAP можно взять из шаблона, поставляемого с пакетом. Парольные фразы на данном этапе не имеют значения. Их можно принять самыми простыми и мнемоничными. Пароль rootdn в самом ближайшем времени будет заблокирован, а пароль ldapadmin ничто не помешает в дальнейшем сменить на ходу.

В итоге должно получиться что-то вроде следующего:

# SUFFIX="dc=office,dc=localnet" ;

\ LDAPROOT="ldaproot" ;

\ ROOTDN="cn=$LDAPROOT,$SUFFIX" ;

\ ROOTPW="secret" ;

\ LDAPADMIN="ldapadmin" ;

\ ADMINDN="cn=$LDAPADMIN,$SUFFIX" ;

\ ADMINPW="admin" ;

\ SCHEMA='{SSHA}' ;

\ T=$(slappasswd -s $ROOTPW -h $SCHEMA) ;

\ cat >/etc/openldap/slapd.conf

modulepath /usr/lib/openldap/modules # # ACL's definitions access to attrs=userPassword,userPKCS by self write by dn="$ADMINDN" write by * auth access to attrs=shadowLastChange by self write by dn="$ADMINDN" write by * read access to * 6 LDAP Start by dn="$ADMINDN" write by self write by * read defaultaccess read # # BD's definitions database bdb suffix "$SUFFIX" checkpoint 1024 cachesize rootdn "$ROOTDN" rootpw $T directory /var/lib/ldap # # Indices to maintain index objectClass eq index cn pres,sub,eq index sn pres,sub,eq index uid pres,sub,eq index displayName pres,sub,eq index uidNumber eq index gidNumber eq index memberUid eq index sambaSID eq index sambaPrimaryGroupSID eq index sambaDomainName eq index default sub EOT Приведенные выше команды создадут конфигурационный файл нужного содержания. После чего можно попробовать запустить сам сервер. В openSUSE стартовый скрипт использует параметры из файла /etc/sysconfig/openldap. Настроим их так, чтобы сервер LDAP прослушивал лишь внутренний петлевой интерфейс lo:

# LDAPSERVER=127.0.0.1 ;

\ LDAPPORT=389 ;

\ LDAPINT="$LDAPSERVER:$LDAPPORT" ;

\ I=/etc/sysconfig/openldap ;

\ sed "/^OPENLDAP_LDAP_INTERFACES/c\ OPENLDAP_LDAP_INTERFACES=\"$LDAPINT\"" $I >$I.$$.tmp ;

\ mv $I.$$.tmp $I Такая настройка позволит не заниматься сейчас обеспечением шифрования трафика обмена данными с LDAP, так как это связано с множеством других служб и такими вопросами как создание локального Центра Сертификации, что совершенно не укладывается в тематику статьи.

После настройки /etc/sysconfig/openldap проверим правильность настроек, запустив сервер:

# rcldap start # LDAPSERVER=127.0.0.1 ;

\ LDAPPORT=389 ;

\ LDAPINT="$LDAPSERVER:$LDAPPORT" ;

\ netstat -apn | grep "LISTEN.*slapd" | \ grep $LDAPINT >/dev/null 2>&1 || echo лувы, не работает! Если печальное сообщение не последовало, то можно включать сервер LDAP в режим автоматического запуска chkconfig --add ldap.

В противном случае надо закомментировать строчку loglevel 0, произвести перезапуск LDAP и посмотреть, что является причиной неудачи в протоколе /var/log/messages. После 7 LDAP Start исправления ошибок следует снова вернуть параметр loglevel, так как в противном случае протоколы системы будут просто забиваться огромным числом сообщений от сервера LDAP, участвующем в каждом процессе аутентификации.

Если уровень протоколирования по умолчанию не позволит выяснить проблему, то следует его повысить и обратится к руководствам по OpenLDAP. Но, как уже ранее было сказано, вся последовательность описываемых действий чрезвычайно проста, полностью соответствует документации, автоматизирована и проверена на ряде серверных установок. Иначе говоря, ищите опечатки!

Настройка клиента.

Теперь, когда в системе есть доступный LDAP-сервер, можно приступить к настройке клиентской части. Клиентом будут пользоваться все программы, которым понадобиться информация из базы, хранимой в LDAP. Именно на этом принципе основано свойство масштабирования. Хотя, тогда уже, скорее всего, придется изменить адрес, прослушиваемый сервером LDAP. В нашем же случае важно подчеркнуть, что подстановка клиента производится прозрачным образом за счет использования библиотек, специально созданных для подобной работы. Это позволяет для каждого отдельного хоста настроить клиент на запросы к некоторому, возможно и не локальному, LDAP-серверу так, что все остальные подсистемы этого хоста, запрашивая информацию через указанные библиотеки, будут получать данные из LDAP-сервера в том числе. Конечно, важно, чтобы это были широко используемые библиотеки, а не подсистемы некоторого приложения. В качестве подобных ключевых библиотек, которые настраиваются на получение данных из LDAP, очень выгодно применять nss и pam. Две эти подсистемы практически на 100% позволяют воспользоваться преимуществами LDAP, совершенно не изменяя другие аутентификационные подсистемы, входящие в целевые пакеты, например в courier-imap. Иначе говоря, именно nss и pam далее и будут настраиваться.

В openSUSE библиотеки nss и pam читают свои настройки из одного и того же файла /etc/ldap.conf. Что очевидно, так как они фактически предоставляют информацию одним и тем же программам на разных этапах их работы. Путь к этому файлу зашит в самих библиотеках. Можно проверить его точное значение в системах, где эта истина не очевидна, например для nss:

# strings $(rpm -ql nss_ldap | grep lib) | grep ldap.conf Как и конфигурационный файл сервера, файл настроек клиента также имеет шаблон, которым можно воспользоваться. Ключевыми значениями являются адрес сервера и суффикс базы LDAP. Все остальные строчки заимствуются из стандартного шаблона. Названия контейнеров можно изменять произвольным образом, но так как они являются результатом соглашения разработчиков, то лучше следовать предложенному, и, например, регистрировать учетные записи пользователей в ou=Peolple. Конфигурацию клиента создадим следующим образом:

# LDAPSERVER=127.0.0.1 ;

\ LDAPPORT=389 ;

\ LDAPINT="$LDAPSERVER:$LDAPPORT" ;

\ SUFFIX="dc=office,dc=localnet" ;

\ cat /etc/ldap.conf host $LDAPINT base $SUFFIX # 8 LDAP Start # Don't try forever if the LDAP server is not reacheable bind_policy soft # RFC2307bis naming contexts nss_base_passwd ou=People,$SUFFIX?one nss_base_shadow ou=People,$SUFFIX?one nss_base_group ou=Group,$SUFFIX?one nss_base_hosts ou=Hosts,$SUFFIX?one nss_base_services ou=Services,$SUFFIX?one nss_base_networks ou=Networks,$SUFFIX?one nss_base_protocols ou=Protocols,$SUFFIX?one nss_base_rpc ou=Rpc,$SUFFIX?one nss_base_ethers ou=Ethers,$SUFFIX?one nss_base_netmasks ou=Networks,$SUFFIX?one nss_base_bootparams ou=Ethers,$SUFFIX?one nss_base_aliases ou=Aliases,$SUFFIX?one nss_base_netgroup ou=Netgroup,$SUFFIX?one # attribute/objectclass mapping # Syntax:

nss_map_attribute rfc2307attribute mapped_attribute nss_map_objectclass rfc2307objectclass mapped_objectclass # ldap_version ssl no # # pam pam_password exop pam_filter objectclass=posixAccount pam_login_attribute uid pam_member_attribute memberUid EOT Обращаю внимание - никаких паролей в этом файле не содержится! Всякое упоминание в этом файле специальных пользователей и их паролей свидетельствует о неверной настройке ограничений доступа в LDAP. Часто из-за невозможности работать c установленными правами на объекты базы LDAP от имени обычных пользователей прибегают к использованию или специального пользователя с полными правами на всю базу или, что еще хуже, просто заставляют клиента соединятся с LDAP-сервером как rootdn, все это лишь от нежелания разобраться в сущности происходящего.

Для того чтобы заставить систему обращаться к LDAP в поиске идентификационных данных, настроим службу nss. Эта служба управляется с помощью своего конфигурационного файла /etc/nsswitch.conf, в котором задаются пути поиска информации в системе. После установки там по всем запросам обычно указан поиск в файловых базах.

Надо его немножечко подправить:

# cat $/etc/nsswitch.conf.tmp passwd: compat shadow: files group: compat services: files ldap netgroup: files ldap aliases: files ldap passwd_compat: ldap group_compat: ldap EOT # grep -v "^\(#\|$\|passwd\|shadow\|group\|services\|netgroup\|aliases\)" \ /etc/nsswitch.conf >>/etc/nsswitch.conf.tmp # mv /etc/nsswitch.conf.tmp /etc/nsswitch.conf Вот теперь во всех актуальных для нас путях указано искать еще и в LDAP, а для passwd и group назначен специальный совместимый режим, в котором также добавлен путь поиска в LDAP. Здесь очень важно, что поиск shadow остался только в файловой базе. Это верно, тут нет ошибки. Так как shadow это не просто база, это совершенно конкретный алгоритм 9 LDAP Start хранения хешей. И подменять его на LDAP не следует. Тем более не надо делать такого винегрета - shadow: tcb ldap files nisplus nis, как указано в [1]. Пусть все парольные хеши, что доставляются из shadow, останутся оригинальными. Pam сможет и так воспользоваться хешами из LDAP, а применение nss для доступа к хешам заставит использовать самые простейшие из криптоалгоритмов. Подробнее об этом в [2]. Здесь же подчеркнем, что обязательное существование локальных учетных записей необходимо для обеспечения аварийного режима работы. Надо быть уверенным, что всегда есть активная учетная запись администратора, воспользовавшись которой, можно вмешаться в работу системы в экстренном случае.

На этапе проверки механизмов функционирования nss следует отключить кэширование запросов rcnscd stop. Это позволит проверять работу системы сразу же после ее модификации. В штатном режиме Name Service Cache Daemon будет работать, как следует.

Последнее, что осталось в настройке АиА, - переключить pam в режим работы с LDAP. В openSUSE применяется исключительно оригинальный механизм подключения LDAP в pam.

Вместо традиционного указания порядка и преимущества использования разных источников АиА-информации применяется композитный модуль pam_unix2, который имеет собственный конфигурационный файл. То есть вместо настройки общих системных файлов в /etc/pam.d используется /etc/security/pam_unix2.conf. Кроме неявной политики указания очередности поиска, что очень подробно критикуется в [2], такой подход создает еще и лишнюю точку настройки. Самое смешное, что вплоть до релиза 10.1 pam_unix2 искал свой собственный файл настроек, а вот, начиная с openSUSE 10.2, он уже его не ищет, а снова принимает параметры из традиционных файлов /etc/pam.d. Но для управления ими теперь стала применяться утилита pam-config, которая согласно каким-то своим, прописанным в ее бинарном коде, правилам создает конфигурационные файлы для подсистемы pam. Но и тут не без юмора: эта утилита, которую написал тот же автор, что и pam_unix2 - Thorsten Kukuk, поддерживает pam_unix2.conf, несмотря на то, что сам pam_unix2 уже не имеет этого конфигурационного файла. Изучение исходного текста позволяет узнать, что лишь с целью обратной совместимости. Откровением будет то, что параметр use_ldap для pam_unix2 с помощью этой утилиты не подставить никак. То есть можно предположить, что в самом ближайшем будущем этот ключ пропадет и в самом pam_unix2. Иначе говоря, в SUSE, начиная с версии 10.2, для работы с LDAP предполагается использовать традиционный для остальных дистрибутивов pam_ldap. К сожалению, как и многое в SUSE, это решение не получило грамотного технологического воплощения. Да и вопрос, зачем тогда нужен pam_unix2, если есть опять же традиционный pam_unix, остается открытым.

Итак, для openSUSE 10.1 исправляем настройки pam_unix2 и тем решаем все проблемы:

# cat /etc/security/pam_unix2.conf auth: use_ldap account: use_ldap password: use_ldap session: none EOT Для openSUSE 10.2 можно применить такой же силовой вариант и просто дописать в каждую строку вызова pam_unix2 параметр use_ldap :

#!/bin/sh for i in /etc/pam.d/common-* ;

do [ -L $i ] || { echo $i | grep -v backup$ >/dev/null && { 10 LDAP Start grep "pam_unix2" $i >/dev/null && { sed '/pam_unix2/s/$/use_ldap/' $i >$i.$$.tmp mv $i.$$.tmp $i } } } done Можно еще выполнить pam-config -a Цldap и получить конфигурацию, которая будет почти работоспособной. И даже воспользоваться такой настройкой..., если, точнее когда, будут исправлены описки в pam-config. А пока прибегнем к описанному выше способу с использованием параметра use_ldap, так как нашей целью является создание нужной конфигурации оптимальным путем, а не бесконечное исправление ошибок разработчиков.

Обладатели дистрибутивов, отличных от openSUSE, могут взять вариант настроек pam из [1], опять же с поправкой на особенности включенных в дистрибуцию утилит.

Осталось добавить специальные разделители в те файловые базы, которые, как было указано выше, работают в режиме совместимости (compat):

# grep "^+:::" /etc/passwd >/dev/null || echo "+::::::" >>/etc/passwd # grep "^+:::" /etc/group >/dev/null || echo "+:::" >>/etc/group Все, теперь настройка клиента завершена.

Инициализация базы LDAP.

Как уже было сказано ранее, в этом процессе нам поможет пакет smbldap-tools. Безусловно, можно обойтись и без него. Но так мы сократим работу за счет автоматизации части операций.

Пакет smbldap-tools представляет собой набор программ, которые помогают манипулировать учетными записями, размещенными в LDAP. Все эти программы используют единый конфигурационный файл /etc/smbldap-tools/smbldap.conf, который надо перед началом работы отредактировать или создать заново, что в данном случае проще. Параметры, важные в настройке, определяют сетевой адрес, на котором доступен сервер LDAP, суффикс базы и некоторые параметры, специфичные для PDC, который можно организовать в случае необходимости с помощью samba3 и той базы LDAP, что будет проинициализирована. Кроме уже ранее обсуждавшихся параметров добавились: имя домена NT, имя сервера, почтовый домен (кстати, опять же не имеющий никакого отношения к реально получаемой почте) и так называемый SID, который используется в построении учетных номеров домена NT. Если далее не планируется использовать samba на этом хосте, то все перечисленные параметры можно назначить достаточно произвольно. Итак, сделаем это:

# NT4DOM="Office" ;

\ LDAPSERVER=127.0.0.1 ;

\ LDAPPORT=389 ;

\ SUFFIX="dc=office,dc=localnet" ;

\ NBTNAME="SERVER" ;

\ MAILDOM="office.localnet" ;

\ LOCALSID=$(net getlocalsid | awk 'BEGIN{FS="is: "}{print $2}') ;

\ cat >/etc/smbldap-tools/smbldap.conf

# SUFFIX="dc=office,dc=localnet" ;

\ LDAPADMIN="ldapadmin" ;

\ ADMINDN="cn=$LDAPADMIN,$SUFFIX" ;

\ ADMINPW="admin" ;

\ cat >/etc/smbldap-tools/smbldap_bind.conf

Но если не планируется использовать из smbldal-tools ничего кроме утилиты smbldap populate, то /etc/smbldap-tools/smbldap_bind.conf можно и не настраивать. Или настроить непосредственно перед вызовом, а потом удалить.

Теперь можно воспользоваться инструментарием smbldap-tools для создания ldiff, которым далее проинициализируем базу LDAP:

# I=/tmp/tmp.ldif ;

\ smbldap-populate -e $I -a Administrator -k 0 -m 0 -u 2000 -g 2000 ;

\ sed '/^#/s/#//' $I | sed '/^objectClass: posixGroup/i\ objectClass: nisNetgroup' >init.ldiff ;

\ rm -f $I Все в полученном файле хорошо, кроме того, что ряд записей закомментирован - поправим, уберем комментарий, да еще забыт очень важный для создания групп класс nisNetgroup - поправим, добавим. Полученный файл сохраним. Если что-то еще не устраивает, его можно отредактировать вручную. Рекомендую его обязательно просмотреть и сравнить с тем, что предлагается в [1]. Можно сказать так, в [1] минимальный вариант, а тот, что создает smbldap-populate - предпочтительный.

Вот самый важный момент, после которого номинально LDAP начинает работать - загрузка базы:

# SUFFIX="dc=office,dc=localnet" ;

\ LDAPROOT="ldaproot" ;

\ ROOTDN="cn=$LDAPROOT,$SUFFIX" ;

\ ROOTPW="secret" ;

\ ldapmodify -v -a -D "$ROOTDN" -H ldap://localhost -x -w $ROOTPW -f init.ldiff Таким образом, база проинициализирована, корневой объект LDAP, соответствующий выбранному суффиксу dc=office,dc=localnet, создан, и можно приступить к её наполнению.

Первым делом добавим учетную запись служебного пользователя - администратора LDAP:

# SUFFIX="dc=office,dc=localnet" ;

\ LDAPROOT="ldaproot" ;

\ ROOTDN="cn=$LDAPROOT,$SUFFIX" ;

\ ROOTPW="secret" ;

\ LDAPADMIN="ldapadmin" ;

\ ADMINDN="cn=$LDAPADMIN,$SUFFIX" ;

\ ADMINPW="admin" ;

\ SCHEMA='{SSHA}' ;

\ cat

13 LDAP Start # I=/etc/openldap/slapd.conf ;

\ grep -v "root\(dn\|pw\)" $I >$I.tmp ;

\ mv $I.tmp $I И перезапустить сам LDAP-сервер rcldap restart для того, чтобы изменения вступили в силу. Ну вот, теперь система АиА, использующая LDAP для хранения бюджетов пользователей, практически полностью готова к работе. Практически, да не совсем. Здесь уже возникают соображения совсем нетривиального характера и свойственные, скорее всего, лишь для среды openSUSE. Дело в том, что создание пользовательских бюджетов сопровождается регистрацией в соответствующих группах. При использовании smbldap-tools пользовательские бюджеты будут размещаться в группах, характерных для samba окружения.

А при использовании useradd... будут использоваться те параметры, которые записаны в /etc/default/useradd:

# cat /etc/default/useradd GROUP= HOME=/home INACTIVE=- EXPIRE= SHELL=/bin/bash SKEL=/etc/skel GROUPS=video,dialout CREATE_MAIL_SPOOL=no То есть, согласно этим настройкам, каждый пользователь будет регистрироваться в группах video и dialout. Можно, конечно, их модифицировать, но тогда надо забыть о принципе прозрачности представления сервиса LDAP, не говоря уже о том, что это может создать трудности, поскольку на принадлежности к группам строится традиционная иерархия прав в unix. Значит, указанные группы необходимо тоже разместить в базе LDAP. Чтобы не создавать проблем на будущее, проще ВСЕ группы продублировать в LDAP. Воспользуемся для этого вот таким простеньким скриптом:

#!/bin/bash SUFFIX="dc=office,dc=localnet" LDAPADMIN="ldapadmin" ADMINDN="cn=$LDAPADMIN,$SUFFIX" ADMINPW="admin" cat /etc/group | grep -v ^+ | awk -F: '{print $1, $3}' | while read GNAME GID ;

do cat

Состояние базы LDAP можно посмотреть с помощью утилиты slapcat или через интерфейс консольного клиента:

# SUFFIX="dc=office,dc=localnet" ;

\ 14 LDAP Start LDAPADMIN="ldapadmin" ;

\ ADMINDN="cn=$LDAPADMIN,$SUFFIX" ;

\ ADMINPW="admin" ;

\ ldapsearch -LLL -w "$ADMINPW" -D "$ADMINDN" \ -v -H ldap://localhost -x -b "$SUFFIX" "(objectClass=*)" >dump.ldiff Проверяется работа LDAP с помощью утилиты getent. Эта программа позволяет вывести содержимое любой системной базы из nsswitch.conf так, как она видится системе. В базах passwd и group должны присутствовать объекты, размещенные в LDAP. Например, проверим group:

# getent group | grep video video:x:33:alekseybb video:*:33:

Первая строка из файловой базы, а вторая из LDAP. Иначе говоря, работает!

Использование LDAP.

Ну, вот и подошли к тому, к чему стремились. Теперь попробуем создать пользовательский бюджет так, чтобы запись о нем была произведена в LDAP. Воспользуемся стандартным системным средством useradd. Для сравнения создадим обычный бюджет, зарегистрированный в passwd и shadow:

# useradd -m -c "shadow user" suser # getent passwd | grep suser suser1:x:1001:100:shadow user:/home/suser1:/bin/bash Установим для него некоторый пароль (здесь и далее пароль совпадает с именем пользователя):

# passwd suser Changing password for suser1.

New Password:***** Bad password: too simple Reenter New Password:***** Password changed.

# getent shadow | grep suser suser1:$2a$10$1qqIvf4KcxLU/1RzxYPIiuKhjnohIlZa68fSHGjwiShgcvheuNFli:13495:0:99999:7:::

И проверим, как работает авторизация такого бюджета:

> su - suser1 -c "LC_ALL=C id" Пароль:***** uid=1001(suser1) gid=100(users) groups=16(dialout),33(video),100(users) А теперь попробуем проделать то же самое, но для бюджета, регистрируемого в LDAP:

# useradd -D cn=ldapadmin,dc=office,dc=localnet --service ldap -m -c "ldap user" luser Enter LDAP Password:***** Base DN for user account `luser1' is "ou=People,dc=office,dc=localnet".

LDAP information update failed: Object>

LDAP information update failed: Object>

# getent passwd | grep luser luser1:x:1002:100:ldap user:/home/luser1:/bin/bash 15 LDAP Start Хотя пользователь был зарегистрирован, но не удалось сделать записи о членстве его в дополнительных группах:

# getent group | grep "^\(video\|dialout\)" dialout:x:16:alekseybb,suser video:x:33:alekseybb,suser dialout:*:16:

video:*:33:

И, увы, эта проблема не поддается простому лечению. Секрет в том, что исходные тексты pwdutils, куда входит утилита useradd, модифицированы для использования схемы rfc2307bis, которая заменила схему nis, и, по идее, должна обеспечить POSIX-совместимые атрибуты пользовательских бюджетов. Но вот вместо применяемых в файловых базах индексов в виде номеров GID/UID, автор модификаций, все тот же неутомимый Thorsten Kukuk, решил заменить их на отличительные имена LDAP (то есть поменять индексы на LDAP-ссылки), что делает такую схему несовместимой с ранее принятыми алгоритмами работы с учетными данными пользователей. Можно, конечно, подождать пока все участники процесса разработки договорятся и придут к выводу о том, что каждая схема регистрации должна пользоваться собственными атрибутами, поддерживая определенный уровень совместимости. Но они не договорились ни к выходу openSUSE 10.1, ни к выходу openSUSE 10.2, и я делаю вывод, что рациональнее пересобрать пакет pwdutils, применяя регрессивную заплатку следующего содержания:

# cat pwdutils-3.1.2-memberUid-member.diff --- lib/libldap.c.orig 2006-12-13 07:37:45.000000000 + +++ lib/libldap.c 2006-12-13 07:46:09.000000000 + @@ -1535,12 +1535,12 @@ return 1;

rc = ldap_update_group (session, group, binddn, password, LDAP_MOD_ADD, - "member", dn );

+ "memberUid", member );

free (dn);

if ( first ) { ldap_update_group (session, group, binddn, password, LDAP_MOD_DELETE, - "member", "" );

+ "memberUid", "" );

} } else @@ -1569,11 +1569,11 @@ if ( last ) { ldap_update_group (session, group, binddn, password, LDAP_MOD_ADD, - "member", "" );

+ "memberUid", "" );

} rc = ldap_update_group (session, group, binddn, password, LDAP_MOD_DELETE, - "member", userdn );

+ "memberUid", member );

free (userdn);

} else @@ -2039,13 +2039,13 @@ strvals[0][1] = "groupOfNames";

strvals[0][2] = NULL;

- /* groupOfNames requires at least one "member" attribute + /* groupOfNames requires at least one "memberUid" attribute * use an empty value for groups with no members */ strvals[3][0] = "";

strvals[3][1] = NULL;

16 LDAP Start mod[3].mod_values = strvals[3];

- mod[3].mod_type = "member";

+ mod[3].mod_type = "memberUid";

mod[3].mod_op = LDAP_MOD_ADD;

mods[3] = &mod[3];

mods[4] = NULL;

# Этот патч предназначен для исходных текстов к openSUSE 10.2, но должен подойти и к pwdutils-3.0.7.1-17 из openSUSE 10.1, хотя там проще изменить патч, накладывающий модификацию согласно rfc2703bis. Бинарные сборки модифицированных pwdutils соответствующих версий доступны в [3]. Итак, исправим и пробуем снова:

# userdel -D cn=ldapadmin,dc=office,dc=localnet --service ldap -r luser Enter LDAP Password:***** no crontab for luser # useradd -D cn=ldapadmin,dc=office,dc=localnet --service ldap -m -c "ldap user" luser Enter LDAP Password:***** Base DN for user account `luser1' is "ou=People,dc=office,dc=localnet".

# getent group | grep "^\(video\|dialout\)" dialout:x:16:alekseybb,suser video:x:33:alekseybb,suser dialout:*:16:luser video:*:33:luser Все хорошо. Но не совсем. Возникают трудности с назначением пароля. Поскольку в утилите passwd нет возможности указать, с каким отличительным именем обращаться к LDAP (кстати, вероятно это временное упущение), а в настройках клиента /etc/ldap.conf не заданы параметры принудительной линковки к LDAP, то если пароль не инициализирован, то установить его от суперпользователя никак не получится. Обойти данную проблему можно несколькими путями. Во-первых, у нас в запасе есть smbldap-passwd и, если /etc/smbldap tools/smbldap_bind.conf настроен правильно, то с помощью этой утилиты можно установить пароль любого пользователя, смирившись с тем, что в конфигурационном файле хранится в открытом виде пароль администратора LDAP. Поэтому так делать не будем. Во-вторых, можно установить пароль-заглушку сразу при создании бюджета:

# useradd -D cn=ldapadmin,dc=office,dc=localnet --service ldap \ -p $(slappasswd -s luser2 -h {SSHA} ) -m -c "ldap user" luser Enter LDAP Password:***** Base DN for user account `luser2' is "ou=People,dc=office,dc=localnet".

И в третьих, можно вспомнить про утилиту usermod (кстати, авторы [1] об этом не упоминают, потому что в ALT Linux используется иная версия управляющих утилит), которая позволяет указывать отличительное имя для связи с LDAP:

# usermod -D cn=ldapadmin,dc=office,dc=localnet --service ldap \ -p $(slappasswd -s luser1 -h {SSHA} ) luser Enter LDAP Password:***** Проверяем, что получилось, и обнаруживаем, что бюджет, где пароль, установлен через usermod, недоступен:

alekseybb@suse102:~> su - luser1 -c "LC_ALL=C id" Password:***** Пароль:***** Права доступа на базу данных паролей может быть слишком ограниченная.

su: неправильный пароль 17 LDAP Start А вот тот, что получил пароль при инициализации, прекрасно работает:

alekseybb@suse102:~> su - luser2 -c "LC_ALL=C id" Password:***** uid=1003(luser2) gid=100(users) groups=16(dialout),33(video),100(users) Причина скрывается в формате парольных хешей:

# slapcat | grep "^\(dn\|userPassword\)" | tail -n dn: uid=luser1,ou=People,dc=office,dc=localnet userPassword:: e2NyeXB0fXtTU0hBfS96d0tsREFDak8xa1MxMktrNENKSCsvSTNURVFTSkhZ dn: uid=luser2,ou=People,dc=office,dc=localnet userPassword:: e1NTSEF9eGNtSFRNZC9zTS9WRDd2V2JqWk1tL2phd0lEdFJPc1k= Здесь и простым глазом видно, что с хешами что-то не так, а, приглядевшись внимательнее, понимаем, что хеш из бюджета luser1 имеет неверный формат.

# slapcat | grep "^userPassword" | tail -n 2 | awk '{print $2}' | mimencode -b -u {crypt}{SSHA}/zwKlDACjO1kS12Kk4CJH+/I3TEQSJHY{SSHA}xcmHTMd/sM/VD7vWbjZMm/jawIDtROsY Таким образом, обнаруживается вторая ошибка, исправляемая следующим патчем:

# cat pwdutils-3.1.2-newpassword.diff --- lib/user.c.orig 2006-12-15 02:16:30.000000000 + +++ lib/user.c 2006-12-15 02:18:42.000000000 + @@ -1036,16 +1036,9 @@ } if (data->newpassword) - { - const char *cryptstr = "{crypt}";

- char buffer[strlen (data->newpassword) + - strlen (cryptstr) + 1];

- snprintf (buffer, sizeof (buffer), "%s%s", cryptstr, - data->newpassword);

retval = ldap_update_user (session, data->pw.pw_name, - data->binddn, data->oldclearpwd, - "userPassword", buffer);

- } + data->binddn, data->oldclearpwd, + "userPassword", data->newpassword);

} if (retval != 0) fprintf (stderr, Видно, что в оригинальном коде полученная строка обрабатывалась не как хеш, а как текстовый пароль. Это противоречит документации на утилиту usermod, и вообще непонятно, как попало в код. В архиве [3] содержатся полностью исправленные версии pwdutils. После их установки получаем адекватные записи в LDAP:

# usermod -D cn=ldapadmin,dc=office,dc=localnet --service ldap -e -1 -p $(slappasswd -s luser -h {SSHA} ) luser Enter LDAP Password:***** # slapcat | grep "^\(dn\|userPassword\)" | tail -n dn: uid=luser1,ou=People,dc=office,dc=localnet userPassword:: e1NTSEF9bTY3cGNYYnR3N0xRdEhZNjNlMWpRQmZZakZNSXBNSUQ= dn: uid=luser2,ou=People,dc=office,dc=localnet userPassword:: e1NTSEF9eGNtSFRNZC9zTS9WRDd2V2JqWk1tL2phd0lEdFJPc1k= И, естественно, удачную проверку авторизации:

alekseybb@suse102:~> su - luser1 -c "LC_ALL=C id" 18 LDAP Start Password:***** uid=1002(luser1) gid=100(users) groups=16(dialout),33(video),100(users) alekseybb@suse102:~> Тем самым, ранее поставленную цель, создать полностью совместимую с традиционной схему размещения пользователей в LDAP, можно считать достигнутой. В завершение можно порекомендовать сменить ранее установленный простенький пароль для ldapadmin на что нибудь более существенное, например, так можно поменять его на my.new.pass :

# cat

{SSHA}lZyR2iLrXzijblIE5gBF5UEMMlzMQabk modifying entry "cn=ldapadmin,dc=office,dc=localnet" modify complete Кстати, после этого smbldap-tools перестанут работать, то есть станут не опасными.

Штатный способ настройки в openSUSE.

Можно задаться вопросом, зачем там много настраивать и подкручивать, есть же штатные для openSUSE инструменты, составляющие YaST и позволяющие выполнить все те задачи, что выше были перечислены. Попробуем! Работать будем в openSUSE 10.2, чтобы не натыкаться на давно исправленные ошибки. Запущенное после уже сделанных настроек средство для установки LDAP-сервера приняло установленную конфигурацию, но потребовало вернуть суперпользователя rootdn (Рисунок 2.).

Здесь важно отметить, что никакой другой уровень доступа кроме rootdn автоматического настройщика не устраивает! Предполагаю, что разработчики openSUSE очень не уверены в том, что без rootdn их системы будут работать. Остается лишь гадать, в какой степени это относится к SLES. Кроме того, обратим внимание, что система правильно восприняла тип парольных хешей - SSHA.

После завершения в конфигурационных файлах LDAP ничего не изменилось, кроме того, что был добавлен rootdn:

# grep ^root /etc/openldap/slapd.conf rootdn "cn=ldaproot,dc=office,dc=localnet" rootpw "{ssha}DHToDgxUuvxDwua/SB5Em5zzlABQWVpGVA==" В процессе настройки клиента совсем не удивило, что снова было указано на невозможность работы без задания суперпользователя LDAP (Рисунок 3).

Дальнейшая настройка выполняется если не просто, то очень просто. Не буду ее даже и комментировать. Уже здесь можно отметить, насколько все легко. Хотя, как я уже писал, все перечисленные в статье команды легко связываются в единый скрипт и выполняются вообще без каких-либо дополнительных манипуляций.

19 LDAP Start Рисунок 2. Настройка сервера LDAP.

Будем считать, что все уже настроено. Через средство управления пользовательскими учетными записями создадим дополнительного пользователя luser3, зарегистрированного в LDAP. И проверим, как все работает.

Сначала проверим, что не сломался старый бюджет:

alekseybb@suse102:~> su - luser1 -c "LC_ALL=C id" Пароль:

Права доступа на базу данных паролей может быть слишком ограниченная.

uid=1002(luser1) gid=100(users) groups=16(dialout),33(video),100(users) Да, все работает, но забавно. Кто интересуется, может взглянуть, как нелепо расписаны приоритеты поиска для pam в /etc/pam.d. Но раз работает, то и не будем придираться. Хуже, что проверка свеженького бюджета не проходит:

alekseybb@suse102:~> su - luser3 -c "LC_ALL=C id" su: пользователь luser3 не существует Не верим своим глазам, проверяем внимательнее:

# getent passwd | tail -n luser1:x:1002:100:ldap user:/home/luser1:/bin/bash luser2:x:1003:100:ldap user:/home/luser2:/bin/bash 20 LDAP Start Рисунок 3. Настройка клиента LDAP.

Точно, нет такого пользователя! Может быть в shadow:

# getent shadow | tail -n suser1:$2a$10$1qqIvf4KcxLU/1RzxYPIiuKhjnohIlZa68fSHGjwiShgcvheuNFli:13495:0:99999:7:::

+::0:0:0::::

А там вообще какой-то неадекватный мусор. Хотя, в конфигурации nss, как и прежде:

# grep shadow /etc/nsswitch.conf shadow: files Посмотрим, что в самой базе LDAP:

# slapcat | grep "^\(dn: u\|userP\)" | tail -n dn: uid=luser1,ou=People,dc=office,dc=localnet userPassword:: e1NTSEF9bTY3cGNYYnR3N0xRdEhZNjNlMWpRQmZZakZNSXBNSUQ= dn: uid=luser2,ou=People,dc=office,dc=localnet userPassword:: e1NTSEF9eGNtSFRNZC9zTS9WRDd2V2JqWk1tL2phd0lEdFJPc1k= dn: uid=luser3,dc=office,dc=localnet userPassword:: e2V4b3B9bHVzZXIz Нет слов! Смех переходит в гомерический. Кроме того, что учетная запись luser3 не размещена в нужном контейнере, так у нее еще и какой-то странный хеш. Смотрим, что 21 LDAP Start внутри:

# slapcat | grep "^userP" | tail -n 1 | awk '{print $2}' | mimencode -b -u {exop}luser Ну что тут сказать? Создается впечатление, что разработчики OpenLDAP и YaST проживают на разных планетах, и им как лунатикам с марсианами никак не договориться. Хотя, быть может это моя вина, и я что-то пропустил в настройке? Снова вернемся к настройке клиента (Рисунок 4).

Рисунок 4. Параметры клиента LDAP.

Видим, что контейнер, в котором ищутся, а значит, и размещаются учетные записи пользователей YaST понят правильно. Даже exop правильно интерпретирован. Но в результате получаем нелепицу. Попробуем починить, исправим путь поиска в nss:

# grep passwd /etc/ldap.conf nss_base_passwd dc=office,dc=localnet?sub И сразу же начинаем видеть новичка:

# getent passwd | tail -n luser1:x:1002:100:ldap user:/home/luser1:/bin/bash luser2:x:1003:100:ldap user:/home/luser2:/bin/bash luser3:x:1004:100:Yast ldap user:/home/luser3:/bin/bash 22 LDAP Start Пробуем авторизоваться:

alekseybb@suse102:~> su - luser3 -c "LC_ALL=C id" Пароль:

Права доступа на базу данных паролей может быть слишком ограниченная.

su: неправильный пароль Опять те же грабли! Здесь, лично я делаю вывод, что в команде openSUSE не только Thorsten Kukuk любит пошутить. Юмористов там очень много, и шутки их с увеличением индекса дистрибутива становятся все разнообразнее.

Выводы.

Данная статья может быть использована как практическое руководство в настройке общего пользовательского LDAP-каталога. Но описанное здесь позволяет сделать выводы, как на счет надежности используемых в Linux настроек общесетевых каталогов LDAP, понять, чем озабочены разработчики подобных систем, или напротив - чем они пренебрегают, так и установить недостатки предложенного в силу свойств, присущих LDAP.

Во-первых, описанная схема работает ТОЛЬКО в pwdutils, используемых в openSUSE и еще в PLD. Во многих других, например RHEL, FC, Mandriva, ALT Linux, применяются shadow utils и их модификации. Отличие в том, что pwdutils, которые создал Thorsten Kukuk, позволяют указывать отличительное имя администратора в командной строке, то есть дают работать с административными правами даже в отсутствие параметра rootbinddn в конфигурации клиента LDAP. Это позволяет избежать столь уязвимого указания пароля администратора в текстовой форме в openSUSE и PLD, и приводит к тому, что все остальные дистрибутивные ветки при настройке общесетевого репозитория LDAP вынуждены хранить пароль администратора системы в открытом виде, как минимум, на тех станциях, с которых допускается административное управление каталогом. Что делает использование LDAP менее надежным, чем традиционная схема размещения бюджетных данных, обходящаяся хранением парольных хешей в файлах.

Во-вторых, тот факт, что данная схема реализуется лишь с помощью заплаток, отсутствующих в дистрибутивных версиях pwdutils, свидетельствует о том, что никто и в openSUSE не смущается данными проблемами и, как и ранее, работает через rootbinddn и, даже более, используя в качестве оного rootdn, как, например в [4]. Другими словами, хранение пароля администратора в нешифрованном виде является повсеместной практикой в Linux. Для сравнения, попробуйте найти нешифрованный пароль администратора на сервере или на рабочей станции MS Windows. И опять, приходится признать, что Linux-каталог LDAP существенно менее безопасен, чем аналогичный в MS Windows.

В-третьих, даже использование pwdutils не является достаточно практичным решением, так как требует введения пароля администратора для КАЖДОЙ операции, что не всегда возможно в случае, если эти утилиты используются как основа в обертывающих скриптах.

То есть это проблема by design. Аналогичная проблема возникает при использовании smbldap-tools. Этот инструментарий предназначен для подключения его в качестве внутренних утилит в samba3. И такое их использование исключает в принципе интерактивную фазу, в ходе которой можно задать вопрос администратору о парольной фразе. Что естественным образом приводит к необходимости хранить пароль в месте, 23 LDAP Start доступном для автоматического считывания (в данном конкретном случае пароль записан в конфигурационный файл). То есть, снова приходим к выводу о слабой защищенности практических решений на основе LDAP в Linux.

И вот теперь сделаем самый главный вывод о том, как можно исправить данную ситуацию.

Фактически, вся слабость использования LDAP по сравнению с традиционной формой хранения учетных данных следует из-за невозможности аутентифицировать удаленного привилегированного пользователя на основе сеансовых данных его локальной регистрации.

При использовании локального доступа к учетным данным UID легко проверяется и является надежным критерием для оценки прав доступа. Так как взаимодействие с LDAP происходит по клиент-серверной схеме, то удаленная сторона обязана потребовать аутентификации клиентской части прежде, чем разрешить нужный уровень доступа. И единственное, на мой взгляд, средство, которое позволяет избежать постоянного интерактивного взаимодействия с механизмами аутентификации, это Kerberos. Лишь в случае построения аутентификации на основе Kerberos можно заранее и на определенный срок получить для некоторого локального администратора достаточный уровень прав на удаленный каталог LDAP и использовать данную возможность в неинтерактивных скриптах, запускаемых от упомянутого пользователя.

Итак, LDAP просто обречен на взаимодействие с Kerberos. Именно по этому пути пошли разработчики Microsoft и точно также поступили в Samba Team. Точно также надо делать и в случае любого применения LDAP как хранилища учетных данных. Большинство схем, описывающих иную настройку (источники [4] и [5] не исключение), можно применять лишь в локальных вариантах, и то закрывая глаза на вопросы безопасности. Но симбиоз OpenLDAP и Kerberos заслуживает отдельного рассмотрения. Это значит, продолжение следует...

Ссылки на использованные источники:

1. Настройка OpenLDAP и его клиентов.

2. Барабанов А.Б. LDAP и Все-Все-Все. Черновик версии 2.

3. Исходные тексты и собранные пакеты для настоящей статьи.

4. Как настроить SAMBA в SUSE как PDC с OpenLDAP, DYNDNS и CLAM.

CLAM 5. Настройка OpenLDAP и его клиентов.

   Книги, научные публикации