我已经设置了一个 Ubuntu 16.04 openLDAP 服务器,并希望允许 LDAP 用户使用 SSH 本地登录(提交到存储库等)libnss
和pam_ldap.so
。
每次我通过 ssh 登录时,输入密码后就会断开连接并显示消息connection closed by remote host
。
我执行的步骤:
- 安装
slapd
并ldap-utils
在服务器上 - 安装
libnss-ldapd
,libpam-ldapd
并且nslcd
安装在服务器上,因为它也可以作为客户端
LDAP 服务器已设置并且用户身份验证可用于其他几项服务:GitLab、使用另一个 Ubuntu 系统或 Windows 的 LDAP 登录。
ldapsearch -h localhost -b ou=users,dc=example,dc=net -x uid=myuser
返回预期的输出:
dn: cn=My User,ou=users,dc=example,dc=net
cn: xxx
givenName: My User
gidNumber: 502
homeDirectory: /home/users/myuser
sn: User
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: top
uidNumber: 1001
uid: myuser
loginShell: /bin/bash
文件如下所示:
/etc/nsswitch.conf
:
passwd: compat ldap
group: compat ldap
shadow: compat ldap
/etc/pam.d/common-auth
:
auth [success=3 default=ignore] pam_unix.so nullok_secure
auth [success=2 default=ignore] pam_sss.so use_first_pass
auth [success=1 default=ignore] pam_ldap.so minimum_uid=1000 use_first_pass debug
# here's the fallback if no module succeeds
auth requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth required pam_permit.so
/etc/pam.d/common-account
:
account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so
# here's the fallback if no module succeeds
account requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
account required pam_permit.so
# and here are more per-package modules (the "Additional" block)
account sufficient pam_localuser.so
account [default=bad success=ok user_unknown=ignore] pam_sss.so
account [success=ok new_authtok_reqd=done ignore=ignore user_unknown=ignore authinfo_unavail=ignore default=bad] pam_ldap.so minimum_uid=1000
/etc/pam.d/common-password
:
password requisite pam_pwquality.so retry=3
password [success=3 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512
password sufficient pam_sss.so use_authtok
password [success=1 default=ignore] pam_ldap.so minimum_uid=1000 try_first_pass
# here's the fallback if no module succeeds
password requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
password required pam_permit.so
输出自:
$ nslcd -d
nslcd: [8b4567] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: [8b4567] <protocol="ip"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=ipProtocol)(cn=ip))")
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_initialize(ldap://example.net)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_rebind_proc()
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,0)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,0)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,0)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_simple_bind_s("cn=admin,dc=example,dc=net","***") (uri="ldap://example.net")
nslcd: [8b4567] <protocol="ip"> DEBUG: ldap_result(): end of results (0 total)
nslcd: [7b23c6] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: [7b23c6] <passwd="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=posixAccount)(uid=myuser))")
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_initialize(ldap://example.net)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_rebind_proc()
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,0)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,0)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,0)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_simple_bind_s("cn=admin,dc=example,dc=net","***") (uri="ldap://example.net")
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [7b23c6] <passwd="myuser"> DEBUG: ldap_result(): end of results (1 total)
nslcd: [3c9869] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: [3c9869] <passwd="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=posixAccount)(uid=myuser))")
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_initialize(ldap://example.net)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_rebind_proc()
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,0)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,0)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,0)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_simple_bind_s("cn=admin,dc=example,dc=net","***") (uri="ldap://example.net")
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [3c9869] <passwd="myuser"> DEBUG: ldap_result(): end of results (1 total)
nslcd: [334873] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: [334873] <passwd="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=posixAccount)(uid=myuser))")
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_initialize(ldap://example.net)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_rebind_proc()
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,0)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,0)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,0)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_simple_bind_s("cn=admin,dc=example,dc=net","***") (uri="ldap://example.net")
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [334873] <passwd="myuser"> DEBUG: ldap_result(): end of results (1 total)
nslcd: [b0dc51] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: DEBUG: accept() failed (ignored): Resource temporarily unavailable
nslcd: [b0dc51] <authc="myuser"> DEBUG: nslcd_pam_authc("myuser","sshd","***")
nslcd: [b0dc51] <authc="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=posixAccount)(uid=myuser))")
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [b0dc51] <authc="myuser"> DEBUG: myldap_search(base="cn=My User,ou=users,dc=example,dc=net", filter="(objectClass=*)")
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_initialize(ldap://example.net)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_rebind_proc()
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_option(LDAP_OPT_PROTOCOL_VERSION,3)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_option(LDAP_OPT_DEREF,0)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMELIMIT,0)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_option(LDAP_OPT_TIMEOUT,0)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT,0)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_option(LDAP_OPT_REFERRALS,LDAP_OPT_ON)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_set_option(LDAP_OPT_RESTART,LDAP_OPT_ON)
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_sasl_bind("cn=My User,ou=users,dc=example,dc=net","***") (uri="ldap://example.net")
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_unbind()
nslcd: [b0dc51] <authc="myuser"> DEBUG: bind successful
nslcd: [b0dc51] <authc="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=shadowAccount)(uid=myuser))")
nslcd: [b0dc51] <authc="myuser"> DEBUG: ldap_result(): end of results (0 total)
nslcd: [495cff] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: DEBUG: accept() failed (ignored): Resource temporarily unavailable
nslcd: [495cff] <passwd="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=posixAccount)(uid=myuser))")
nslcd: [495cff] <passwd="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [495cff] <passwd="myuser"> DEBUG: ldap_result(): end of results (1 total)
nslcd: [e8944a] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: DEBUG: accept() failed (ignored): Resource temporarily unavailable
nslcd: [e8944a] <passwd="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=posixAccount)(uid=myuser))")
nslcd: [e8944a] <passwd="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [e8944a] <passwd="myuser"> DEBUG: ldap_result(): end of results (1 total)
nslcd: [5558ec] DEBUG: connection from pid=12412 uid=0 gid=0
nslcd: DEBUG: accept() failed (ignored): Resource temporarily unavailable
nslcd: [5558ec] <authz="myuser"> DEBUG: nslcd_pam_authz("myuser","sshd","","192.168.0.1","ssh")
nslcd: [5558ec] <authz="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=posixAccount)(uid=myuser))")
nslcd: [5558ec] <authz="myuser"> DEBUG: ldap_result(): cn=My User,ou=users,dc=example,dc=net
nslcd: [5558ec] <authz="myuser"> DEBUG: myldap_search(base="ou=users,dc=example,dc=net", filter="(&(objectClass=shadowAccount)(uid=myuser))")
nslcd: [5558ec] <authz="myuser"> DEBUG: ldap_result(): end of results (0 total)
看一下 auth.log,结果显示:
sshd[14229]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.0.1 user=myuser
sshd[14229]: pam_ldap(sshd:auth): nslcd authentication; user=myuser
sshd[14229]: pam_ldap(sshd:auth): authentication succeeded
sshd[14229]: Failed password for myuser from 192.168.0.1 port 57734 ssh2
sshd[14229]: fatal: Access denied for user myuser by PAM account configuration [preauth]
在端口 4000 上运行自己的 ssh 守护程序来调试输出:
/usr/sbin/sshd -d -D -p 4000
Connection from 192.168.0.1 port 46728 on 192.168.0.2 port 4000
debug1: Client protocol version 2.0; client software version OpenSSH_7.2p2 Ubuntu-4ubuntu2.4
debug1: match: OpenSSH_7.2p2 Ubuntu-4ubuntu2.4 pat OpenSSH* compat 0x04000000
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4
debug1: permanently_set_uid: 107/65534 [preauth]
debug1: list_hostkey_types: ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256,ssh-ed25519 [preauth]
debug1: SSH2_MSG_KEXINIT sent [preauth]
debug1: SSH2_MSG_KEXINIT received [preauth]
debug1: kex: algorithm: [email protected] [preauth]
debug1: kex: host key algorithm: ecdsa-sha2-nistp256 [preauth]
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none [preauth]
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none [preauth]
debug1: expecting SSH2_MSG_KEX_ECDH_INIT [preauth]
debug1: rekey after 134217728 blocks [preauth]
debug1: SSH2_MSG_NEWKEYS sent [preauth]
debug1: expecting SSH2_MSG_NEWKEYS [preauth]
debug1: rekey after 134217728 blocks [preauth]
debug1: SSH2_MSG_NEWKEYS received [preauth]
debug1: KEX done [preauth]
debug1: userauth-request for user myuser service ssh-connection method none [preauth]
debug1: attempt 0 failures 0 [preauth]
debug1: PAM: initializing for "myuser"
debug1: PAM: setting PAM_RHOST to "192.168.0.1"
debug1: PAM: setting PAM_TTY to "ssh"
debug1: userauth-request for user myuser service ssh-connection method password [preauth]
debug1: attempt 1 failures 0 [preauth]
debug1: PAM: password authentication accepted for myuser
debug1: do_pam_account: called
Failed password for myuser from 192.168.0.1 port 46728 ssh2
Access denied for user myuser by PAM account configuration [preauth]
debug1: do_cleanup [preauth]
debug1: monitor_read_log: child log fd closed
debug1: do_cleanup
debug1: PAM: cleanup
debug1: Killing privsep child 14671
debug1: audit_event: unhandled event 12
我下一步该去哪里?