锦
锦思新知编辑组
发布时间:2026/11/9 3:43:04
来源:锦思新知
阅读:知识向官网定制

智能卡插在读卡器里远程桌面连到一台还在服役的 Windows Server 2008 R2证书选完、PIN 输完进度条刚转两圈窗口就没了客户端弹出“终端服务器安全层在协议流中检测到错误并已断开客户端连接”服务器侧安全日志里对应一条STATUS_LOGON_TYPE_NOT_GRANTED。这个组合我前后处理过好几次每次都会有人在网络层、防火墙、MTU 上耗掉大半天最后发现问题根本不在传输上。这篇就把这条报错从“客户端看到的一句话”拆到“服务器日志里的一行状态码”把智能卡远程登录在域环境里要过的三道关、证书链上每一环的检查点、以及授权层那几个容易被组策略悄悄改掉的开关一次讲透。适合正在维护老系统、被智能卡域远程桌面三件套卡住的朋友也适合想搞清楚 NLA 和 PKINIT 到底谁在干什么的人。1. 这条报错其实是两个错误叠在一起先说最容易走偏的地方。很多人看到“终端服务器安全层在协议流中检测到错误”第一反应是网络抖动、链路 MTU 不对、中间设备篡改于是抓包、改 MTU、换交换机折腾一圈毫无进展。原因在于这句话描述的只是连接被谁掐断的而不是为什么被掐断的。1.1 表象层协议流被安全层主动掐断远程桌面建立会话是分阶段推进的粗略分四段TCP 三次握手到 3389X.224 连接请求与安全层协商RDP 标准安全层或者 TLS如果启用了网络级身份验证NLA再做一轮 CredSSP 交换最后才是把身份交给本地安全机构做登录产生一个“登录类型”并做授权判断。“终端服务器安全层在协议流中检测到错误”这句话是第二段或第三段抛出来的。它对应服务器系统日志里TermDD来源的 56 号事件本质含义是安全层期望收到一段符合协议规范的数据实际收到的数据对不上于是它选择直接断开而不是继续猜。这句话本身信息量极低因为它只说明“协议流不合规”不说明“为什么不合法”。1.2 根因层STATUS_LOGON_TYPE_NOT_GRANTED 是拒绝理由不是断链原因真正的信息在后面那个状态码上。STATUS_LOGON_TYPE_NOT_GRANTED转成十六进制是0xC000015B含义非常明确请求的登录类型没有被授予这个用户。注意它的措辞不是“密码错”不是“账户被锁”不是“证书无效”而是“这种登录方式你没权限用”。我的理解是启用 NLA 之后服务器在 CredSSP 阶段其实已经把身份验证做完了——它知道你是谁也确认了你的智能卡证书合法。但紧接着的授权检查发现这个账户不允许以“远程交互式登录”这种类型进来于是整轮交换以失败收场。CredSSP 返回的是一个客户端不容易映射成友好提示的错误状态RDP 客户端解不出来就退化成了那句笼统的“协议流错误”。这条路我在现场验证过同一台服务器、同一张卡把 NLA 关掉再连客户端提示就变成了能看懂的“您没有远程登录的权限”之类的话服务器日志里依然是 0xC000015B。也就是说状态码才是主线协议流错误只是它在 NLA 模式下的马甲。1.3 为什么智能卡场景特别容易叠出这种报错纯密码登录时如果用户不在远程桌面用户组很多系统会直接给出比较明确的提示排查路径也短。智能卡不一样它把“认证”和“授权”之间插进了证书映射、KDC 换票、EKU 校验这一大串环节任何一个环节失败都可能被上层折叠成同一句话。更麻烦的是这类环境往往版本偏老。Windows 7 客户端和 Windows Server 2008 R2 服务器默认使用的还是 TLS 1.0 那一套后来的补丁又往里面加过“加密 Oracle 修正”这种会改变 CredSSP 版本协商行为的开关。补丁级别不一致的两台机器放一起报错文本几乎一模一样但根因可能天差地别。所以第一步不是动手改而是把错误分层。下面这张表是我自己排查时常用的对照先确定自己落在哪一行再往下走。现象大概率所在层首要检查点弹出协议流错误服务器 TermDD 事件 56无 4625安全层协商TLS/证书服务器 RDP 证书、TLS 版本、加密 Oracle 修正值弹出协议流错误同时有 4625 且状态 0xC000015B授权层登录类型远程桌面登录权限、拒绝策略能连上但卡在“正在配置远程会话”会话层用户配置文件、组策略登录脚本直接提示证书无效或凭据不对认证层智能卡证书、NTAuth 存储、KDC 证书2. 智能卡远程登录这条链上到底有几次身份验证要定位问题得先知道一次智能卡远程登录到底走了几遍身份。很多人以为“插卡输 PIN 就完事了”实际上在域环境里这个过程至少要完成三轮彼此独立的校验任何一轮失败最终表现都可能长成同一副样子。2.1 第一次CredSSP 拿证书向服务器证明“我是谁”启用 NLA 之后客户端在会话建立之前就要先完成一次身份验证走的是 CredSSP 协议底下垫的是 TLS。客户端把智能卡里的证书和签名结果送过去服务器验证这个签名并顺着证书链一路验到根。这一轮的关键在于服务器信任不信任这张卡背后的 CA以及服务器的 TLS 证书客户端认不认。两边任何一边的信任链断了握手就停在这里。这一层的典型表现是连接刚发起就被断开服务器日志里只有 TermDD 事件没有安全日志的登录记录。2.2 第二次Kerberos PKINIT 向 KDC 换票据CredSSP 通过之后真正的域身份验证才刚开始。智能卡登录在 Kerberos 里走的是 PKINIT 扩展客户端用私钥签一段预认证数据发给域控域控验证签名、校验证书然后签发 TGT。这一轮对证书的要求最苛刻也是老环境里最容易出问题的地方。KDC 在验签时至少要看三件事智能卡证书本身是否在有效期内、没有被吊销签发这张卡的 CA 是否被登记在NTAuth存储里域控自己有没有一张带“智能卡登录”用途的证书。第三条最容易被忽略——很多人把卡配得好好的却不知道域控的证书模板选错了PKINIT 直接谈不下去。2.3 第三次会话管理器按登录类型做授权票据拿到了会话也建起来了最后一关是授权。用户身份交给本地安全机构它会根据这次登录的来源判定登录类型。远程桌面登录对应的是远程交互式登录登录类型 10系统会去查两件事这个账户有没有被授予“允许通过远程桌面服务登录”的权限有没有哪条策略明确“拒绝通过远程桌面服务登录”。这两条只要有一条不满足就会返回 0xC000015B。注意拒绝策略的优先级高于允许策略这是 Windows 用户权限模型里一贯的规则后面还会再提。把这三轮串起来看就清楚了前两轮是“你是谁”第三轮是“你能不能以这种方式进来”。协议流错误出现在前两轮但它的根因完全可能来自第三轮——因为 NLA 把三轮压在了会话建立之前授权失败会让整轮交换整体失败客户端只能看到最外层那个报错。3. 证书链上每一环的核对清单证书这条线是智能卡场景的重灾区因为它牵涉的角色多而且每个角色需要的用途EKU都不一样。我习惯按“卡 → 域控 → 服务器 → 客户端信任”这个顺序逐个过一遍比东一榔头西一棒子效率高得多。3.1 智能卡证书本身有效期、模板、私钥与主体先看卡里的证书。在客户端上打开证书管理查看“个人”存储里的那张卡证书重点看四项。第一是有效期。这类老环境经常出现证书过期很久没人换的情况因为平时大家都用密码登录卡只是备选。过期证书在 PKINIT 阶段会直接失败而且错误被折叠之后看不出是过期。第二是密钥用途。智能卡登录要求证书里包含智能卡登录 EKUOID 是1.3.6.1.4.1.311.20.2.2通常还会带上客户端身份验证。如果这张卡是用某个自定义模板签发的模板里漏了这个用途卡能用来做别的比如邮件签名但登不了域。第三是私钥是否可读。有些读卡器驱动装得不完整证书能列出来私钥却调不出来签名操作直接失败。这种情况在设备管理器里未必有黄色感叹号只能靠实际签名测试。第四是主体名称与账户映射。域里可以靠altSecurityIdentities属性显式把证书映射到账户也可以靠主体名称里的 UPN 自动匹配。如果映射不上KDC 找不到对应账户报的是另一类错误但在客户端看来同样只是“连不上”。3.2 KDC 证书没有智能卡登录 EKUPKINIT 直接跪这是我最想强调的一条。域控要能处理智能卡登录自己必须持有一张合适的证书通常来自“Kerberos 身份验证”这个模板里面包含客户端身份验证和智能卡登录两个用途。如果域控只有一张老的“域控制器”模板证书那张证书里没有智能卡登录用途PKINIT 就走不通。检查方法很直接在域控上执行certutil -store My看输出里每张证书的“证书模板”和“增强密钥用法”两栏。如果找遍整个“个人”存储都没有带智能卡登录用途的证书那问题基本就锁定在这里了。补发的办法是在证书服务里基于正确模板申请一张或者用组策略做自动注册。顺带说一个坑域控换证书之后新的根证书和中间证书要同步分发到客户端否则客户端验不过域控的证书链。有些环境里根证书是手工导入的域控换了签发 CA 之后只更新了服务器客户端还揣着旧根表现就是“有的机器能登有的机器不能”特别迷惑人。3.3 RDP 服务器证书与客户端信任服务器这一侧的 TLS 证书是 CredSSP 的地基。如果这台 2008 R2 的 RDP 监听器用的还是安装时自签的那张证书客户端默认会做服务器身份验证验不过就可能中断。要区分两种模式安全层设为“协商”时客户端和服务器会尝试用 TLS失败可以退回标准 RDP 安全层安全层被策略强制成“SSL”时没有退路证书不合规就直接断。另外别忘了NTAuth 存储这一环。签发智能卡证书的那个 CA必须被登记为企业级的 NTAuth CA否则域控不认这张卡做登录凭证。检查命令certutil -viewstore -enterprise NTAuth输出里应该能看到签发 CA 的证书。如果没有需要用证书颁发机构管理工具把它发布进去或者用certutil -dspublish -f ca.cer NTAuthCA手工登记然后等域内复制完成。下面这张表是我自己用的核对清单出问题时从上往下过一遍基本能覆盖八成情况。角色需要的用途检查命令常见故障智能卡证书智能卡登录 客户端身份验证certutil -store My模板选错、证书过期、私钥不可读KDC 证书智能卡登录 客户端身份验证域控上certutil -store My模板过老、缺 EKU、链不完整RDP 服务器证书服务器身份验证RDP 监听器属性里看自签名、过期、主体名不匹配签发 CA需登记进 NTAuthcertutil -viewstore -enterprise NTAuth未登记、复制未完成根证书客户端需信任客户端“受信任的根”存储换 CA 后未同步4. STATUS_LOGON_TYPE_NOT_GRANTED授权层的四种典型成因状态码已经把话说得很白了问题出在“登录类型没被授予”。但落到具体环境里导致这件事发生的原因有好几种而且彼此会互相掩盖。下面按我遇到的频率从高到低排。4.1 远程桌面用户组与 SeRemoteInteractiveLogonRight最直接的一条账户既不在服务器的本地“远程桌面用户”组里也没有被单独授予“允许通过远程桌面服务登录”这个用户权限。很多人有个误解以为“域管理员”天然能远程登录任何机器。默认情况下域管理员组确实在很多机器的本地管理员组里而本地管理员组默认拥有这个权限所以平时看不出问题。但只要有人动过用户权限分配把“允许通过远程桌面服务登录”从默认值改成了某个特定组域管理员也可能被挡在外面。检查方法在服务器上导出安全策略secedit /export /cfg C:\temp\secpol.txt /areas USER_RIGHTS findstr /i RemoteInteractive C:\temp\secpol.txt输出里会有两行一行是SeRemoteInteractiveLogonRight允许一行是SeDenyRemoteInteractiveLogonRight拒绝。看允许那一行里到底列了哪些组再看目标账户是不是这些组的成员。注意这里显示的是 SID 而不是组名需要自己换算一下。4.2 拒绝策略比允许策略优先这是最容易让人抓狂的一条。账户明明在允许列表里还是被拒。原因就是另一条策略把它显式拒绝了。默认的“拒绝通过远程桌面服务登录”里通常包含Guests、Support_388945a0之类的账户但如果有人在域级别或者某个 OU 上做了一条策略把某个业务组塞进了拒绝列表那这个组里的所有人都会中招而且从允许列表上完全看不出问题。排查的时候一定要两行都看只看允许那行等于白看。我在一个环境里遇到过某次安全加固把“拒绝”列表填成了“Domain Users”本意是想限制一批外包账号结果把全体域用户都拒了表现就是所有人远程登录都返回 0xC000015B但本地登录一切正常。4.3 账户“交互式登录需要智能卡”标志与实际证书不匹配账户属性里有一个选项叫“交互式登录需要智能卡”。勾上之后这个账户就只能用智能卡登录密码彻底失效。这个设计本身没问题但在混合环境里容易出岔子。比如某台服务器上还跑着依赖密码认证的服务或者某台机器上的智能卡中间件版本太老读卡失败后退回密码认证这时候就会撞上这个标志。表现出来不是“证书无效”而是登录被拒。还有一种情况账户勾了这个标志但用户的卡换过新证书没有正确映射到账户或者旧证书还挂在altSecurityIdentities里没清掉。域控在 PKINIT 阶段找不到匹配项最终也会落到授权失败这一侧。4.4 组策略覆盖与本地策略的先后用户权限分配属于“安全设置”它的生效规则是域级策略覆盖 OU 级OU 级覆盖站点级实际顺序更细但大方向是这样最后本地策略垫底。也就是说如果域里有一条策略定义了“允许通过远程桌面服务登录”那么服务器本地再怎么改都不生效。这种“改了没反应”的情况特别消耗耐心。判断方法是用gpresult生成一份结果报告看最终生效的是哪条策略、来自哪个 GPO。养成改之前先看一眼结果集的习惯能省掉大量来回。gpresult /h C:\temp\rsop.html打开生成的报告找“安全设置 → 用户权限分配”那一节里面会明确列出每条权限的最终值和来源 GPO。这比在组策略管理控制台里一层层点开找快得多。5. 安全层、加密级别与那些年久失修的默认值授权层排查完还没解决就得回头看安全层本身了。这块的麻烦在于同样一句“协议流错误”可能是三个完全不同的开关造成的。5.1 SecurityLayer 与 UserAuthentication 的组合矩阵RDP 监听器上有两个关键开关都存在注册表里reg query HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp /v SecurityLayer reg query HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp /v UserAuthenticationSecurityLayer的取值0 表示只用标准 RDP 安全层1 表示协商2 表示强制 TLS。UserAuthentication的取值0 表示不要求 NLA1 表示要求 NLA。两个开关交叉起来行为差异很大。SecurityLayerUserAuthentication实际行为适用场景1协商0优先 TLS失败退回标准层兼容性最好的默认值1协商1强制 NLA必须 TLS现代环境常用2强制 TLS0只走 TLS无退路需要加密但不要求 NLA2强制 TLS1最严格证书不合规必断高安全要求环境0标准层1矛盾组合常直接失败应当避免最后那一行是重点。标准 RDP 安全层本身不提供 NLA 所需的通道两个设置互相打架结果就是连接刚建立就被断。这种配置通常是有人为了“解决连不上”把安全层改成了 0忘了 NLA 还开着。5.2 加密 Oracle 修正值补丁级别不一致时的隐形杀手这个开关是后来才加的专门处理 CredSSP 的版本协商。它有三个档位强制更新客户端、已缓解、易受攻击。客户端和服务器的档位如果不匹配握手阶段就会失败。默认值通常是“已缓解”这个档位能和“已缓解”以及“易受攻击”的对端通信但不能和“强制更新客户端”的对端通信。如果一台机器被某次安全加固改成了“强制更新客户端”另一台还是老版本没打补丁两边就谈不拢。检查命令reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle取值 0 是强制更新客户端1 是已缓解2 是易受攻击。这个键默认可能不存在不存在时按“已缓解”处理。要临时验证是不是这个原因可以把它设成 2 测一下reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\CredSSP\Parameters /v AllowEncryptionOracle /t REG_DWORD /d 2 /f改完需要重启相关服务或重启系统。验证完一定要改回去把档位长期停在“易受攻击”是个坏习惯尤其这类机器往往还在内网横着走。正确的做法是两边都打齐补丁统一到“已缓解”。5.3 TLS 版本与 RDP 8.x 的 UDP 传输老系统默认启用的还是 TLS 1.0。如果某次加固在客户端上把 TLS 1.0 关了只留 1.2而 2008 R2 这边没有打上支持 1.2 的补丁握手就谈不成表现同样是安全层报错。判断方法不难用任何能测 TLS 握手的小工具连一下 3389看能不能协商出共同版本。或者在客户端临时把 TLS 1.0 打开如果立刻能连上那方向就对了。长期方案当然是给服务器补齐补丁并开启 1.2而不是把客户端的限制放开。还有一条容易被忽略Windows 7 装了 RDP 8.x 之后会尝试用 UDP 传输做优化。某些网络环境下 UDP 走不通表现就是连接时好时坏或者干脆在协商阶段断掉。测试时可以把传输协议锁成只用 TCPreg add HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services /v SelectTransport /t REG_DWORD /d 1 /f取值 1 表示只用 TCP0 表示两者都用。这条不是主因但在“时好时坏”的场景里值得顺手试一下。6. 一次完整的现场排查从 .rdp 变量控制到日志对时上面讲的都是知识点落到现场得有顺序。我习惯用“变量控制”的方式推进一次只改一个条件让现象自己告诉你是哪一层的问题。下面这套流程走过很多次比较稳。6.1 第一步做一个可控的 .rdp 测试样本不要直接用远程桌面连接界面点界面上的选项会影响判断。手工建一个文本文件后缀改成.rdp内容如下full address:s:192.0.2.10 username:s:testuser enablecredsspsupport:i:1 authentication level:i:2 negotiate security layer:i:1几个参数的含义enablecredsspsupport控制是否走 NLAauthentication level控制服务器身份验证的严格程度0 是不验证2 是必须验证negotiate security layer控制安全层是否可协商。用这个文件做基线后面每次只改一行就能精确定位。6.2 第二步用“关掉 NLA 还能不能连”做二分把enablecredsspsupport:i:1改成0再连一次。这一步是整个排查的分水岭。如果能连上说明证书链和 Kerberos 这条线基本是通的问题集中在 CredSSP 相关的配置上——加密 Oracle 修正值、服务器 TLS 证书、TLS 版本逐个排。如果还是连不上而且提示变成了“没有远程登录权限”之类更明确的话那就印证了前面的判断认证没问题卡在授权。这时候直接跳到第 4 节那四条去查不要再看证书了。如果关掉 NLA 之后报的是别的错比如证书相关的提示那说明认证层本身有问题回到第 3 节。这一步的价值在于把三层错误强行分开避免在一堆互相掩盖的现象里绕圈。6.3 第三步服务器端日志对时与 4625 细节字段客户端的话只能当线索服务器日志才是证据。在服务器上打开事件查看器同时看两个位置系统日志里TermDD来源的事件和安全日志里的 4625登录失败。关键在于对时间戳。如果 TermDD 事件和 4625 出现在同一秒或相邻一两秒那基本可以确定是同一件事的两面授权失败导致 CredSSP 整体失败安全层随之中断。如果只有 TermDD 事件、完全没有 4625那说明身份根本没送到授权环节问题在前面的握手。点开 4625 看细节字段重点关注三个登录类型应该是 10、状态代码0xC000015B、子状态代码。子状态有时能进一步缩小范围。另外注意“登录进程”和“身份验证包”两栏如果身份验证包显示的是 Kerberos说明已经走到 PKINIT 了如果显示 NTLM 或者别的那说明智能卡认证根本没生效客户端退回了别的认证方式。顺便看一眼Microsoft-Windows-TerminalServices-LocalSessionManager/Operational和RemoteConnectionManager/Operational这两个日志里面会记录会话建立和断开的顺序能帮你还原时间线。6.4 第四步改完之后的回归验证改完配置不要只测一台机器、一个账号。智能卡环境的特点是个体差异大A 的卡能用不代表 B 的卡能用。我的做法是准备一个小矩阵两台客户端一新一旧、两个账号一个刚换过卡、一个用的老卡、两种登录方式智能卡、密码。全部过一遍再收工。回归时重点看两件事一是服务器日志里不再出现 4625 的 0xC000015B二是客户端不再出现协议流错误。两条都满足才算真解决。只满足第二条有可能是把 NLA 关了换来的假象下次策略一刷新又回来了。7. 一些踩过之后才记住的细节别在客户端上找答案。这条报错的文本是客户端给的但它的真正含义藏在服务器的安全日志里。我见过太多次客户端上换版本、清缓存、重装中间件全是无用功服务器上一看 4625 就知道怎么回事。养成先连服务器看日志的习惯能省一半时间。改配置前先存一份基线。老环境的配置往往被历任管理员改得面目全非你以为是默认值的地方早就不是了。把SecurityLayer、UserAuthentication、AllowEncryptionOracle、用户权限分配这几项先导出存一份出问题能快速回滚也方便对比“改之前是什么样”。“临时改成易受攻击”这种做法只能用来验证。验证完必须改回去而且要在变更记录里写清楚。我遇到过一台机器两年前为了排查临时把档位调低了之后一直没人管成了环境里一个长期的隐患点。验证和修复是两件事别混。域控换过证书的环境客户端一定要跟着更新根证书。这类问题最阴险的地方在于它是“部分机器出问题”很容易被误判成“某几台电脑有毛病”。实际上是那几台机器的根证书存储没更新。遇到“有的人能登有的人不能登”先怀疑信任链差异而不是怀疑用户。智能卡登录的排错顺序建议固定下来卡 → 域控 → 服务器 → 客户端 → 授权。这个顺序不是随意的它按“失败概率从高到低”排也按“改一项影响面从小到大”排。从卡开始改影响面最小从域控开始改一改全环境受影响。先做低风险验证再做高风险变更。最后提一个容易被忘的点时间。Kerberos 对时间偏移有硬性要求默认容忍五分钟。老机器的 CMOS 电池、虚拟化平台的时钟同步、时区设置任何一个出问题都可能让 PKINIT 失败。这类故障的特点是“过一段时间自己好了”或者“重连几次偶尔能进”遇到这种飘忽的现象先对一下服务器和域控的时间比查证书快得多。如果这台机器还要继续服役考虑把 NLA 和智能卡登录的组合做一次完整的文档化。包括用的是哪个模板、哪个 CA、根证书怎么分发、用户权限分配给到了哪个组。这类环境往往人手换了几轮配置的来龙去脉全靠口口相传下一次出问题还得从头查一遍。花半小时写清楚后面能省掉很多重复劳动。
知识建站
内容驱动
阅读友好版式
SEO 精细化
线索转化
这篇内容对您有启发吗?
预约一次免费方案沟通,我们会根据您的行业给出可落地的站点架构建议。
立即预约沟通