LDAP学习笔记之九:OpenLDAP 密码策略、审计控制
一、密码策略
OpenLDAP密码策略包括以下几方面
1 2 3 4 5 6 7 8 | 密码的生命周期。 保存密码历史,避免在一段时间内重用相同的密码。 密码强度,新密码可以根据各种特性进行检查。 密码连续认证失败的最大次数。 自动账号锁定。 支持自动解锁账号或管理员解锁账号。 优雅(Grace)绑定(允许密码失效后登录的次数)。 密码策略可以在任意DIT 范围定义,可以是用户、组或任意组合。 |
密码策略属性详解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | pwdAllowUserChange,允许用户修改其密码。 pwdAttribute,pwdPolicy对象的一个属性,用于标识用户密码。 pwdExpire Warning,密码过期前警告天数。 pwdFailureCountInterval,密码失败后恢复时间。 pwdGraceAuthNLimit,密码过期后不能登录的天数,0代表禁止登录。 pwdInHistory,开启密码历史记录,用于保证不能和之前设置的密码相同。 pwdLockout,超过定义次数,账号被锁定。 pwdLockoutDuration,密码连续输入错误次数后,账号锁定时间。 pwdMaxAge,密码有效期,到期需要强制修改密码。 pwdMaxFailure,密码最大失效次数,超过后账号被锁定。 pwdMinAge,密码有效期。 pwdMinLength,用户修改密码时最短的密码长度。 pwdMustChange,用户登录系统后提示修改密码。 pwdSafeModify,是否允许用户修改密码,与 pwdMustChange共同使用。 pwdLockoutDuration,账号锁定后,不能自动解锁,此时需要管理员干涉。 |
设定用户密码定期修改及过期时间
向条目中添加一个名为shadowAccount的objectClass, 设定如下属性(attributes):
1 2 3 4 5 6 7 | shadowLastChange: 密码从1970年1月1日开始, 到最近一次修改, 一共间隔了多少天. 比如这里指定成16967就表示2016年6月15日. 也可以直接获取当天的日期,方法为:在系统里useradd一个用户,查看/etc/shadow中该用户的第三个值, 即是该值. 该值如果设置成0, 则表示下次登陆将强制修改密码, 用户修改密码成功以后, 该值将发生对应的变化; shadowMin: 密码从shadowLastChange指定的日期开始, 到多少天以后才能再次修改密码, 防止某些人天天没事就修改密码, 此值设置成0表示不限制; shadowMax: 密码从shadowLastChange指定的日期开始, 到多少天以后过期(即多少天后必须更改密码); shadowInactive: 密码过期以后还可以登陆多少天(每次登陆都会要求更改密码), 如果超过此值指定的天数, 下次登陆时会提示Your account has expired; please contact your system administrator; shadowWarning: 提前多少天开始警告用户密码将会过期; shadowExpire: 密码从1970年1月1日开始, 多少天以后将会过期, 这里一般用不到; shadowFlag: 暂时无用 |
一组建议的值
1 2 3 4 5 | shadowLastChange: 0 shadowMin: 0 shadowMax: 90 #每隔90天强制更换密码 shadowInactive: 7 #过期以后还有7天可以登陆,每次登陆都会提示修改密码 shadowWarning: 8 #提前8天开始提示密码即将过期 |
二、OpenLDAP服务端定制密码策略
1.加载模块
查看模块相关信息
1 2 3 4 5 6 | [root@ldap01 ~]# cat /etc/openldap/slapd.d/cn\=config/cn\=module\{0\}.ldif|grep ^olcModule #查看模块相关信息 olcModulePath: /usr/lib64/openldap olcModuleLoad: {0}memberof.la olcModuleLoad: {1}refint [root@ldap01 ~]# ls /usr/lib64/openldap/ppolicy.la #查看 ppolicy.la 模块 /usr/lib64/openldap/ppolicy.la |
加载模块(根据上面的模块信息对序号进行修改)
1 2 3 4 5 6 7 | [root@ldap01 ~]# cat << EOF | ldapadd -Y EXTERNAL -H ldapi: /// dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: {2}ppolicy.la EOF [root@ldap01 ~]# cat /etc/openldap/slapd.d/cn\=config/cn\=module\{0\}.ldif|grep ^olcModule #查看模块相关信息 |
添加 objectClass 对象,增加额外属性和值
1 2 3 4 5 6 7 8 9 10 | [root@ldap01 ~]# cat << EOF | ldapadd -Y EXTERNAL -H ldapi: /// dn: olcOverlay=ppolicy,olcDatabase={2}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcPPolicyConfig olcOverlay: ppolicy olcPPolicyDefault: cn= default ,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com olcPPolicyHashCleartext: TRUE olcPPolicyUseLockout: TRUE EOF |
2.定义密码策略组
在 pwpolicies 条目下创建密码策略组
1 2 3 4 5 | [root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: ou=pwpolicies,dc=ldap01,dc=pwb,dc=com ou: pwpolicies objectClass: organizationalUnit EOF |
定义密码策略组默认密码规则,可以定义多个,例如一个默认,一个安全人员的密码策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | [root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: cn= default ,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com cn: default objectClass: pwdPolicy objectClass: person pwdAllowUserChange: TRUE pwdAttribute: userPassword pwdExpireWarning: 259200 pwdFailureCountInterval: 0 pwdGraceAuthNLimit: 5 pwdInHistory: 5 pwdLockout: TRUE pwdLockoutDuration: 300 pwdMaxAge: 2592000 pwdMaxFailure: 5 pwdMinAge: 0 pwdMinLength: 8 pwdMustChange: TRUE pwdSafeModify: TRUE sn: dummy value EOF [root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: cn=security,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com cn: security objectClass: pwdPolicy objectClass: person pwdAllowUserChange: TRUE pwdAttribute: userPassword pwdExpireWarning: 259200 pwdFailureCountInterval: 0 pwdGraceAuthNLimit: 5 pwdInHistory: 5 pwdLockout: TRUE pwdLockoutDuration: 300 pwdMaxAge: 2592000 pwdMaxFailure: 5 pwdMinAge: 0 pwdMinLength: 8 pwdMustChange: TRUE pwdSafeModify: TRUE sn: dummy value EOF |
设置用户使用密码策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: uid=ldap1,ou=People,dc=ldap01,dc=pwb,dc=com changetype: modify add: pwdPolicySubentry #修改使用security策略组可以replace pwdPolicySubentry: cn= default ,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com EOF 如果对全局进行配置,则可以加入如下权限: [root@ldap01 ~]# cat << EOF | ldapmodify -c -Y EXTERNAL -Q -H ldapi: /// dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcAccess olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by dn= "cn=default,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com" write by anonymous auth by * read olcAccess: {1}to * by self write by dn= "cn=default,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com" write by * read EOF |
定义用户登录需改密码
1 2 3 4 5 6 7 8 | root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: uid=ldap1,ou=People,dc=ldap01,dc=pwb,dc=com changetype: modify replace: pwdReset pwdReset: TRUE EOF [root@ldap01 ~]# ldapsearch -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 "uid=ldap1" + #注意最后有个+号,pwdReset 属性隐藏属性,默认 ldapsearch 无法获取隐藏属性,通过+号可获取查询包含的隐藏属性 |
利用shadow设置用户首次登陆修改密码
利用shadow属性来强制用户(网上在客户端的配置好像存在问题,在centos7上存在问题,google后有人建议使用shadow)
1 2 3 4 5 6 | [root@client01 log]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: uid=ldap1,ou=People,dc=ldap01,dc=pwb,dc=com changetype: modify replace: shadowLastChange shadowLastChange: 0 EOF |
3.客户端配置验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | [root@client01 log]# ssh ldap1@192.168.1.132 #首次登录提示密码过期,强制我们需要修改密码 ldap1@192.168.1.132's password: You are required to change your password immediately (root enforced) need a new password Last login: Thu Apr 21 23:09:47 2022 from client01.pwb.com WARNING: Your password has expired. You must change your password now and login again! 更改用户 ldap1 的密码 。 (current) LDAP Password: 新的 密码: #此处输入123456 重新输入新的 密码: password change failed: Constraint violation #提示我们修改失败,因为不符合密码策略组设置的密码策略 passwd: 鉴定令牌操作错误 Connection to 192.168.1.132 closed. [root@client01 log]# ssh ldap1@192.168.1.132 #重新登录修改密码,需要符合密码长度 ldap1@192.168.1.132's password: You are required to change your password immediately (root enforced) need a new password Last login: Thu Apr 21 23:17:37 2022 from client01.pwb.com WARNING: Your password has expired. You must change your password now and login again! 更改用户 ldap1 的密码 。 (current) LDAP Password: 新的 密码: 重新输入新的 密码: passwd:所有的身份验证令牌已经成功更新。 Connection to 192.168.1.132 closed. [root@client01 log]# ssh ldap1@192.168.1.132 #修改后程序登录是密码可以正常登录 ldap1@192.168.1.132's password: Last login: Thu Apr 21 23:23:19 2022 from client01.pwb.com [ldap1@client01 ~]$ |
4.添加pqchecker密码检查模块
上面的策略只能实现基本的功能,但对于密码负责度的检测,自带的模块无法实现,我们只能额外安装其他模块,此处用到的模块是:pqchecker
安装模块
1 2 3 4 | [root@ldap01 ~]# wget --no-check-certificate https: //meddeb.net/pub/pqchecker/rhel/7/pqchecker-2.0.0-1.el7.x86_64.rpm [root@ldap01 ~]# qpm -ql pqchecker [root@ldap01 ~]# cat /etc/openldap/pqchecker/pqparams.dat |grep -v "^#" 0|01010101 #规则实例如上:|号后面的为规则,前两位表示密码至少得有多少个大写字母,最多为99个,最少为0个,以此类推,每两位标识一种字符至少包含的数量,后面分别是小写字母,数字,特殊字符。 |
配置密码策略对新策略的支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | root@ldap01 ~]# vim add_pqchecker.ldif dn: cn= default ,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com changetype: modify replace: pwdCheckQuality pwdCheckQuality: 2 #可以使用3个值 0:不检查 1:检查,但是密码不符合也接受 2:检查,密码不符合不接受 - add: objectclass objectclass: pwdPolicyChecker - add: pwdcheckmodule pwdcheckmodule: pqchecker.so.2.0.0 [root@ldap01 ~]# ldapadd -x -D cn=admin,dc=ldap01,dc=pwb,dc=com -w 123456 -f add_pqchecker.ldif root@ldap01 ~]# ldapsearch -Y external -H ldapi: /// -b cn=config "(objectClass=olcModuleList)" -LLL ...... olcModuleLoad: {2}ppolicy.la #pqchecker依赖ppolicy模块,必须为加载状态 [root@ldap01 ~]# ldapsearch -Y external -H ldapi: /// -b cn=default,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com pwdCheckModule pwdCheckQuality -LLL SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 dn: cn= default ,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com pwdCheckModule: pqchecker.so.2.0.0 pwdCheckQuality: 2 |
配置用户
1 2 3 4 5 6 | [root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: uid=ldap2,ou=People,dc=ldap01,dc=pwb,dc=com changetype: modify add: pwdPolicySubentry pwdPolicySubentry: cn= default ,ou=pwpolicies,dc=ldap01,dc=pwb,dc=com EOF |
客户端验证ldapadd 用户修改密码时是否满足包含1个字符1个数字一个大写字母一个小写字母的策略,自行验证
5.加载审计模块 Auditlog
开启密码审计功能主要用于记录 OpenLDAP 用户修改密码,以及密码审计
1 2 3 4 5 6 7 8 9 10 11 12 | [root@ldap01 log]# cat << EOF | ldapadd -Y EXTERNAL -H ldapi: /// dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: {1}auditlog dn: olcOverlay=auditlog,olcDatabase={2}hdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcAuditLogConfig olcAuditlogFi EOF |
6.常见用户密码问题
超过输入密码的次数账户被锁
1 2 3 4 5 | [root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: uid=ldap2,ou=People,dc=ldap01,dc=pwb,dc=com changetype: modify delete: pwdAccountLockedTime #超过次数后,用户隐藏属性为打上 pwdAccountLockedTime 标志,删除标签即可 EOF |
密码过期解决方案
1 2 3 4 5 6 7 8 9 10 11 | #密码过期主要是由于账号没有在指定时间内修改密码,当超过的时间后会提示用户密码过期 将用户的密码信息删除,然后添加密码字符串即可 [root@ldap01 ~]# cat << EOF | ldapadd -x -D "cn=admin,dc=ldap01,dc=pwb,dc=com" -w 123456 -H ldap: //ldap01.pwb.com dn: uid=ldap2,ou=People,dc=ldap01,dc=pwb,dc=com dn: cn=shilei,cn=ops,ou=IT,dc=shileizcc,dc=com changtype: modify delete: userpassword userpassword: 123 - add: userpassword userpassword: 123 EOF |
"一劳永逸" 的话,有是有的,而 "一劳永逸" 的事却极少
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具