12 июл. 2008 г.

Debian 4.0 Etch + pam_ldap HOWTO

Долго я шел к этому, но дошел ;) и слава богу, что не до ручки, а до решения задачи: авторизации пользователей в системе через pam_ldap в среде Debian. На openSuSE все до безобразия просто, там с помощью YaST'a настройка сервера, создание корня дерева (base DN), заведение пользователя и его последующая аутенфикация - прошли сразу, быстро и без проблем. С дебианом пришлось нехило помучаться.
Затыка была еще в том, что реализация openldap в каждом дистрибутиве несколько отличается, есть разночтения в конфиг-файлах. И в Сети достаточно подробного и, главное, соотвествующего Debian 4 etch how-to я не нашел. Поэтому пришлось собирать инфу из разнозенных источников, ну и читать официальную документацию. Но, это все в прошлом, и сейчас кратко обо всех необходимых действиях, требуемых для решения поствленной задачи.
Первым делом нам поднадобится сервер OpenLDAP, обслуживаемый демоном slapd. Для общения ОС с деревом LDAP (точнее, для "трансляции" имен) потребуется libnss-ldap (Name Switch Service, если мне память не изменяет). Для реализации самой аутенфикации пользователя в системе неоходим PAM-модуль libpam-ldap.
apt-get install slapd libnss-ldap libpam-ldap
Если сразу после установки пакетов debconf не предложил их сконфигурировать, сделаем это самостоятельно. Сие избавит от ручного редактирования конфиг-файлов.
dpkg-reconfigure slapd libnss-ldap libpam-ldap
Сначала настраивается slapd.
На вопрос о пропуске конфигурирования OpenLDAP отвечаем отрицательно. В следующем окне вводим baseDN (Distinguish Name), говоря по-русски, уникальное имя, то есть как будет называется корень нашего будущего LDAP дерева - например inspire.hvn в моем случае. Сие в LDAP форме запишется как dc=inspire,dc=hvn (в будущем пригодится). Нажав ентер, получаем запрос ввести имя компании - тут свобода фантации, например, Roga&Kopyta Inc. ;) Далее вводим пароль записи - cn=admin,dc=inspire,dc=hvn, то есть админской учетки для работы с базой. После этого следует небольшой экскурс по сабжу выбора формата базы LDAP - BDB или HDB. Жмем ОК и выбираем BDB, согласившись с доводами разработчиков (однако пробовал и HDB, никаких проблем). Двигаемся дальше, "Удалять базу при вычистке slapd" - у нас там все равно ничего нет, так что пусь делит ;), LDAPv2 включать не нужно, все будет на LDAPv3. Далее видим в консоли сообщения о том что debconf создает /var/lib/ldap, помещает туда базу, запускет демон slapd.
Плавно перетекаем к настройке libnss-ldap...
Универсальный идентификатор ресурса (URI) - это адрес LDAP-сервера, куда nss будет обращаться за информацией. В нашем случае, когда сервер и клиент находятся на одной машине, эта строчка имеет вид ldap://127.0.0.1. В следующем окне нужно ввести уникальное имя базы поиска (base DN) - то же, что и при настройке slapd, но уже в полном, ldif формате, а именно dc=inspire,dc=hvn. Версия третья. Далее - наша база будет требовать учетное имя для входа - нет, спецпривилегии для root-пользователя - да. В следующем окне соглашаемся с проверкой и принудительной установкой прав 0600 на конфигурационный и secret (там пароль записи rootbinddn хранится) файлы libnss-ldap во имя секурности, ибо пароли там находятся в открытом виде. Здесь стоит отметить, что такое положение дел не есть секурно, поэтому вообще говоря, далее мастер предложит ввести название учетной записи, которой будет позволено лишь читать пароли, но непозволено их изменять. При таком раскладе нужно будет подредактировать вручную slapd.conf, где описываюся access-опции для всех категорий пользователей. Имхо же, если вы не страдаете паранойей, то это не так и нужно. В этом описании я все права делегирую лишь пользователю cn=admin (более того, он уже создан, еще в самом начале, и необходимые права для чтения/записи в каталоге LDAP у него уже есть). Поэтому, когда в следующем окне нас просят завести учетку для хождения libnss к LDAP, предлагаемого конфигуратором cn=manager шлем в лес и пишем cn=admin,dc=inspire,dc=hvn, ну и пароль соответственный. Затем инсталлер предлагает отредактировать nsswitch.conf - правда кнопки отказа все рно нет, так что давим ОК. Кстати, как окажется в будущем, предложение отредактировать файл было действительно лишь предложением, никаких действий в нем конфигуратор не произвел, но к этому мы вернемся ниже.
Переходим к настройке libpam-ldap. Практически все шаги аналогичны предыдущей настройке, поэтому кратко: URI - ldap://127.0.0.1, корень базы поиска - dc=inspire,dc=hvn, версия LDAP - 3. На следующий вопрос о root-пользователе базы - да, требование учетного имени - нет. Далее вводим DN для суперюзера базы, я опять же не завожу отдельного пользователя, а отдаю все на откуп cn=admin,dc=inspire,dc=hvn по вышеописанным соображениям. На вопрос о методе шифрования пароля выбираем crypt, как наиболее удобный и совместимый (по крайнй мере, я где-то так вычитал, хотя уверен, что выбор метода на работоспособность системы не сказывается) с unix-шифрованием метод. Конфигурация завершена. Теперь наша лдап база имеет корневую запись dc=inspire,dc=hvn, а так же запись админа cn=admin,dc=inpire,dc=hvn. Сделаем две ou (organizationUnit) записи - ou=people - там будут пользователи, и ou=groups - в ней будут описаны группы, в которые те или иные пиплы будут входить. Так как пока у нас ничего графического под рукой нет, пользуемся консолью и утилитой ldapadd из пакета ldapscripts, который, если не был поставлен как зависимость основных ldap-пакетов, нужно инсталить отдельно.
apt-get install ldapscripts
Создадим файлик следующего содержания (в нем мы опишем в ldif-формате желаемые записи):
dn: ou=people,dc=inspire,dc=hvn
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=inspire,dc=hvn
objectClass: organizationalUnit
ou: groups

dn: cn=testgroup,ou=groups,dc=inspire,dc=hvn
objectClass: posixGroup
cn: testgroup
gidNumber: 10001

dn: uid=test,ou=people,dc=inspire,dc=hvn
objectClass: inetOrgPerson
objectClass: posixAccount
uid: test
sn: test
givenName: TestUser
cn: test
displayName: test
uidNumber: 1050
gidNumber: 10001
userPassword: 123456
loginShell: /bin/bash
homeDirectory: /home/test
Сразу скажу по поводу паролей. Их можно передавать как в открытом виде (для тестовой записи вполне сойдет), так и зашифрованном. Как передашь, так и будет храниться в базе. Если plaintext по параноидальным соображениям не подходит, воспользоваться утилой slappasswd. К примеру наш тестовый пароль можно сделать таким:
slappasswd -h '{CRYPT}' -s 123456
{CRYPT}EvOKngmsHj6CA
или таким:
slappasswd -h '{MD5}' -s 123456
{MD5}4QrcOUm6Wau+VuBX8g+IPg==
Подробности - в man slappasswd. Полученную строку вполне можно запихать в наш текстовый файл.
Итак, добавим в наше дерево новые записи
ldapadd -D cn=admin,dc=inspire,dc=hvn -x -w 123321 -f /home/delayer/add.ldif adding new entry "ou=people,dc=inspire,dc=hvn"
adding new entry "ou=groups,dc=inspire,dc=hvn"
adding new entry "cn=testgroup,ou=groups,dc=inspire,dc=hvn"
adding new entry "uid=test,ou=people,dc=inspire,dc=hvn"
Опции ldapadd можно глянуть в man'е.
Перезапускаем сервер,
/etc/init.d/slapd restart
ищем нашего test'a
id test
id: test: Такого пользователя нет
Жаль... это значит что база LDAP не контактирует с системной... то есть PAM также не знает о таком пользователе... Соответственно, никто его и не авторизует. Это значит, что почему-то debconf в самом начале ничего не сделал c /etc/nsswich.conf (вот мы к нему и вернулись). Сделаем самостоятельно. Открываем его любимым текстовым редактором (фу, ну что за фраза избитая...), ищем строки passwd: group: shadow: и меняем их следующим образом:
passwd: files ldap
group: files ldap
shadow: files ldap
UPD:
/etc/init.d/nscd restart
Снова ищем test'a:
id test
uid=1050(test) gid=10001(testgroup) группы=10001(testgroup)
Уже лучше, не правда ли ;)
Остался последний штрих для достижения нашей цели - конфигурационные файлы в /etc/pam.d. В убунтовском репо есть классная чтука - скрипт auth-client-config, который сам изменяет что нужно в этом каталоге для успешной ldap-аутенфикации приходящего пользователя. В дебе почему-то такого пакета нет, видно, админы дебиана должны быть настолько суровы, что знать и делать все руками и vi ). Что ж, сделаем ;) (Хотя можно и просто стянуть да инсталлировать убунтовский пакет, наверняка встал бы без проблем)
Если бегло оглядеть файлы login, su, passwd, ssh и так далее, то, во-первых, по названиям их ясно, за что они отвечают ;), а во-вторых, все они подключают include'ом некоторые из этих файлов - common-auth, common-passwd, common-session и common-account. Их то мы и поправим.
Для достижения нашей цели файлы должны выглядеть так (почему именно так, и что значат нижеследующие символы - милости просим на man странички =):
/etc/pam.d/common-account
account sufficient pam_unix.so
account sufficient pam_ldap.so use_first_pass
account required pam_deny.so

/etc/pam.d/common-auth
auth required pam_env.so
auth sufficient pam_unix.so nullok_secure
auth sufficient pam_ldap.so use_first_pass
auth required pam_deny.so

/etc/pam.d/common-password
password required pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2 retry=3
#если пакет cracklib2 не установлен, то предыдущую опцию следует закомментировать.
password sufficient pam_unix.so nullok md5 shadow use_authtok
password sufficient pam_ldap.so use_first_pass
password required pam_deny.so

/etc/pam.d/common-session
session required pam_limits.so
session required pam_unix.so
session optional pam_ldap.so
session required pam_mkhomedir.so skel=/etc/skel/ umask=0077
#предыдущая опция предназначена для того, чтобы при первом входе ldap-пользователя в систему ему автоматически создавался хоумдир. При ненадобности - камент )
Вот и все, проверим работоспособность.
delayer@interra:/$ su -l test
Password:
Creating directory '/home/test'.
test@interra:~$
В заключение добавлю, что если требуется добавлять много пользователей, и вообще периодически с записями работать, стоит обратить внимание на более наглядные утилиты, например, luma или lam, правда, для работы последнего требуется web-сервер и php5.