public:linux:pam_ldap

基于 LDAP 的 PAM 验证

Linux 可以通过 PAM (Pluggable Authentication Modules, 可插入认证模块)来提供认证功能,不少系统服务认证是通过 pam 来进行。 pam 的配置文件放在 /etc/pam.d/ 目录下, 其中以 common 开关的配置文件是通用认证,里面通过 pam_unix.so 模块来进行认证,该模块读取 /etc/passwd 、 /etc/shadow 等系统配置信息,做到与系统账号同步。

通过 debian 的 wiki 可以知道,目前有两个包可以实现 pam_ldap 功能的,分别是 libpam-ldaplibpam-ldapd (注意,后面这个包名称后面多了个'd')

其中, 后者(libpam-ldapd)是更新的解决方案,但是前者配置上比较简单。

安装

apt install libpam-ldap

libpam-ldap 相关的几个配置文件:

  • /etc/ldap/ldap.conf (系统级 ldap 配置文件)
  • /etc/pam_ldap.conf

安装完毕后,该包会修改 /etc/pam.d/ 目录下的几个 common 开头的配置文件,加入跟 pam_ldap.so 相关的配置。首先使用 pam_unix.so 进行本地验证,未通过时通过 pam_ldap.so 进行远程验证。

理论上来说,此时应该可以使用 ldap 进行登录,然而在试验中一直报连不上服务器。搜索许久未找到解决方案,遂放弃。

libpam-ldapd 是新的解决方案,它使用 nslcd 作为服务后端,而 nslcd 也是 libnss-ldapd 的服务后端。

安装

apt install libpam-ldapd
 
# 同时会安装 nslcd libnss-ldapd 等包,而且只安装 libnss-ldapd 时也会安装 libpam-ldapd 包。debian 把它们做成了相互依赖。

libpam-ldapd 相关的几个配置文件:

  • /etc/ldap/ldap.conf (系统级 ldap 配置文件)
  • /etc/nslcd.conf (nslcd 配置文件)
  • /etc/nsswitch.conf (nsswitch 配置文件)

同样的,安装完毕后,程序也会修改 /etc/pam.d/ 目录下的几个 common 开头的配置文件,加入跟 pam_ldap.so 相关的配置。不知道该 pam_ldap.so 跟上一个包里的 pam_ldap.so 是不是同一个,不过机制是同样的机制。但是这里还运用到了 NSS

nsswitch (Name Service Switch,名称服务开关)是 linux 系统给各应用实现名称解析的通用框架,名称解析流程为:

应用程序  --> nsswitch(配置文件(查询顺序)) --> 对应库文件 --> 解析库 --> 完成解析

系统级的解析也是通过该框架完成,如 passwd ,在该配置上可以配置从哪里获取 passwd 信息。

这部分配置在安装软件的时候有图形界面进行设置,直接选择 passwd, group, shadow 就行了。

手动修改的话,编辑 /etc/nsswitch.conf

# 在每一项后面加上 ldap 
passwd:         compat ldap
group:          compat ldap
shadow:         compat ldap

该修改的意思是,passwd、group、shadow 除了从对应的文件中获取数据外,还要从 ldap 中获取信息。

在安装软件的时候,这部分会要求填写 uri, base, 和 tls 证书。可以在安装完成后,再进行手动修改。

手动对 /etc/nslcd.conf 进行修改,仅使用以下配置即可(ldap 的配置按自己的需要进行填写):

uid nslcd
gid nslcd
 
# 按需填写
uri ldaps://ldapserver.com
base ou=myou,dc=example,dc=com
base group ou=unix,ou=groups,dc=example,dc=com
 
# 按需填写
binddn CN=test,ou=myou,dc=example,dc=com
bindpw <yourpassword>
 
ssl on
tls_reqcert allow
# 需要先把自定义证书加到系统证书内
tls_cacertfile /etc/ssl/certs/ca-certificates.crt
 
# for map
# 按需填写
filter  passwd  (&(objectClass=user)(objectClass=person)(!(objectClass=computer))(uidNumber=*))
filter  group   (objectClass=group)
filter  shadow  (&(objectClass=user)(objectClass=person)(!(objectClass=computer))(uidNumber=*))
 
map     passwd  uid                sAMAccountName
#map     passwd  homeDirectory      unixHomeDirectory
map     passwd  homeDirectory      "/home/$sAMAccountName"
map     passwd  gecos              displayName
#map     passwd  gidNumber          primaryGroupID
map     passwd  loginShell         "/bin/bash"
 
#map     group   uniqueMember       member
#map     group   gidNumber          primaryGroupID

首先是配置 ldap 的 url、base dn、bind dn、证书等。

后面的 filter 和 map 主要是给 ldap 使用的,filter 指定搜索条件, map 指定属性映射关系。由于这里使用 windows AD ,因此要做相应的属性映射。 (部分unix需要的属性可参考: https://blogs.technet.microsoft.com/activedirectoryua/2016/02/09/identity-management-for-unix-idmu-is-deprecated-in-windows-server/

手动创建或修改文件 /usr/share/pam-configs/mkhomedir ,内容如下:

Name: Create home directory during login
Default: yes
Priority: 900
Session-Type: Additional
Session:
        required        pam_mkhomedir.so umask=0077 skel=/etc/skel

然后运行命令 sudo pam-auth-update 进行更新 pam 即可。

修改完毕后,需要重启服务

systemctl restart nscd
systemctl restart nslcd

getent - get entries from Name Service Switch libraries。 从某个解析库LIB中获的条目。该命令可以检测nsswitch配置是否正确。

使用方式:

getent passwd

该命令从 nsswitch 中获取 passwd 信息。如果配置正确,那么输出的结果除了本地的 passwd 信息外,还会包含 ldap 的账户信息。

(注意,这里能正确输出的前提是,ldap 中相应的 uid 等信息要存在,后续往 ldap 中添加用户,至少要设置 uidNumber gidNumber Loginshell 属性。)

1. getent passwd 明明已经可以获取到用户信息,可是 ssh 就是连不上,报 Failed password 。几经周折,最后发现它还是对文件 /etc/ldap/ldap.conf 有依赖, nslcd.conf 中配置了 ssl on ,而 ldap.conf 中没有配置,因此在实际获取数据时,没有用正确的连接方式,因而获取不到数据。解决方法: 在 ldap.conf 和 nslcd.conf 中都加上 ssl on

2019-11-12 补充: 上面的解决方法不对。真正原因是 nscd 缓存未刷新,重启一下 nscd 服务即可, 命令 service nscd restart。 ldap.conf 里面不需要设置 ssl on 。

  • 最后更改: 2021/06/26 16:23
  • 由 Jinkin Liu