十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

域用户无法修改密码?从ACL到DC复制的完整排障指南

域用户无法修改密码?从ACL到DC复制的完整排障指南 周一上午刚进办公室Helpdesk的同事就拉了个群说分公司三个人同时报障登录界面按 CtrlAltDel 改密码输入新密码后直接弹“无法更新密码”。这三个人的账户都是域用户密码策略也没改过怎么就集体改不了等我远程上去一看发现问题根本不是出在“密码不符合复杂度”这种表面上而是分散在账户ACL、密码策略、甚至DC复制这块。今天就把这次排查的完整链路写下来顺便把域用户无法修改密码的几个隐藏坑一次说清包括ADUC属性、组策略、ACL委派、SDProp、多域控复制这些环节希望对同样被这个问题折磨过的运维朋友有帮助。1. 先对号入座域用户改密码失败的几种典型表现域用户改不了密码报错提示看着都差不多但背后的原因可能完全不同。我习惯先按场景分类因为不同场景对应的排查路径几乎不重叠。1.1 登录界面改密码直接报错最常见的就是用户按 CtrlAltDel选择“更改密码”输入旧密码和新密码后系统提示“无法更新密码”。这种情况下客户端和域控之间的通信通常是正常的问题大概率出在账户属性、ACL权限或者密码策略上。这类报错最大的迷惑性在于它不告诉你具体是哪一项不满足。新密码长度够、复杂度也够可系统就是拒绝。很多人以为是用户输入的密码不符合规则实际上账户的“更改密码”权限早就在ACL里被拒了或者密码最短使用期还没过。1.2 密码过期后第一次登录卡在改密码环节还有一种高频场景用户密码已经过期在登录界面提示“密码已过期必须更改密码”但点击确定后弹出的修改窗口很快报错甚至直接退回锁屏界面。这种场景比第一种更尴尬因为用户处于“不改密码就进不了系统、系统又不让改密码”的死循环里。碰到这种情况先不要急着在ADUC里手动重置密码因为如果根因是ACL拒绝管理员重置密码后用户下次登录还是改不了。1.3 管理员重置密码后用户仍然改不动管理员在ADUC里右键账户选择“重置密码”给用户设置一个临时密码用户登录后第一次改密依然失败。这种情况基本可以排除“用户输错旧密码”的因素问题集中在账户对象本身的权限控制上。还有一种容易被忽视的现象管理员在ADUC里看到“用户不能更改密码”没有被勾选但用户的ACL里确实存在一条拒绝Change Password的ACE。这个问题后面会专门讲ADUC界面勾选只是最表层的一种操作方式。2. “用户不能更改密码”这个开关到底藏在哪里很多人对“用户不能更改密码”的理解就是ADUC属性页里那个复选框。实际上它只是一个操作入口真正的机制是把一条“拒绝Everyone更改密码”的ACE写入了用户对象的nTSecurityDescriptor。2.1 ADUC属性中的复选框只是表象在ADUC中打开用户属性切到“账户”选项卡底部有一组“账户选项”其中一个就是“用户不能更改密码”。勾上并应用后系统会在该用户对象的ACL中添加入一条类型为“拒绝”的访问控制项主体是Everyone权限是“更改密码”这个扩展权限。这也是为什么有人用脚本批量勾选或取消这个选项时会碰到“界面显示与权限实际生效状态不一致”的情况。我之前就遇到过一批从旧OA系统同步过来的账户界面看没有任何异常但用户就是改不了密码最后用PowerShell查ACL才发现问题。对于单个账户直接在ADUC里取消勾选通常就能解决。但如果你遇到的是批量账户中招挨个点界面显然不现实。这里分享一段我常用的PowerShell排查脚本找出所有携带“拒绝更改密码”ACE的账户$changePwdGUID ab721a53-1e2f-11d0-9819-00aa0040529b Get-ADUser -Filter * -Properties ntSecurityDescriptor | ForEach-Object { $deny $_.ntSecurityDescriptor.Access | Where-Object { $_.AccessControlType -eq Deny -and $_.ObjectType -eq $changePwdGUID } if ($deny) { [PSCustomObject]{ SamAccountName $_.SamAccountName DeniedBy $deny.IdentityReference } } } | Format-Table -AutoSize原理说明一下GUID“ab721a53-1e2f-11d0-9819-00aa0040529b”对应的就是User-Change-Password这个扩展权限。在ntSecurityDescriptor的Access列表里如果存在ObjectType等于这个GUID且类型为Deny的条目就说明该账户被设置了“用户不能更改密码”。2.2 组策略里也有一个“用户不能更改密码”很多管理员找了一圈在组策略管理编辑器里发现“账户策略”下面只有密码策略、账户锁定策略并没有专门控制单个用户能否改密码的项。别急组策略里确实有一个入口只不过它控制的对象不是单个用户而是机上所有用户。位置在“计算机配置 - 策略 - Windows 设置 - 安全设置 - 本地策略 - 用户权限分配”里有一个“拒绝从网络访问这台计算机”和“拒绝作为批处理作业登录”等条目但真正影响改密行为的是“拒绝通过远程桌面服务登录”之类的登录权限。更直接相关的组策略设置其实是这两个策略路径策略项影响计算机配置 - 策略 - Windows 设置 - 安全设置 - 本地策略 - 安全选项交互式登录: 提示用户在过期前更改密码密码过期前多少天提示不影响改密能力计算机配置 - 策略 - Windows 设置 - 安全设置 - 本地策略 - 安全选项域成员: 禁用计算机帐户密码更改只影响计算机账户不影响用户账户有些文档会把“域成员: 禁用计算机帐户密码更改”误写成控制用户改密码这是个常见误区。这个策略其实是禁止DC周期性地修改机器账户的密码和用户改密完全是两码事。2.3 批量创建账户时最容易踩的隐藏勾选用dsadd、net user或第三方脚本批量创建域账户时很容易带上一些隐形的属性。比如通过net user /add创建的域用户在部分环境下会被打上“密码永不过期”的标记用户账户控制标志位会包含DONT_EXPIRE_PASSWORD。而有些HR系统同步脚本会创建一个带“用户不能更改密码”权限的模板账户然后通过复制模板的方式批量生成新账户。这种方式最坑因为新账户的ACL是从模板继承来的ADUC的用户属性页里可能看着正常但ACL里那条Deny ACE已经复制过来了。我的习惯是批量创建账户后先抽几个不同OU的账户用上一小节那段PowerShell脚本跑一遍确认没有异常的Deny ACE再通知用户使用。3. 密码策略与账户状态不是操作不对而是策略把路堵死了排除了ACL层面的问题接下来大概率是密码策略在作怪。域密码策略由Default Domain Policy或细粒度密码策略PSO定义用户侧的报错千篇一律但策略原因其实有规律可循。3.1 复杂度、历史记录与最短使用期的组合拳域环境默认开启了密码复杂性要求新密码必须同时包含大写字母、小写字母、数字和特殊字符且不能包含账户名或用户全名中的部分字段。这一点很多用户不清楚经常在设置一个看似“很强”的密码后反复被拒。容易被忽略的是“强制密码历史”和“最短密码使用期”。默认域策略通常保留最近24个密码如果用户改来改去都在用熟悉的几组密码很容易触发历史记录限制。而“最短密码使用期”设置了之后管理员刚刚重置的临时密码用户当天就尝试改成自己的密码会因为“新密码使用时间太短”直接被拒。我在处理过一个加固过的客户环境他们的域策略把最短密码使用期设成了2天导致管理员每次重置密码后用户必须等48小时才能修改。这个策略本意是防止用户绕过历史记录但实际运维中直接造成了“管理员重置了密码用户依然改不了”的误会。查看当前域密码策略直接在域成员机上执行net accounts /domain这个命令会显示域级别的密码策略包括最大密码使用期、最小密码使用期、最小密码长度、密码历史等。如果发现最短密码使用期不为0就要把这个因素纳入排查范围。3.2 “密码永不过期”和“下次登录须更改密码”形成的死锁这个是我见过最隐蔽的组合。正常情况下ADUC里勾选了“用户下次登录时须更改密码”就不会再勾选“用户不能更改密码”因为界面层会阻止这两个选项同时生效。但脚本创建的账户没有这个限制。如果某段脚本直接把pwdLastSet设置为0下次登录须更改密码同时又把ACL里的Deny Change Password ACE写进去了那用户就会被卡在一个逻辑闭环里系统要求必须先改密码但权限又不允许改密码。登录的时候表现就是屏幕上提示“你必须在登录前更改密码”点确定后修改窗口一闪而过然后又回到锁屏界面如此反复。管理员即便在ADUC里重置密码只要这两个条件没解除问题照样存在。排查时需要同时检查这两项Get-ADUser -Identity testuser -Properties pwdLastSet,userAccountControl关注pwdLastSet是否为0以及userAccountControl是否包含65536这个DONT_EXPIRE_PASSWORD标记。注意DONT_EXPIRE_PASSWORD本身不阻止用户改密码它只是让密码不过期。真正要关注的是ACL中的Deny ACE。3.3 用组策略结果集和PSO确定生效策略有些环境启用了细粒度密码策略PSO这时候单看Default Domain Policy就不够准确了。PSO可以针对不同用户组设置不同的密码策略优先级高于域默认策略。查看某个用户实际生效的密码策略Get-ADUserResultantPasswordPolicy -Identity testuser这个命令会返回该用户生效的PSO名称及策略参数。如果返回值为空说明用户还是走默认域策略。之前处理过一个案例一个部门用户的密码策略被PSO单独设置了最短密码长度14位但Helpdesk测试时用的是普通策略账户长度12位就能通过。结果部门用户反复报“改不了密码”Helpdesk反复说“策略没问题”最后查PSO才发现各说各话。所以遇到批量用户集体改码失败先跑一遍这个命令确认你测试的账户和报障用户是否真的在同一套策略下。4. 不是域管理员就一定能改ACL委派里容易被忽略的权限很多运维想当然地认为只要是域管理员或者账户所属OU的管理员就能修改用户密码。这个观点在“管理员帮用户重置密码”的场景下基本成立但在“用户自己修改密码”的场景下完全站不住脚因为自主修改密码依赖的是用户对自己账户对象的Change Password权限而这个权限是可以被精确控制的。4.1 最小权限授权把“更改密码”和“重置密码”切开了AD中有两个容易混淆的权限“更改密码”和“重置密码”。前者是用户本人或其他人对账户执行自主密码修改时需要的权限后者是管理员不输入旧密码直接强制设置新密码时需要的权限。这是两个独立的扩展权限GUID也不一样。很多企业做权限委派时给IT支持人员配置了“重置密码”权限同时为了安全考虑在OU上禁用了Everyone的“更改密码”权限。结果就是IT支持能帮用户重置密码但用户拿到临时密码后自己改不了。碰到这种情况要么在OU级别给Everyone重新授“更改密码”权限要么在ADUC里为用户单独取消“用户不能更改密码”的勾选。前者是批量操作的思路后者只适合单点修复。检查用户对象当前是否拥有“更改密码”权限可以借助ADUC的“高级功能”视图在用户属性的“安全”选项卡里查看高级权限。注意这里要重点查看“有效访问”或者“权限”列表里Everyone主体对应的Change Password项。4.2 继承被关闭后失去默认修改权限还有一种更隐蔽的情况用户所在OU被设置了“阻止继承”而且新ACL里没有包含Everyone的Change Password权限。这样即使用户对象的属性页里所有复选框都正常用户依然无法修改自己的密码。出现这种情况通常都是其他管理员在调整OU权限时误操作把继承关了然后手工配置了一个“最小权限集”。这种“最小权限集”往往只包含该OU管理组的权限漏掉了默认的Everyone权限。恢复方法打开OU属性 - 安全 - 高级勾选“允许从父项继承权限”或者手动添加一条Everyone的Change Password权限。改完之后注意SDProp的传播不是即时的可以强制执行或等待一段时间。4.3 正确授权给技术支持团队的做法如果你希望IT支持团队既能帮用户重置密码又不希望他们越过这个权限去做其他危险操作正确做法是在OU委派向导里选择“重置用户密码并强制在下一次登录时更改密码”这个委派任务不要顺手把“修改组成员身份”之类的权限也加上。通过委派向导生成的ACE给予的是“重置密码”权限而不是“更改密码”权限。这意味着IT支持只能重置修改完成后用户仍需要使用自己的“更改密码”权限来改密码。这条链路里用户的Change Password权限必须保留不能被删除或拒绝。5. 多域控环境下的“假故障”复制延迟、DNS与RODC还有一种情况最容易被当成玄学账户配置、ACL、策略全部检查过都正常但用户就是改密码失败或者改密码成功后马上登录另一台服务器又失败。这种多半是AD拓扑出了问题。5.1 改完密码立刻用新密码登录另一台DC失败用户在自己电脑上改了密码马上用新密码登录某个业务系统或另一台终端结果提示密码错误。这不一定是因为密码改失败了很可能是认证请求被负载均衡或DNS轮询发到了另一台还没收到密码更新通知的域控上。AD的密码修改不是全局实时同步。默认情况下密码修改会先把新密码写入当前DC然后通过复制机制传递给其他DC。跨站点复制可能延迟15分钟甚至更久。虽然Windows客户端会缓存最近一次改密的DC并优先用新密码去认证但如果你强制用IP登录或者应用服务器配置了固定的DC列表就可能碰到旧密码仍然有效的情况。碰到这种场景第一时间不要急着改策略先确认用户的密码确实改成功了再检查事件日志判断认证命中了哪台DC。5.2 DNS指向和站点覆盖导致找不到可写DC用户改密码时系统通过DNS定位域控然后向它发起LDAP或者RPC调用。如果客户端配置的DNS服务器是旧的或者站点拓扑里没有为当前子网分配合适的站点客户端可能连接到一个跨广域网的DC甚至连接到RODC。RODC上不能发起密码修改请求RODC会把请求转发给中心站点的可写DC。如果这个可写DC不可达用户就会看到“无法更新密码”之类的错误。在实际处理中RODC当机导致的批量用户改密失败并不少见。排查时优先确认客户端连的是哪台DCnltest /dsgetdc:corp.contoso.com这个命令会显示客户端当前获取的DC名称、站点名以及是否可写。5.3 排查复制与DNS的关键命令我把多域控环境常用的诊断命令整理成一套按顺序执行基本能定位问题命令作用判断要点nltest /dclist:corp.contoso.com查看域中所有DC列表是否完整dcdiag /test:replications测试DC复制状态是否有复制错误或延迟repadmin /showrepl查看复制伙伴与上次复制时间是否有长时间未复制的DCdcdiag /test:dns测试DNS解析是否有注册和解析错误nltest /dsgetdc:corp.contoso.com查看客户端实际命中的DC是否命中可写DC复制问题通常不直接表现为“改密码失败”更多是“改密码后新密码生效不一致”。如果你的用户在全域范围内分布处理问题前先跑一遍repadmin和dcdiag能省下大量后面追查的时间。6. 一套可以直接用的排错检查清单写到这里我把整个排查链路浓缩成一套固定的检查动作。以后再有用户报“改不了密码”按这个顺序走基本不会漏。6.1 从现象到根因的快速定位路径第一梯队查账户属性确认用户账户没有被锁定、没有被禁用、没有同时勾选“密码永不过期”和“下次登录须更改密码”。特别注意pwdLastSet是否为0以及userAccountControl是否正常。第二梯队查ACL用PowerShell检查ntSecurityDescriptor中是否存在拒绝Everyone更改密码的ACE。不要只看ADUC的复选框那只是表象。第三梯队查策略net accounts /domain看域密码策略Get-ADUserResultantPasswordPolicy看是否有PSO覆盖。重点关注最小密码长度、复杂性要求、最短使用期、历史记录。第四梯队查拓扑nltest看客户端连接的DCrepadmin看复制状态。如果客户端命中RODC优先确认可写DC的网络可达性。6.2 常用命令与事件日志对应关系域控上的安全日志是排查改密问题最靠谱的现场证据。Windows安全日志中有几个关键事件ID事件ID含义排查作用4723尝试更改账户密码查看修改请求是否到达DC以及结果是否成功4724尝试重置账户密码用于排查管理员重置密码的请求是否真正执行4738用户账户被更改结合此事件看账户属性或ACL是否被改动4740账户被锁定确认是否触发了账户锁定策略事件4723和4724都会记录操作者和目标账户如果用户明确在界面上点了改密码但域控日志里连4723都没有说明客户端请求根本没到达域控问题在网络层或客户端配置不用继续在AD权限上钻牛角尖。6.3 修复完成后的验证与日常预防修复后一定要让用户实际走一遍改密流程而不是只在ADUC里重置一次密码。我的验证步骤是先确认旧密码依然有效让用户登录后改成新密码再等几分钟后用新密码登录另一台业务系统验证复制是否正常。日常预防方面有三件事我现在每季度都会做把批量创建账户后检查ACL做成固定动作重点看是否带异常的Deny ACE。反向确认“最小密码使用期”是否被改过特别是安全加固过的环境。在IT支持团队的SOP里写死一条任何人帮用户重置密码后必须在工单里记录是否同时检查了“用户不能更改密码”选项。最后分享一个习惯处理完改密故障后我会顺手把域控安全日志中该时段的4723、4724事件导出一份。这些日志既能作为排查留痕也能在下次出现类似问题时快速比对省得每次都从头猜起。地修改都是基于权限控制搞清楚AD的ACL机制和密码策略联动方式比什么都管用。
返回列表