OpenSSH通过PAM中转实现LDAP认证,需安装SSSD或LDAP客户端工具,配置sssd.conf与PAM策略,并在sshd_config中设置AuthenticationMethods publickey,password以兼顾密钥与密码验证。

OpenSSH 服务端如何加载 LDAP 用户认证模块
OpenSSH 本身不原生支持 LDAP 认证,必须通过 PAM 中转。直接改 sshd_config 加 AuthenticationMethods ldap 会报错——那根本不存在。真实路径是:OpenSSH 调用 PAM,PAM 加载 pam_ldap.so 或 pam_sss.so(推荐后者,更健壮)。
关键动作有三步:
- 确认系统已安装
sssd或libnss-ldapd+libpam-ldapd(Ubuntu/Debian)或sssd-tools+pam_sss(RHEL/CentOS) - 配置
/etc/sssd/sssd.conf指向你的 LDAP 服务器、base DN、TLS 设置,并确保services = nss, pam - 在
/etc/pam.d/sshd中插入auth [success=done default=ignore] pam_sss.so,且位置要在pam_unix.so之前
为什么 ssh 登录时提示 “Permission denied (publickey)” 却没走 LDAP
这是最常踩的坑:OpenSSH 默认开启 PubkeyAuthentication yes,一旦客户端提供了密钥,它就不再触发密码/PAM 流程。LDAP 认证走的是密码验证路径,密钥成功就直接跳过了。
解决办法不是关掉公钥认证,而是让两种方式共存:
- 在
/etc/ssh/sshd_config中设AuthenticationMethods publickey,password(注意顺序:先验密钥,再验密码) - 确保
PasswordAuthentication yes和ChallengeResponseAuthentication yes同时开启 - 重启
sshd后,用ssh -o PubkeyAuthentication=no user@host临时测试 LDAP 密码登录是否生效
SSSD 配置里 binddn 和 ldap_id_use_start_tls 的取舍
LDAP 连接安全性和权限模型直接决定能否查到用户。常见错误是用匿名绑定(bind_dn = ""),但多数企业 LDAP 禁止匿名搜索,结果就是 getpwnam("alice") failed,SSH 登录卡在“用户不存在”。
必须显式配置服务账号:
-
bind_dn = cn=sshd-svc,ou=service,dc=example,dc=com(不能写错 OU 层级) -
bind_pw = /etc/sssd/secrets.d/sshd-bind-pw(绝对不要明文写密码) -
ldap_id_use_start_tls = true是底线——除非你敢把密码明文跑在内网裸连上;若用 LDAPS(端口 636),则关掉它并设ldap_uri = ldaps://ldap.example.com/
用户能登录但 home 目录不存在或 shell 被拒绝
SSHD 成功调 PAM 验证后,会调 getpwent 查用户信息。如果 LDAP 条目里没填 homeDirectory 或 loginShell 属性,OpenSSH 就会 fallback 到 /bin/bash 和 /home/username,而这个目录大概率没被自动创建。
两个务实解法:
- 在
/etc/sssd/sssd.conf的[domain/EXAMPLE]下加fallback_homedir = /home/%u和default_shell = /bin/bash - 启用
pam_mkhomedir.so:在/etc/pam.d/common-session(Debian)或/etc/pam.d/system-auth(RHEL)中追加session optional pam_mkhomedir.so skel=/etc/skel umask=0022 - 检查 LDAP 用户条目的
objectClass是否含posixAccount,否则 SSSD 根本不认它是“可登录用户”
真正麻烦的永远不是连上 LDAP,而是属性映射没对齐、TLS 证书链不完整、或者 home 目录权限和 SELinux 上下文打架——这些不会报 LDAP 错误,只会静默失败。










