Kerberos+LDAP+NFSv4怎样实现单点登录

89次阅读
没有评论

共计 10531 个字符,预计需要花费 27 分钟才能阅读完成。

Kerberos+LDAP+NFSv4 怎样实现单点登录,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Kerberos+LDAP+NFSv4 实现单点登录

六.nfs 客户机的安装
nfs 客户机也即 SSSD 客户机, 需安装 sssd 和 nfs-common

1. 安装 sssd
会自动安装 libsasl2-modules-gssapi-mit(非依赖)
libsasl2-modules-gssapi-mit 和 libsasl2-modules-gssapi-heimdal 两者冲突, 安装 libsasl2-modules-gssapi-heimdal 也可以

root@debian:~# apt-get install sssd sssd-krb5 sssd-ldap libsasl2-modules-gssapi-heimdal

安装后的 sssd.conf 是空白文件,nsswitch.conf 没改变

root@debian:~# ls -l /etc/sssd/sssd.conf
-rw------- 1 root root 1938 Jun 10 11:18 /etc/sssd/sssd.conf

仅拥有者可读(SSSD 文档要求 sssd.conf 仅 root 根用户可读写, 否则无法启动 sssd)

修改配置文件 sssd.conf、nsswitch.conf

1)查看 sssd.conf
root@debian:~# cat /etc/sssd/sssd.conf
[sssd]
config_file_version = 2

services = nss, pam
domains = intern

[nss][pam][domain/intern]

#–v– unix 用户信息由 LDAP 提供
id_provider = ldap
#–^–

#–v– 用户认证及密码修改由 Kerberos 提供
auth_provider = krb5
chpass_provider = krb5
#–^–

ldap_uri = ldap://192.168.1.101
ldap_search_base = ou=hdkrb5,dc=ctp,dc=net
ldap_tls_reqcert = allow

krb5_server = 192.168.1.101
krb5_realm = CTP.NET

#–v– 有的环境不设总无法认证, 应该密码认证要很长时间, 需设超时时间大一点
krb5_auth_timeout = 60
#–^–
root@debian:~#

2)查看 nsswitch.conf
root@debian:~# cat /etc/nsswitch.conf
passwd:         files sss
group:          files sss
shadow:         files sss

gshadow:        files

hosts:          files mdns4_minimal [NOTFOUND=return] dns
networks:       files

protocols:      db files
services:       db files sss
ethers:         db files
rpc:            db files

netgroup:       nis sss
sudoers:        files sss

root@debian:~#
即将原来的 compat 改为 files sss

3)安装 sssd 时自动设置 /etc/pam.d/
linlin@debian:~$ cat /etc/pam.d/common-session-noninteractive
session    [default=1]            pam_permit.so
session    requisite            pam_deny.so
session    required            pam_permit.so
session    required    pam_unix.so
session    optional            pam_umask.so umask=002

linlin@debian:~$
linlin@debian:~$ cat /etc/pam.d/common-session

session    [default=1]            pam_permit.so
session    requisite            pam_deny.so
session    required            pam_permit.so
session    required    pam_unix.so
session    optional            pam_sss.so
session    optional    pam_systemd.so
session    optional            pam_umask.so umask=002

linlin@debian:~$
linlin@debian:~$ cat /etc/pam.d/common-password

password    requisite            pam_pwquality.so retry=3
password    [success=2 default=ignore]    pam_unix.so obscure use_authtok try_first_pass sha512
password    sufficient            pam_sss.so use_authtok
password    requisite            pam_deny.so
password    required            pam_permit.so
password    optional    pam_gnome_keyring.so

linlin@debian:~$
linlin@debian:~$ cat /etc/pam.d/common-auth

auth    [success=2 default=ignore]    pam_unix.so nullok_secure
auth    [success=1 default=ignore]    pam_sss.so use_first_pass
auth    requisite            pam_deny.so
auth    required            pam_permit.so
auth    optional            pam_group.so

linlin@debian:~$
linlin@debian:~$ cat /etc/pam.d/common-account

account    [success=1 new_authtok_reqd=done default=ignore]    pam_unix.so
account    requisite            pam_deny.so
account    required            pam_permit.so
account    sufficient            pam_localuser.so
account    [default=bad success=ok user_unknown=ignore]    pam_sss.so
linlin@debian:~$

4)重启 sssd

root@debian:~# /etc/init.d/sssd stop
root@debian:~# /etc/init.d/sssd start

5)测试
linlin@debian:~$ kpasswd krblinlin
krblinlin@CTP.NET s Password:
New password for krblinlin@CTP.NET:
Verify password – New password for krblinlin@CTP.NET:
Success : Password changed

linlin@debian:~$
linlin@debian:~$ su krblinlin
Password:
krblinlin@debian:/home/linlin$
krblinlin@debian:/home/linlin$ passwd

Current Password:
New password:
BAD PASSWORD: The password is shorter than 8 characters
New password:
Retype new password:
passwd: password updated successfully   要很长时间
krblinlin@debian:/home/linlin$

登录成功, 修改密码命令 kpasswd、passwd 都成功. 注意密码是 Kerberos 密码, 非 LDAP 密码

但某些环境存在一个问题, 当 kdc 服务器重启,SSSD 客户机无法登录, 需手工在 kdc 服务器上重启守护进程 heimdal-kdc, 还找不到原因. 而另试另外环境很正常

2. 安装 nfs-common
root@debian:~# apt-get install nfs-common

修改 /etc/default/nfs-common 文件

NEED_GSSD=
改为
NEED_GSSD= yes

root@debian:~# /etc/init.d/nfs-common stop
root@debian:~# /etc/init.d/nfs-common start

root@debian:~# ps -e |grep gss
1027 ?        00:00:00 rpc.gssd

1)挂载网络共享
手工挂载

root@debian:~# mount -t nfs4 srvnf.ctp.net:/home/linlin/share /mnt -o sec=krb5

添加到 /etc/fstab, 一开机挂载网络共享
root@debian:~# cat /etc/fstab
UUID=c992cbf5-3eca-4434-baf9-b5a3180acdbb /               ext4    errors=remount-ro 0       1
#swap was on /dev/sda5 during installation
UUID=854aa36b-6ce5-436d-91fa-50aa10e8338c none            swap    sw              0       0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0

# 添加网络共享
srvnf.ctp.net:/home/linlin/share  /mnt nfs4 rw,sec=krb5
root@debian:~#

2)查看挂载信息
linlin@debian:~$ mount|grep nfs
srvnf.ctp.net:/home/linlin/share on /mnt type nfs4 (rw,relatime,vers=4.0,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=krb5,clientaddr=192.168.1.102,local_lock=none,addr=192.168.1.103)

3)测试写网络共享

root@debian:~# ls -ld /mnt
drwxr-xr-x 2 krblinlin 4001 4096 Sep 18 09:13 /mnt
root@debian:~#

可看到已获取显示 ldap 用户信息,krblinlin 为 ldap 用户

在普通本地用户下
linlin@debian:~$ su krblinlin
Password:
或控制台直接登录
debian login: krblinlin
Password:

krblinlin@debian:/home/linlin$ cd /mnt
krblinlin@debian:/mnt$ touch a.txt
krblinlin@debian:/mnt$ ls
a.txt
krblinlin@debian:/mnt$

写成功

root@debian:~# ps -e |grep idmapd
 533 ? 00:00:00 rpc.idmapd

至此, 以 LDAP 作为存储用户信息, 以 Kerberos 作为身份认证,SSSD 客户机已成功访问读写 NFSv4 服务器网络共享

七. 后记
本文的目的是要打造一个类似 FreeIPA、AD 活动目录, 而完善的 Kerberos 系统还需 DNS、DHCP 配合, 所以本文也仅仅实验而已.

实现单点登录的方案多种多样.LDAP 同时也提供简单用户认证, 如果不需应用 NFSv4 或 NFSv4 采用弱的系统认证, 无需搭建 Kerberos, 仅 LDAP 就可满足单点登录; 而 samba4 可轻松打造一个 linux 下的活动目录.

1.
Kerberos 系统最初由麻省理工开发, 即 MIT Kerberos 项目 (http://web.mit.edu/kerberos/), 当前很活跃
另一 Kerberos 系统即本文的 Heimdal Kerberos 项目(http://www.h6l.org/).

为何本文选 Heimdal 而不选 MIT, 前文已讲过, 一是使用 LDAP 作为 Kerberos 后端, 二是避免存储明文的 ldap 数据库管理员密码.
1)MIT 通过插件支持 LDAP 作为后端, 文档也说明支持 EXTERNAL, 但我搞不掂配置怎支持 EXTERNAL, 查看源码也看不出头绪
st = ldap_sasl_interactive_bind_s(server- ldap_handle, NULL,ctx- sasl_mech, NULL, NULL,LDAP_SASL_QUIET, interact, ctx);
通过配置文件将 EXTERNAL 传递到 ctx- sasl_mech

查找了资料好象 ldap_sasl_interactive_bind_s 使用 EXTERNAL 之前要先 ldap_get_option 有关 LDAP_OPT_X_SASL_AUTHZID, 虽 MIT 源码有 ldap_get_option, 但里边是几个写死的 LDAP_OPT_xxxx, 与认证无关, 也没找到和 SASL 相关

2)Heimdal 内置支持 LDAP 作为后端, 缺省支持 EXTERNAL, 查看源码简单明了
rc = ldap_sasl_bind_s(HDB2LDAP(db), NULL, EXTERNAL , bv,NULL, NULL, NULL);

3)openldap 的同步密码插件只支持 Heimdal

2.openldap 同步密码
当有时以 Kerberos 登录, 有时要以 LDAP 登录, 要维护记住两套密码是麻烦的事情. 有 3 种方法可只使用一个密码

方法 1:
使用 {SASL} 方式, 需配置如下面

root@debian:~# cat /etc/sasl2/slapd.conf
pwcheck_method: saslauthd
root@debian:~#

userPassword 属性填上固定值 {SASL}
此方法是搜索网上的方法, 本人未试过.

方法 2 和方法 3: 安装 openldap 的同步密码插件 slapd-smbk5pwd

方法 2:
userPassword 属性填上固定值 {K5KEY}
方法 2 和方法 1 都要注意不要改动到 userPassword 属性的值, 并且修改密码只能用 Kerberos 方式

方法 3:
修改密码只能用 LDAP 方式, 且只能用类似 ldappasswd 命令的方式, 同时修改了 userPassword、krb5Key .
ldappasswd is a tool to set the password of an LDAP  user. ldappasswd uses the LDAPv3 Password Modify (RFC 3062) extended operation.
注意 ldappasswd 是 LDAP 一扩展操作, 详细请参考 RFC 3062.
我对 ldappasswd 的理解应该是发送未经散列的明文密码到 LDAP 服务器, 由 LDAP 服务器自己散列成密文存储到 ldap 数据库.
而普通 ldap 修改密码是要自己在客户端将明文密码散列成密文,LDAP 服务器不再变换而存储到 ldap 数据库, 也就是说本来 LDAP 的密码属性和其它属性没什么区别, 普通 ldap 修改密码的方式就是如同修改其它属性值.
方法 3 可做到 Kerberos、LDAP、samba 三套密码同步

本文采用方式 2 或方式 3
1)安装

root@debian:~# apt-get install slapd-smbk5pwd

slapd-smbk5pwd : Keeps Samba and Kerberos passwords in sync within slapd

2)加载模块

root@debian:~# cat smbk5pwd.ldif
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: smbk5pwd
root@debian:~#
root@debian:~# ldapadd -Y EXTERNAL -H ldapi:/// -f smbk5pwd.ldif

3)前面已安装了 heimdal-kdc, 并 LDAP 已添加加了 heimdal 模式, 因本文目的只要同步 Heimdal, 不同步 samba, 所以无需添加 samba 模式

4)将 /var/lib/heimdal-kdc/m-key 改为 openldap 用户拥有
m-key 原权限是 root 拥有, 仅 root 读写. 而 openldap 是以 openldap 用户启动.
如不先改 m -key 权限, 而先执行步骤 5), 则会因无权限而 ldapadd 出错

root@debian:~# chown openldap  /var/lib/heimdal-kdc/m-key

5)启用同步

root@debian:~# cat krb5.ldif
dn: olcOverlay=smbk5pwd,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSmbK5PwdConfig
olcOverlay: smbk5pwd
olcSmbK5PwdEnable: krb5
root@debian:~#
root@debian:~# ldapadd -Y EXTERNAL -H ldapi:/// -f krb5.ldif

6)重启 openldap
通常在线配置, 是立即生效, 但因 /var/lib/heimdal-kdc/m-key 文件权限问题, 所以还是重启 openldap 为好

7)测试
以普通本地用户登录

linlin@debian:~$ ldappasswd -h 192.168.1.101 -D  krb5PrincipalName=krblinlin@CTP.NET,ou=hdkrb5,dc=ctp,dc=net  -W -S
New password:
Re-enter new password:
Enter LDAP Password:  老密码(LDAP 用户的密码, 不是指 Kerberos 用户密码)
linlin@debian:~$

这样修改 LDAP 用户的密码同时也修改了 Kerberos 用户密码, 用 Kerberos 用户密码登录也正常

注意 /var/lib/heimdal-kdc/m-key 文件权限要确保正确(否则虽 ldappasswd 提示成功, 但实际 krb5Key 属性的值是破损的, 无法以 Kerberos 用户密码登录)

3. 因 LDAP 安装过程自动设置了可匿名读取除 userPassword 外的其它属性, 而 krb5Key 属性应是包含 Kerberos 密码信息, 是否需设置非本 Kerberos 用户禁止读取 krb5Key ?
本人不才, 未见有相关资料有明确设置禁止, 是不是即使 krb5Key 被非法获取, 没有 /var/lib/heimdal-kdc/m-key 也无法破解密码吗?

4. 设置非本地用户 SSSD 登录自动创建用户目录
上面的实验 krblinlin 登录到客户机, 该客户机不存在 krblinlin 的用户目录.
可使用 pam_mkhomedir.so 来自动创建用户目录,pam_mkhomedir.so 在 libpam-modules 包中  
1)安装
root@debian:~# apt-get install libpam-modules

2)到 /etc/pam.d/common-session 中增加一行 pam_mkhomedir.so, 内容大致如下

session    required    pam_unix.so

#–v– 新增一行, 自动创建用户目录
session required   pam_mkhomedir.so umask=0077
#–^–

session    [success=ok default=ignore]    pam_ldap.so minimum_uid=1000

3)登录
debian login: krblinlin
Password:
Creating directory /home/krblinlin . 已正常首次登录创建用户目录

krblinlin@debian:~$
krblinlin@debian:~$ pwd
/home/krblinlin
krblinlin@debian:~$

5. 文件系统的 ACL(访问控制列表)
虽说 NFSv4 的是 NFSv4 acl, 但本实验仍是 posix acl, 猜测 NFSv4 acl 可能需本地文件系统支持吧, 好象只有 zfs 本地文件系统才支持 NFSv4 acl

6. 域
LDAP 域和 Kerberos 域可以不同

即 Kerberos 的 realm 是 CTP.NET
LDAP 的基本 DN 可以是 dc=oled,dc=com

7. 其它
debian 9 安装 openldap 过程是使用 mdb 作为 LDAP 的后端, 而 LDAP 还可选 hdb 等其它作为后端. 选不同的后端, 其配置目录、文件名称及配置数据库条目内容按后端名称
如本实验是 mdb

root@debian:~# apt-get install tree
root@debian:~# tree /etc/ldap/slapd.d
/etc/ldap/slapd.d
|-- cn=config
| |-- cn=module{0}.ldif
| |-- cn=schema
| | |-- cn={0}core.ldif
| | |-- cn={1}cosine.ldif
| | |-- cn={2}nis.ldif
| | |-- cn={3}inetorgperson.ldif
| |-- cn=schema.ldif
| |-- olcBackend={0}mdb.ldif
| |-- olcDatabase={-1}frontend.ldif
| |-- olcDatabase={0}config.ldif
| |-- olcDatabase={1}mdb.ldif
|-- cn=config.ldif
root@debian:~#
上面是刚安装完 openldap 后的

如要重新创建 ldap 数据库
root@debian:~# dpkg-reconfigure slapd
配置过程中假如选 hdb 作为后端, 则相关内容是 hdb

查看 ldap 数据库
root@debian:~# slapcat

查看配置数据库
root@debian:~# slapcat -b cn=config

八. 修正
实验时的环境是 debian 9 testing 版
第三章节第 1 小节的 2)设置 ACL 访问控制列表, 那行 将

olcAccess: {2}to * by self write by dn= cn=admin,dc=ctp,dc=net  write by * read

不记得是 openldap 安装包脚本本身设定的, 还是我自己弄错, 原 改为 那行也照抄 to * by self write
这是严重的漏洞及错误. to * by self write 会允许 ldap 用户修改本身条目的任何属性,
如 ldap 用户可将自己的 unix 的 uidNumber 设为 0 即根用户, 这很危险, 即普通用户可以提权自己 (虽然 ldap 客户机默认配置将 ldap 的 uidNumber 值为 0 映射为非根用户) 或冒充其他用户.
所以, 原则 ldap 用户只允许修改本身及只能修改密码属性, 其他属性只能由管理员设置.

因此, 原 改为 那行
olcAccess: {2}to * by self write by dn= cn=admin,dc=ctp,dc=net write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * read
实际是需改为
olcAccess: {2}to * by dn= cn=admin,dc=ctp,dc=net write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * read

本文已作了修正

附 debian 10 testing 版 openldap 安装后未经 改为 的原始完整 olcAccess 配置

olcSuffix: dc=ctp,dc=net
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read
olcLastMod: TRUE
olcRootDN: cn=admin,dc=ctp,dc=net

关于 Kerberos+LDAP+NFSv4 怎样实现单点登录问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注丸趣 TV 行业资讯频道了解更多相关知识。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-25发表,共计10531字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)