Я пытаюсь создать один тестовый сервер для аутентификации пользователей по LDAP-серверу 389. Я установил nscd и nslcd, заставил их работать. Команды типа getent passwd
работают просто отлично.
Теперь мне нужно настроить PAM-модуль pam_ldap.so для аутентификации пользователей. man ldap_conf
утверждает, что:
При аутентификации или авторизации пользователя pam_ldap сначала сопоставляет имя пользователя с уникальным именем путем поиска на сервере каталогов. Это должно быть возможно с использованием идентификатора локальной системы, указанного в pam_ldap.conf. (Обратите внимание, что в настоящее время только простая аутентификация поддерживается для аутентификации на этом начальном этапе.) Для аутентификации пользователя pam_ldap пытается привязаться к серверу каталогов, используя отличительное имя пользователя (полученное ранее). Поддерживаются как простые, так и SASL-механизмы аутентификации ; в первом случае следует позаботиться об использовании безопасности на транспорте, чтобы пароль пользователя не передавался в открытом виде.
Однако при попытке аутентификации пользователя модуль pam_ldap не выполняет BIND для сервера LDAP, чтобы попытаться аутентифицировать пользователя.
/etc/nslcd.conf:
# nslcd daemon
uid nslcd
gid ldap
# ldap servers
uri ldaps://127.0.0.1:1636/
uri ldaps://127.0.0.1:1637/
ldap_version 3
# CA certificates for server certificate verification
ssl yes
tls_cacertfile /etc/ca.pem
#TODO: for testing only
tls_reqcert never
# limits
bind_timelimit 30
timelimit 30
idle_timelimit 600
# bind and globals
binddn uid=proxytest,ou=proxies,c=gb
bindpw 123456789
base o=company,c=gb
scope sub
# users
base passwd ou=people,o=company,c=gb
scope passwd sub
filter passwd (objectClass=posixAccount)
# groups
base group ou=group,o=company,c=gb
scope group sub
filter group (objectClass=posixGroup)
/etc/openldap/ldap.conf (имеет значения по умолчанию, это должно быть хорошо, потому что я переопределил все в pam_ldap.conf):
# LDAP Defaults
#
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
#URI ldap://localhost:1389 ldap://localhost:1390
#SIZELIMIT 12
#TIMELIMIT 15
#DEREF never
TLS_CACERTDIR /etc/openldap/certs
/etc/pam_ldap.conf:
# @(#)$Id: ldap.conf,v 1.38 2006/05/15 08:13:31 lukeh Exp $
#
# The man page for this file is pam_ldap(5)
#
# PADL Software
# http://www.padl.com
#
base ou=people,o=company,c=gb
uri ldaps://127.0.0.1:1636/
uri ldaps://127.0.0.1:1637/
ldap_version 3
binddn uid=proxytest,ou=proxies,c=gb
bindpw 123456789
scope sub
timelimit 30
bind_timelimit 30
bind_policy hard
idle_timelimit 600
pam_filter objectclass=posixAccount
pam_login_attribute uid
# Group member attribute
pam_member_attribute memberUid
ssl on
#TODO: for testing only
tls_checkpeer no
# CA certificates for server certificate verification
tls_cacertfile /etc/ca.pem
/etc/nsswitch.conf:
...
passwd: files ldap
shadow: files ldap
group: files ldap
...
При такой конфигурации аутентификация работает просто отлично. Дело в том, что сервер выполняет чтение информации о тенях пользователя с сервера LDAP с помощью модуля pam_unix (через nss), что фактически означает, что модуль считывает userPassword из LDAP и сравнивает его локально. Это то, что я не хочу, чтобы это произошло. При просмотре журналов LDAP (а также о незашифрованном сетевом трафике) нет никаких доказательств того, что система пытается выполнить привязку под пользователем, который пытается войти в систему:
[19/May/2017:15:20:19 +0200] conn=213 op=0 BIND dn="uid=proxytest,ou=proxies,c=gb" method=128 version=3
[19/May/2017:15:20:19 +0200] conn=213 op=0 RESULT err=0 tag=97 nentries=0 etime=0 dn="uid=proxytest,ou=proxies,c=gb"
[19/May/2017:15:20:19 +0200] conn=213 op=1 SRCH base="ou=people,o=company,c=gb" scope=2 filter="(&(objectClass=posixAccount)(uid=test))" attrs="userPassword cn gidNumber uidNumber loginShell objectClass gecos uid homeDirectory"
[19/May/2017:15:20:19 +0200] conn=213 op=1 RESULT err=0 tag=101 nentries=1 etime=0
[19/May/2017:15:20:19 +0200] conn=205 op=12 SRCH base="ou=people,o=company,c=gb" scope=2 filter="(&(objectClass=posixAccount)(uid=test))" attrs="uid"
[19/May/2017:15:20:19 +0200] conn=205 op=12 RESULT err=0 tag=101 nentries=1 etime=0
[19/May/2017:15:20:19 +0200] conn=205 op=13 SRCH base="ou=group,o=company,c=gb" scope=2 filter="(&(objectClass=posixGroup)(|(memberUid=test)(uniqueMember=uid=test,ou=people,o=company,c=gb)))" attrs="cn userPassword memberUid gidNumber uniqueMember"
[19/May/2017:15:20:19 +0200] conn=205 op=13 RESULT err=0 tag=101 nentries=0 etime=0 notes=U
Даже перестановка модулей PAM таким образом, что pam_ldap.so
идет перед pam_unix.so
, не влияет на это поведение. Я пытаюсь это на CentOS 6.8 x86_64 с pam_ldap-185-11.el6.x86_64
, другие библиотеки:
rpm -qa | grep -E "ldap|nss|nscd|nslc"
apr-util-ldap-1.3.9-3.el6_0.1.x86_64
openldap-2.4.40-16.el6.x86_64
pam_ldap-185-11.el6.x86_64
nss-util-3.28.4-1.el6_9.x86_64
nss-sysinit-3.28.4-1.el6_9.x86_64
nss-pam-ldapd-0.7.5-32.el6.x86_64
openldap-clients-2.4.40-16.el6.x86_64
nss-3.28.4-1.el6_9.x86_64
nss-tools-3.28.4-1.el6_9.x86_64
nscd-2.12-1.209.el6_9.1.x86_64
nss-softokn-freebl-3.14.3-23.3.el6_8.x86_64
nss-softokn-3.14.3-23.3.el6_8.x86_64
Также соответствующая конфигурация pam.d:
cat /etc/pam.d/password-auth
#%PAM-1.0
auth required pam_warn.so
auth required pam_env.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth sufficient pam_ldap.so use_first_pass
auth required pam_deny.so
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 500 quiet
account [default=bad success=ok user_unknown=ignore] pam_ldap.so
account required pam_permit.so
password requisite pam_cracklib.so try_first_pass retry=3 type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
session optional pam_ldap.so
Есть ли способ заставить модуль pam_ldap.so выполнить связывание LDAP с помощью uid=test,ou=people,o=company,c=gb
user? Я понимаю, что библиотека сначала будет искать свой DN в LDAP, и я в порядке.
У меня в настоящее время нет идей, поэтому даже советы намекаются. :)