每天都在打补丁,每天都在失败:Windows Update 与那条被收掉的 HTTP/80
缘起
preprod 里有个维护窗口:nusa-preprod-windows-patch,每天凌晨 03:17(Asia/Singapore)跑 AWS-RunPatchBaseline,目标是两台带 PatchGroup=preprod-windows 的 PowerBI Gateway。
某天随手翻了一下执行历史,发现一件不太妙的事:
从 6 月 25 号到 7 月 24 号,最近三十来次执行,全部 Failed。
不是偶发超时,不是某一台掉线,是窗口级天天红。SSM Agent 在线,机器也跑着,任务确实打上去了——然后挂在 Windows 补丁搜索这一步。
现象
错误信息不长,但很「经典」:
1 | An error occurred when attempting to search Windows Update. |
微软文档对 0x80072F8F 的第一反应通常是:
- 系统时间不准,SSL 证书日期校验失败;
- 或者证书链不被信任(常见于自家 WSUS / 自签证书)。
第一眼很容易往「时钟漂了」上想。毕竟这两台在私有子网,出网靠 NAT,SG 出站又收得很紧——万一 NTP 不通,时间漂一个月,证书校验挂掉,说得通。
于是先查时间线,再上机验证。
时间线对上了,但不是你想的那个故事
先把 Git 和维护窗口摆在一起看:
| 时间 | 发生了什么 |
|---|---|
| 6/23 03:17 | 最后一次补丁成功(当时还只有 gateway-1) |
| 6/23 晚上 | 安全收紧:PowerBI SG 的 HTTP/80 从 0.0.0.0/0 收到 169.254.0.0/16 |
| 6/25 03:17 | 起,维护窗口开始天天 Failed |
| 6/25 白天 | 又补了一刀:link-local 放开全协议,修好到 Amazon Time Sync 的 UDP/123;但公网 HTTP/80 没有恢复 |
成功补丁停在「收紧 HTTP」之前;失败从收紧之后的第一个维护窗口开始。相关性高得有点过分。
再看一眼当前 SG 实际放行什么:
- VPC 内网:全通
- 互联网:只有 TCP 443
- link-local
169.254.0.0/16:全通(含 NTP)
而同仓库里 dev / qa 的 PowerBI Gateway SG,仍然保留着 0.0.0.0/0:80。preprod 成了特例。
上机诊断:时钟是无辜的,80 端口不是
在两台机上跑了只读探测(时间、NTP、443、80、几个 Microsoft URL)。结果两边几乎一字不差:
时间正常。
1 | DateTime: 2026-07-24T04:42:42Z |
Amazon Time Sync 在干活,Stratum 正常。所以「证书日期无效」这条线,至少对现在不成立。
443 也正常。
1 | TCP 443 -> sls.update.microsoft.com : True |
80 全灭。
1 | TCP 80 -> download.windowsupdate.com : False |
Windows Update 官方要访问的那一串地址里,至今仍有大量 http://... 端点。你只放 443,等于让 WU Agent 去跑一场缺了半条腿的搜索。
于是 Patch Manager 的故事就变成了:
- 维护窗口准点触发;
AWS-RunPatchBaseline打到两台 Online 的 Windows;PatchWindows调IUpdateSearcher.Search;- 搜索阶段触达需要 HTTP 的更新端点;
- 被 SG 丢掉;
- 表层报成
0x80072F8F; max_errors = 1,整窗 Failed。
调度没问题,NAT 没问题,Agent 没问题,时间也没问题。少的就是那条 TCP/80。
为什么错误码会骗人
0x80072F8F 在微软文案里被写成 SSL / 时钟问题,并不等于现场永远是时钟问题。
这次诊断里,HTTPS 到 sls.update.microsoft.com 已经能完成 TLS;真正稳定复现的,是 HTTP/80 被拒。结合 6/23 那次「只留 443、收掉公网 80」的变更,根因应落在出网上,而不是再去重装一堆根证书、或者怀疑系统日期跳到了 1970。
另外,6/23 到 6/25 之间,NTP(UDP/123 到 link-local)确实也曾一度不通——那几天如果刚好撞上时钟偏差,错误码看起来会更「像教科书」。但 6/25 修完 Time Sync 之后,失败还持续了整整一个月。说明真正让它日复一日挂着的,不是时钟,是 HTTP。
修复
很土,但有效:把 HTTP/80 加回去,跟 dev / qa 对齐,并在注释里写清楚为什么不能再「顺手」收掉。
1 | # Windows Update still requires HTTP (e.g. download.windowsupdate.com). Without this, |
原则就一句:
安全收紧可以,但别把业务依赖的协议通道当成「多余的 80」一起砍。
Windows Update 不是只走 HTTPS 的现代 SPA。
Apply 之后,建议手动跑一次 Scan / Install 验证,别等第二天凌晨再看红绿。
一点感想
这事有个很典型的运维味道:
- 监控面上,维护窗口「有在跑」;
- 错误码面上,像是「证书 / 时间」;
- Git 历史上,是一次「看起来更安全」的 egress 收紧;
- 实例面上,443 绿灯会让人误以为「出网没问题」。
把这四层叠在一起,才能看到真相:
出网不是「有没有网」,而是「缺了哪一种协议、到哪一类域名」。
下次再看到 Patch Manager 天天 Failed、错误又是 0x80072F8F,我会先做三件事:
- 看最近有没有动过 Windows 实例的 SG egress;
- 看 HTTP/80 和 HTTPS/443 是否都通到 Microsoft Update 域名;
- 再用
w32tm确认时间——而不是一上来就只信错误码的字面意思。
坑不深,但藏在「我们为了安全做对了的那次变更」里。