在 openLDAP 服务器上设置 SSH 身份验证

在 openLDAP 服务器上设置 SSH 身份验证

我已经设置了一个 Ubuntu 16.04 openLDAP 服务器,并希望允许 LDAP 用户使用 SSH 本地登录(提交到存储库等)libnsspam_ldap.so

每次我通过 ssh 登录时,输入密码后就会断开连接并显示消息connection closed by remote host

我执行的步骤:

  • 安装slapdldap-utils在服务器上
  • 安装libnss-ldapdlibpam-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

我下一步该去哪里?

相关内容