目录

基于 LDAP 的 PAM 验证

参考资料:

https://wiki.debian.org/LDAP/PAM

https://wiki.debian.org/LDAP/NSS

https://wiki.samba.org/index.php/Nslcd

https://uit.stanford.edu/service/directory/pam/local-home

https://stackoverflow.com/questions/30725840/active-directory-and-linux-nslcd-binding-without-extending-the-ad-schema

https://blogs.technet.microsoft.com/activedirectoryua/2016/02/09/identity-management-for-unix-idmu-is-deprecated-in-windows-server/

一、前言

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)是更新的解决方案,但是前者配置上比较简单。

二、libpam-ldap (无法调通,放弃,仅做记录)

安装

apt install libpam-ldap

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

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

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

三、libpam-ldapd (可以使用的方案)

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

安装

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

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

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

1. nsswitch 配置

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 中获取信息。

2. nslcd 配置

在安装软件的时候,这部分会要求填写 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/

3. 配置登录后自动创建 home 目录

手动创建或修改文件 /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 即可。

4. 重启服务

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

systemctl restart nscd
systemctl restart nslcd

5. 使用 getent 命令验证配置是否正确

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 。