IIS 安全加固是 Windows 服务器托管站点抵御 Web 攻击的基础工程。本文面向使用 Windows Server 运行 IIS 托管 ASP.NET、PHP 等站点的运维人员,系统讲解从请求过滤、URL 授权、NTFS 权限到 TLS 版本限制的完整加固流程,所有命令均可在 PowerShell 中直接执行。
适用场景
以下场景应优先实施 IIS 安全加固:
- Windows 服务器上托管的网站曾遭受目录遍历、双扩展名绕过、文件上传攻击
- 站点被扫描器探测到敏感文件(.git、.bak、.config)可被直接下载
- 需要满足等保 2.0、PCI DSS 等合规要求中的 Web 服务器安全基线
- IIS 日志中频繁出现畸形 HTTP 请求或异常 HTTP 动词
前置条件
- 操作系统:Windows Server 2016 / 2019 / 2022
- IIS 版本:8.5 及以上(Windows Server 2012 R2 及以上自带)
- 具备本机管理员权限,可用 PowerShell 管理员窗口执行命令
原理说明
IIS 对每个 HTTP 请求的处理沿固定管线进行:请求过滤(Request Filtering)→ URL 授权(URL Authorization)→ 处理器映射(Handler Mapping)→ 身份验证(Authentication)。安全加固的本质是在管线的每个环节收紧默认策略:请求过滤在最早阶段拦截畸形与危险请求,URL 授权控制谁能访问哪个路径,NTFS 权限则决定了文件系统层的最终防线。配置可在服务器级(applicationHost.config)与站点级(web.config)两个层级叠加,站点级配置优先级更高。
操作步骤
步骤一:确认当前 IIS 版本
# 查看 IIS 版本(10.0 对应 Windows Server 2016+)
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\InetStp" | Select-Object MajorVersion, MinorVersion
步骤二:配置请求过滤(核心加固项)
# 拒绝双扩展名请求(如 shell.asp.jpg),禁止 .git、.bak 等敏感后缀
Import-Module WebAdministration
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering/fileExtensions" -Name collection -Value @{fileExtension=".git"; allowed="False"} -PSPath "IIS:\Sites\Default Web Site"
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering/fileExtensions" -Name collection -Value @{fileExtension=".bak"; allowed="False"}
# 限制 URL 长度 4096、查询字符串 2048、单文件上传 30MB
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering/requestLimits" -Name maxUrl -Value 4096
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering/requestLimits" -Name maxQueryString -Value 2048
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering/requestLimits" -Name maxAllowedContentLength -Value 31457280
# 仅允许常见动词,拒绝 TRACE、DELETE、PUT
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering/verbs" -Name collection -Value @{verb="TRACE"; allowed="False"}
Set-WebConfigurationProperty -Filter "system.webServer/security/requestFiltering/verbs" -Name collection -Value @{verb="DELETE"; allowed="False"}
步骤三:URL 授权与 NTFS 权限收紧
# 移除站点根目录的 Everyone 完全控制,仅保留 管理员/应用程序池 标识 读取
icacls "C:\inetpub\wwwroot" /remove "Everyone" /T
# 禁止通过 Web 访问敏感目录(在站点 web.config 中添加)
# <system.webServer><security><authorization><remove users="*" roles="" verbs="" /><add accessType="Deny" users="*" /></authorization></security>
web.config 中完整的 URL 授权片段:
<configuration>
<location path="App_Data">
<system.webServer>
<security>
<authorization>
<remove users="*" roles="" verbs="" />
<add accessType="Deny" users="*" />
</authorization>
</security>
</system.webServer>
</location>
</configuration>
步骤四:添加 HTTP 安全响应头
# 在站点 web.config 的 system.webServer 节点中添加
# <httpProtocol><customHeaders>
# <add name="X-Content-Type-Options" value="nosniff" />
# <add name="X-Frame-Options" value="SAMEORIGIN" />
# <add name="Referrer-Policy" value="strict-origin-when-cross-origin" />
# <add name="Strict-Transport-Security" value="max-age=31536000" />
# </customHeaders></httpProtocol>
步骤五:强制 HTTPS 并禁用旧版 TLS
# 禁用 TLS 1.0 / 1.1,启用 TLS 1.2 / 1.3(重启生效)
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" -Force
New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" -Name Enabled -Value 0 -PropertyType DWord -Force
New-Item "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" -Force
New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" -Name Enabled -Value 0 -PropertyType DWord -Force
Restart-Service W3SVC
步骤六:开启 W3C 详细日志
# 确保日志包含 User-Agent、Referer、X-Forwarded-For(反代场景)
Set-WebConfigurationProperty -Filter "system.applicationHost/sites/siteDefaults/logFile" -Name logFormat -Value "W3C"
# 通过 IIS 管理器 → 站点 → 日志 → 选择字段,勾选 User-Agent / Referer
配置验证
# 检查安全响应头
curl.exe -I https://your-domain.com
# 验证敏感后缀被拦截(应返回 404.7)
curl.exe -s -o /dev/null -w "%{http_code}" https://your-domain.com/shell.asp.jpg
# 查看请求过滤配置是否生效
Get-WebConfiguration -Filter "system.webServer/security/requestFiltering" | Select-Object -ExpandProperty Property
常见问题
Q1:开启请求过滤后正常功能返回 404.7 或 405,怎么办?
先确认具体拦截原因:404.7 为文件扩展名被拒,405 为 HTTP 动词被拒。若为合法业务(如 WebDAV 上传),在 requestFiltering 中仅对该目录单独放开,切勿全局放宽;若站点确实需要 PUT/DELETE,至少保留 TRACE 禁用,并为这些动词增加来源 IP 限制。
Q2:IIS 6(Windows Server 2003)老站如何加固?
IIS 6 已停止安全支持且不支持请求过滤高级配置,建议尽快迁移至 IIS 10(Windows Server 2019/2022)。过渡期内至少做到:禁用 WebDAV、移除不必要的 ISAPI 筛选器、开启 URLScan 3.0 等价配置、及时安装补丁。
Q3:配置了 HSTS 头后 HTTP 访问全部被拦截,如何回退?
HSTS 的 max-age 期间浏览器强制 HTTPS。回退需两步:先将 HSTS 头移除并发布 max-age=0 的响应(浏览器收到后清除策略),再修改回 http 跳转逻辑。生产环境建议先用 max-age=3600 灰度一段时间再放大到 31536000。
总结
IIS 安全加固遵循「层层设防」原则:请求过滤拦截畸形请求、URL 授权控制访问路径、NTFS 权限兜底文件系统、TLS 版本限制堵住协议层漏洞、详细日志支撑事后溯源。完成上述六步后,建议每月复查一次请求过滤规则与日志中的异常请求,并结合 WAF 形成纵深防御。