Estou tentando fazer com que um servidor de teste autentique usuários em um LDAP do Servidor de Diretórios 389. Eu instalei o nscd e nslcd, consegui-os trabalhar. Comandos como getent passwd
funcionam bem.
Agora preciso configurar o módulo PAM pam_ldap.so para autenticar usuários. O man ldap_conf
afirma que:
When authenticating or authorizing a user, pam_ldap first maps the user’s login name to a distinguished name by searching the directory server. This must be possible using the local system’s identity, specified in pam_ldap.conf. (Note that presently only simple authentication is supported for authenticating in this initial step.) To authenticate a user, pam_ldap attempts to bind to the directory server using the distinguished name of the user (retrieved previously). Both simple and SASL authentication mechanisms are supported; in the former case, one should take care to use transport security to prevent the user’s password being transmitted in the clear.
No entanto, ao tentar autenticar um usuário, o módulo pam_ldap não executa um BIND em um servidor LDAP para tentar autenticar o usuário.
/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 (tem padrões, deve ser bom porque eu cancelei tudo no 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
...
Com esta configuração, a autenticação funciona bem. A coisa é o servidor vai com a leitura de informações de sombra do usuário do servidor LDAP com o módulo pam_unix (através de nss) - o que efetivamente significa que o módulo lê userPassword fora do LDAP e o compara localmente. Isso é o que eu não quero que aconteça. Ao examinar os logs LDAP (e também no tráfego de rede não criptografado), não há evidências de que o sistema tente fazer uma ligação no usuário que está tentando efetuar login. :
[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
Mesmo reorganizando os módulos PAM, o pam_ldap.so
vai antes de pam_unix.so
não afeta esse comportamento. Estou tentando isso no CentOS 6.8 x86_64 com pam_ldap-185-11.el6.x86_64
, outras bibliotecas:
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
Além disso, a configuração pam.d relevante:
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
Existe alguma maneira de forçar o módulo pam_ldap.so a fazer a ligação LDAP sob o usuário uid=test,ou=people,o=company,c=gb
? Eu entendo que a biblioteca irá primeiro olhar seu DN no LDAP e eu estou perfeitamente bem com isso.
Atualmente estou sem ideias, por isso até as sugestões são bem-vindas. :)