Overview
SSSD (System Security Services Daemon) 是一套用于远程身份验证的套件服务,为使用SSSD服务的客户端提供了远程访问身份认证服务来获取权限,其后端包括AD, LDAP等,本文将围绕下列方向来阐述SSSD:
- 为什么需要SSSD,以及使用SSSD来解决什么
- 使用SSSD的好处
- SSSD服务工作原理及架构
- 如何在Linux上配置SSSD+LDAP
为什么需要SSSD
SSSD设计主要是为了传统使用身份认证服务,例如PAM+NSS架构中存在的一些问题:
- PAM+NSS扩展性差,并配置较为复杂,尽管提供了
authconfig
,通常在大多数教程中以及不同的系统中配置都不相同 - PAM+NSS不是真正意义上的离线身份认证,如果当
nslcd
或者slapd
等服务异常时,无法完成用户认证 - 以及越来越多的后端,例如LDAP, AD, IPA, IdM,Kerberos等无法做到很好的适配
SSSD就是为了解决上述的问题,对于Linux平台中,SSSD拥有比传统PAM+NSS更好的优势:
- 符合现代Linux基础架构设计需求,可以适配更多的后端,并降低了操作配置的复杂性
- 增加了缓存功能,有效的减少了对于后端服务器的负载
- 因为有了缓存功能,实现了真正的离线认证功能,即使后端服务异常,例如LDAP服务down
了解SSSD架构
了解SSSD架构,其实就是了解前两章的内容,要做到真正的多后端,真脱机,那么服务就有多个组件组成:
- Monitor:所有SSSD的父进程,即用于管理 Providers 与 Responders
- Providers:用于感知验证后端的模块,后端就是提供目录树的一端
- Responders:为Linux提供与后端交互的功能,这部分通常为 NSS PAM sudo等
Providers
- Local:保存在本地缓存中的账户信息
- LDAP, Kerberos, AD,
- IPA :用于 Linux/UNIX 网络环境中集成身份和身份验证解决方案。
- IdM:一种使用本地 Linux 工具在 Linux 系统上创建身份存储、集中身份验证、Kerberos 和 DNS 服务的域控制以及授权策略的目录树后端
- sudo,autofs 与LDAP集成的功能
Responders
- nss:名称解析服务,用于解析组与用户信息
- pam:用于用户验证的模块
- autofs:自动挂载模块,通常用于与LDAP集成,用于映射LDAP目录树
- sudo:linux中用户权限控制,通常也是与LDAP集成
- ssh:
- sssd_be:SSSD的后端进程:其中每一种后端都代表都作为一个sssd_be进程启动
monitor
monitor是SSSD的进程,是用于管理(启动,停止,监控服务状态)Provider与Responders的功能
SSSD工作流程
当每次用户登录,使用 id
, getent
, su
, sudo
等命令时,都会触发一次查询,下图是整个查询的流程
可以看到图中描述了对用户 Alice 进行查询,从调用函数getpwnam
开始,首先会在memcache中检索用户数据,如果检索不到,此时 sssd_nss
(sssd内置的模块)将从本地cache检索,如果此时还是检索不到,那么 sssd_be
(上面提到过一个后端会有一个 sssd_be 进程) 将从远程后端检索。
通过这种模式,增加了缓存功能,有效的减少了对于后端服务器的负载,以及完整的脱机查询功能(即使LDAP服务短暂不可用),而存在的问题则是可能会造成本地资源负载过高,例如这个例子:由于服务器忙时,并且sssd_nss
造成与其他进程争抢资源 [2]
迁移nslcd到sssd
安装sssd
配置SSSD
先决条件:建议使用SSL模式与openldap进行通信,此时数据是加密传输的
默认安装好sssd后,不存在配置文件,需要手动创建配置文件 /etc/sssd/sssd.conf
|
|
复制下列配置到 /etc/sssd/sssd.conf
[sssd]
# sssd全局配置,service为需要使用的模块,这里将会启动一个子进程
# 例如传统的nss+pam作为linux认证的基础,这里开启就为nss,pam
services = nss, pam
config_file_version = 2
# domains作为给后端配置提供的一个名称
domains = default
# 如果需要对每个模块定义的配置可以[<module_name>]进行配置
[pam]
# 成功登录后的用户在sssd中缓存的天数。 如果为0将意味着永久保存。
offline_credentials_expiration = 60
[domain/default]
# 启用tls通讯
ldap_id_use_start_tls = True
# 这个与offline_credentials_expiration进行配合的参数
# 如果true 将在offline_credentials_expiration天后是否查找缓存
# 如果为false,或不填写该参数将不查找
cache_credentials = True
# 搜索的跟域
ldap_search_base = dc=ldapmaster,dc=kifarunix-demo,dc=com
# 下面是一系列provider
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
access_provider = ldap
# ldap相关配置
ldap_uri = ldap://ldapmaster.kifarunix-demo.com
# 搜索使用的ldap用户
ldap_default_bind_dn = cn=readonly,ou=system,dc=ldapmaster,dc=kifarunix-demo,dc=com
# 搜索使用的ldap用户的密码,仅支持明文
ldap_default_authtok = P@ssWOrd
# tls相关参数
# 这个参数是指定TLS绘画是否对服务器证书进行检查
# never 客户端不检查服务器证书
# allow 请求验证服务端证书,如果没有证书则会话正常进行,如果证书错误,将被忽略
# demand 请求验证服务端证书,如果证书错误或者没有证书,终止会话
# try 请求验证服务端证书,如果没有证书则会话正常进行,如果证书错误,终止会话
ldap_tls_reqcert = demand
ldap_tls_cacert = /etc/openldap/certs/cacert.pem
# 与ldap服务端通信超时相关配置
ldap_search_timeout = 50
ldap_network_timeout = 60
# 搜索用户的参数,下列是默认条件,这是强制参数,sssd在ldap上搜索用户的搜索条件,如果目录树是特别的名称需要更改
ldap_access_order = filter
ldap_access_filter = (objectClass=posixAccount)
# 例如 ldap_access_filter = memberOf=cn=allowedusers,ou=Groups,dc=example,dc=com
配置完成后可以启动服务,该服务与使用 nlscd
一样,需要开机自启,否则远端用户将不能完成认证
|
|
完成后需要配置下 nss 与 pam 的配置
- CentOS 7:
authconfig --enablesssd --enablesssdauth --enablemkhomedir --update
- CentOS 8:
authselect apply-changes -b --backup=ldap-configuration-backup
- Ubuntu:
pam-auth-update --enable mkhomedir
Notes:参数根据平台不同命令也不同,可以man查看下具体需要配置什么
sudo over sssd
对于sudo方面,配置没有使用nss+pam架构那么复杂只需要加几个参数即可使用sssd作为sudo认证
[sssd]
..
# service 增加 sudo
services = nss, pam, sudo, ssh
domains = default
debug_level = 6
[sudo]
# 枚举授信域
subdomain_enumerate = true
debug_level = 9
[domain/default]
...
# provider 增加 sudo_provider
sudo_provider = ldap
# 配置sudo默认搜索域,也就是sudoers的跟容器,这个必须设置
ldap_sudo_search_base = ou=SUDOers,dc=test,dc=com
# sssd在下载ldap服务端的sudo规则间隔秒数
# 默认21600
ldap_sudo_full_refresh_interval=86400
# 智能刷新,默认900秒,可以设置为0禁止只能刷新
# 该参数是指,下载条目为服务端USD高于当前SSSD的USN最高值的所有规则
# USD Update Sequence Number 代表数据变化的序列
ldap_sudo_smart_refresh_interval=3600
下面为sudo 与 NSS+PAM 迁移至SSSD的完整配置
[sssd]
config_file_version = 2
services = nss, pam, sudo, ssh
domains = default
debug_level = 6
[pam]
offline_credentials_expiration = 60
[sudo]
subdomain_enumerate = true
debug_level = 9
[domain/default]
id_provider = ldap
auth_provider = ldap
sudo_provider = ldap
ldap_uri = ldaps://10.0.0.10/
ldap_search_base = dc=test,dc=com
ldap_sudo_search_base = ou=SUDOers,dc=test,dc=com
ldap_default_bind_dn = uid=searchUser,ou=tvb,dc=test,dc=com
ldap_default_authtok_type = password
ldap_default_authtok = 1
cache_credentials = True
ldap_search_timeout = 50
ldap_network_timeout = 60
ldap_access_order = filter
ldap_access_filter = (objectClass=posixAccount)
ldap_tls_cacert = /etc/ssl/certs/cacert.crt
ldap_id_use_start_tls = true
ldap_tls_reqcert = allow
ldap_sudo_full_refresh_interval=86400
ldap_sudo_smart_refresh_interval=3600
此时验证用户登录与sudo是使用SSSD缓存还是通过每次请求slapd
Notes:对于更多的配置参数的说明,可以使用
man sssd
,man sssd-ldap
.. 进行查询 ,也可以通过 linux man 手册进行查询
Troubleshooting
ldap 日志报错 TLS established tls_ssf=256 ssf=256
[5]
Sep 19 12:16:40 centos6 slapd[16620]: conn=228 fd=14 ACCEPT from IP=client-IP:client-Port (IP=0.0.0.0:636)
Sep 19 12:16:40 centos6 slapd[16620]: conn=228 fd=14 TLS established tls_ssf=256 ssf=256
这里原因是,如果你使用TLS进行通讯,只有基于 ldap://[port_389]
才是TLS,如果使用 ldaps://[port_636]
那么是通过SSL隧道进行的
解决:对于SSSD端需要开启对应的TLS配置,如下
ldap_tls_cacert = /etc/ssl/certs/cacert.crt
ldap_id_use_start_tls = true
# 对服务器提供的证书执行的检查,因为服务端配置了要验证客户端证书
ldap_tls_reqcert = allow
Reference
[2] High CPU usage by sssd_nss during heavy disk IO
[3] SSSD and LDAP
[4] Chapter 10. Migrating authentication from nslcd to SSSD
[5] OpenLDAP Client 2.4.23: TLS negotiation failure
[6] Chapter 10. Migrating authentication from nslcd to SSSD
[7] Configure SSSD