Windows站点搭建总踩坑?5步权限配置法一次到位
|
跟产品吵完接口背锅那会儿,灰度开关没推完,PM在钉钉里把接口文档撤回三次又重发,我盯着那个403弹窗看了十八秒——不是数的,是监控大屏右下角那个CPU曲线突然往下砸了一小截,抖得像有人用指甲刮黑板。去年九月,IIS站点绑完主机头,连本地环回都 401,查 Event Viewer 日志里写的是“令牌为空”,结果发现是 AppPool Identity 默认用的是 ApplicationPoolIdentity,而我们代码里硬写了 DirectoryServices 去读 AD 组——你猜它读的是谁的上下文?
文章配图,仅供参考 第一步:AppPoolIdentity 别碰,直接换成 gMSA(组托管服务账户)。这个我敢打包票,本地跑通不等于服务器跑通,服务器跑通不等于部署脚本里没手滑打成 “GmsaAccount” 而不是 “gMSA-WebSvc”。前端老张昨天还拿 PowerShell 手动 New-ADServiceAccount 时少加 -PrincipalsAllowedToRetrieveManagedPassword,结果预热阶段所有 .config 加载全卡住,日志里连 trace 都没打出来,就一个 TimeoutException 堆在 w3wp.exe 线程栈底。我原以为是 web.config 的 搞鬼,结果是账户根本没权限进 DC 的 msDS-GroupMSAMembership 属性。咖啡杯上印的公司 logo 正好裂了一道缝,从“智”字撇捺中间断开。 第二步:物理路径 ACL,别只信“编辑权限”那个 GUI 弹窗。它给你勾了“读取和执行”,但漏掉“遍历文件夹/运行文件”这个独立 flag。oncall 手机震了一下,凌晨两点十七分,测试发来截图:/api/health 返回 500,堆栈第一行是 UnauthorizedAccessException —— 可站点根目录明明给了 IIS_IUSRS 全权限。我扒进程句柄,发现 w3wp 拿着的是 w3wp.exe 的 token,而它试图打开的是 D:\\sites\\prod\\web.config,那个盘是 NTFS 格式,但父级 D:\\sites 权限继承被手动关了两次——第一次是 DBA 同事巡检时清空过,第二次是我自己上周补漏改 Registry 键值时顺手删的 DACL 备份标记。DBA 那天穿了件起球的灰T恤,袖口卷到小臂中间,他往我显示器边沿敲了三下键盘:“你这路径是不是跨卷了?” 我说没跨,他说:“哦,那你看看 D:\\ 是不是被 GPO 推了‘仅允许指定用户访问可移动驱动器’。” 我说……算了,我真说不准。 第三步:web.config 的 必须配 WindowsAuthentication = true,且禁用 AnonymousAuthentication。这点太反常识——你越想用 Windows 凭据自动透传,越要先亲手掐死匿名入口。我上个月线上翻车就是这里:启了 Windows Auth,但没关 Anonymous,结果 Kerberos 票据没发出去,系统 fallback 到 NTLM,而 NTLM 不支持跨域代理转发,所以调下游服务时 identity 丢了。测试妹子当场重启 IIS,重试三次,每次 response header 里都少了 WWW-Authenticate: Negotiate 字段。她倒了杯水回来,水杯底下压着一张便签,写着“上次上线流程 KPI 要求灰度时间 ≥2 小时,这次压缩到四十三分钟,运维那边说 logrotate 脚本没适配新路径格式”。 第四步:ApplicationInitializationModule 预热权限,很多人忽略它的 hostable WebCore 进程是在 Network Service 下启动的,不是 AppPool Identity。这就导致预热期间去读 registry、连 SQL Server、调 Azure Key Vault——全部报错。但错误全吞在 Native Host 层,IIS 日志只记个 0x80070005,Event ID 5011。我查了三个小时,在 appcmd list config /section:system.webServer/applicationInitialization 输出里才看见 这一行下面藏着个 silentFailure="false" —— 默认是 true。这玩意不开,你永远不知道 pre-start HTTP 请求卡在哪一层。我们产线有个老服务用的是 ASP.NET Core 2.2 自托管模式,Kestrel 在 System 用户下跑,结果 applicationInitializationModule 根本不触发,整个健康检查链断在第零环。 第五步:别信“回收后自动重启”——AppPool 回收后若第一个请求到来前发生内存不足或线程池耗尽,IIS 会静默拒绝初始化,且不抛任何异常。这时你看到的是 503 Service Unavailable,但 Application Pool State 显示 Running。必须配 且确保 startupTimeLimit 设置小于 90 秒。优胜劣汰?不是算法优胜劣汰,是权限配置法淘汰掉所有靠“试试看”“重启解决”“换台机器重装”的人。这个我说不准有没有普适性,但在我经手的十二个 IIS 站点里,五个撑不过两周自动降级成 Linux 容器——不是因为性能差,是运维同学嫌 audit policy 跟不上 Windows 权限变更节奏。上回上线流程卡在安全扫描环节,扫描器扫出“NT AUTHORITY\\IUSR 对 web.config 有读权限”,其实那是个假阳性,但整改单已经下了。现在我在写一个轻量 hook,等哪天 PR 合进我们的内部 CI 模板再说。 对了,昨晚 build 服务器磁盘告警,Ops 把 C:\\Windows\\Temp 清了八百次,最后发现是 W3SVC 日志轮转脚本把日志压缩包默认塞进 C 盘,而不是我们部署配置里写的 E:\\logs。没人改配置,只是脚本版本号升级了,默认行为变了。我现在盯着那个压缩包名,叫 “W3SVC1_20240903_173241.zip”,时间戳对得上去年九月我第一次栽进去那天下午五点半。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


Windows数据科学环境搭建:15年工程师避坑与高效配置
Windows运行库高效管理:打造稳定技术开发环境
Windows站点搭建的3个致命安全断点