Visual Studio 只在 VPN 下变慢?检查 CRL 与 OCSP
当 WDAC 策略生效时,一次缓慢的启动可能是吊销查询而非隧道本身。在放宽策略之前,先证明是哪一步在阻塞。
Visual Studio 在家启动正常,但同一台笔记本接入公司隧道后,每次启动都会在启动画面停留半分钟。移除策略,卡顿随之消失;移除隧道,同样的情况也会出现。两种观察都准确,所以这两个组件总是互相背锅。决定性的问题是:证书吊销查询是在等待只有隧道才提供的路径,还是根本找不到路径。
测的是获取耗时,不是启动耗时
一份 WDAC 策略,以已签名的 SiPolicy.p7b 形式部署,决定哪些映像可以在机器上运行。代码完整性会在执行前验证映像的签名链,而这项验证可能包含吊销问题。答案取决于证书内部指定的 CRL 分发点或 OCSP 响应器。
这些是普通网络请求,因此其开销取决于响应器所在的位置。当它只能通过隧道访问,或者 其名称只能通过隧道之后的 DNS 服务器解析时,验证就会等待隧道就绪。Visual Studio 启动时会加载大量已签名的程序集和扩展,每个映像的小延迟累积成可见的停顿。没有任何东西损坏,策略完全按配置运作,所以移除策略看起来修好了问题。
每个已签名映像都可能触发网络调用
先从磁盘上已有的已签名二进制文件开始,让平台用与启动时相同的获取行为去验证它。分别在隧道内和隧道外各运行一次,然后比较获取记录,而不是只看最终结论。
certutil -verify -urlfetch C:\Tools\Contoso.Editor.dll
nslookup ocsp.contoso.example
Test-NetConnection ocsp.contoso.example -Port 80
输出会列出证书链、CRL 与 OCSP 地址,以及每次获取是否成功。在隧道内超时、在隧道外能应答的响应器,就是需要的证据,它比「感觉慢」有分量得多。如果获取缓慢但成功,记下该地址,下一步就能直接测试那台主机。
解析响应器的主机名,并在应用之外测试可达性,因为无法解析的名称永远不会被任何客户端设置修好。CodeIntegrity 操作日志提供证据的另一半,把验证事件与缓慢启动的时间戳对应起来。
缩短延迟,而不是移除控制
关闭策略或改为审核模式会让延迟消失,同时也移除了组织部署的控制,所以应视为错误的修复。更窄的选项包括:调整路由让响应器可经隧道访问、为响应器主机在拆分隧道中加入例外、在名称解析到不可达地址时修正 DNS,或为吊销数据使用受支持的缓存代理。每一项都有不同的负责人:PKI 团队负责响应器可达性,网络团队负责隧道拆分,终端团队负责策略。
把每个吊销主机都排除在隧道之外并不自动安全,因为内部响应器可能是有意设在内部的。写规则之前,先与运行 PKI 的团队确认这项例外,否则这条规则会悄悄把证书检查发到公网。没有这项确认的改动,往往会在下一次策略刷新时被回滚。
变更后验证冷启动
在两种状态下各测一次冷启动并保留数据,因为程序集进入缓存后,热启动几乎证明不了什么。从全新会话重复一次启动,让扩展加载路径再次被执行。
Get-WinEvent -LogName Microsoft-Windows-CodeIntegrity/Operational -MaxEvents 40 |
Where-Object { $_.TimeCreated -gt (Get-Date).AddMinutes(-10) }
Get-ChildItem C:\Windows\System32\CodeIntegrity\CiPolicies\Active
Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard
修复后的配置仍会联系响应器,或使用 PKI 团队批准的缓存路径,日志显示验证完成而不是超时。确认新签名的应用仍能启动,因为允许一切的策略不算成功的修复。也要检查活动策略文件夹和强制状态,确保正在调试的策略就是实际运行的那一个。把证书链、响应器地址和启动时间戳放在同一张工单里,因为续期通常会迁移响应器,并让例外或 DNS 规则过期。