2026.05.26 | youres | 13次围观
# HSTS响应头缺少includeSubDomains修复:子域名安全漏洞彻底解决方案
## 前言
最近在给一个网站做安全响应头配置审计时,发现一个很典型的问题:主域名配置了HSTS,但缺少`includeSubDomains`指令。这个看似小小的遗漏,实际上给整个域名体系留下了一个不小的安全隐患。
今天这篇文章,就是把这个问题的来龙去脉讲清楚,顺便给出完整的修复方案。文章会覆盖Nginx、Apache、IIS等主流Web服务器的配置方法,以及如何验证修复是否生效。
## 什么是includeSubDomains?
先复习一下HSTS(HTTP Strict Transport Security)的基本原理。HSTS是一个安全响应头,用来告诉浏览器:"这个网站只允许HTTPS连接,不要用HTTP访问我"。
而`includeSubDomains`是HSTS的一个可选指令,它的作用是:**把这条强制HTTPS的规则,也应用到所有的子域名**。
一个标准的、完整的HSTS响应头应该是这样的:
```
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
```
三个指令的含义:
- `max-age=31536000`:告诉浏览器缓存这个规则31536000秒(1年)
- `includeSubDomains`:规则同时适用于所有子域名
- `preload`:同意被加入到浏览器的HSTS预加载列表
## 缺少includeSubDomains的风险
如果只配置了`max-age`而没有`includeSubDomains`,会出现什么问题?
**问题核心:子域名仍然可以通过HTTP访问**
举个例子:
- 主域名:`example.com`(配置了HSTS,但没有includeSubDomains)
- 子域名:`admin.example.com`(可能根本没有配置HTTPS)
这种情况下:
1. 用户访问 `https://example.com` 后,浏览器会记住这个站点只能用HTTPS
2. 但是访问 `http://admin.example.com` 或者 `https://admin.example.com` 时,浏览器**不会**强制跳转HTTPS
3. 攻击者可以对子域名实施**降级攻击**(Downgrade Attack)或者**cookie劫持**
### 实际攻击场景
假设你的主站 `example.com` 配置了HSTS,但 `api.example.com` 没有:
1. 用户连上了一个恶意WiFi(咖啡厅、机场等)
2. 攻击者作为中间人,拦截了用户发往 `api.example.com` 的请求
3. 即使用户想访问HTTPS版本的API,攻击者也可以把请求降级到HTTP
4. 因为缺少`includeSubDomains`,浏览器不会阻止这个降级行为
5. 攻击者在HTTP明文流量中截获了用户的session cookie或者API token
这个漏洞在现实中被多次利用,特别是在那些有大量子域名的企业应用中。
## 如何检测是否缺少includeSubDomains?
有三种快速检测方法:
### 方法1:使用curl命令
```bash
curl -I https://example.com
```
查看响应头中是否有:
```
Strict-Transport-Security: max-age=31536000
```
如果看到了HSTS头,但没有`includeSubDomains`,那就是缺少了这个指令。
### 方法2:使用浏览器开发者工具
1. 打开Chrome/Firefox开发者工具(F12)
2. 切换到Network(网络)标签
3. 访问你的网站
4. 点击第一个请求,查看Response Headers(响应头)
5. 找到`Strict-Transport-Security`这一行
### 方法3:使用在线检测工具
推荐两个工具:
- **Security Headers**(https://securityheaders.com):输入域名,一键检测所有安全响应头
- **Mozilla Observatory**(https://observatory.mozilla.org):更详细的安全评分和建议
这两个工具都会明确指出你的HSTS是否缺少`includeSubDomains`。
## Nginx修复方法
Nginx的配置非常直接,在`nginx.conf`或者站点配置文件的`server`块中添加:
```nginx
server {
listen 443 ssl;
server_name example.com;
# 其他SSL配置...
# HSTS配置(包含includeSubDomains)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# ...
}
```
### 关键点说明
1. **必须加`always`参数**:Nginx的`add_header`指令默认只在成功响应(2xx和3xx)时添加头信息。加上`always`后,错误页面(4xx、5xx)也会返回HSTS头。
2. **HTTP到HTTPS的重定向也要配置**:
```nginx
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
```
3. **测试配置是否正确**:
```bash
nginx -t
```
4. **重新加载配置**:
```bash
systemctl reload nginx
# 或者
nginx -s reload
```
## Apache修复方法
Apache需要在虚拟主机配置或者`.htaccess`文件中添加:
### 方法1:修改虚拟主机配置(推荐)
在`/etc/apache2/sites-available/your-site.conf`或者`httpd.conf`中:
```apache
ServerName example.com
# 其他SSL配置...
# HSTS配置
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# ...
```
### 方法2:使用.htaccess文件
如果你的站点使用`.htaccess`,在网站根目录的`.htaccess`文件中添加:
```apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
```
### 关键点说明
1. **确保`mod_headers`模块已启用**:
```bash
a2enmod headers
systemctl restart apache2
```
2. **测试Apache配置**:
```bash
apache2ctl configtest
```
3. **重新加载配置**:
```bash
systemctl reload apache2
```
## IIS修复方法
在IIS中配置HSTS需要通过HTTP响应头设置:
### 方法1:使用IIS管理器(GUI)
1. 打开IIS管理器
2. 选择你的站点
3. 双击"HTTP响应头"
4. 点击"添加"
5. 名称:`Strict-Transport-Security`
6. 值:`max-age=31536000; includeSubDomains; preload`
7. 点击"确定"
### 方法2:修改web.config文件
在站点根目录的`web.config`文件中添加:
```xml
```
### 方法3:使用PowerShell
```powershell
Import-Module WebAdministration
Set-WebConfigurationProperty -Filter "system.webServer/httpProtocol/customHeaders" -Name "." -Value @{name="Strict-Transport-Security";value="max-age=31536000; includeSubDomains; preload"} -PSPath "IIS:\Sites\YourSiteName"
```
## Cloudflare修复方法
如果你使用Cloudflare CDN,可以直接在Cloudflare控制台开启HSTS:
1. 登录Cloudflare控制台
2. 选择你的域名
3. 点击"SSL/TLS" → "边缘证书"
4. 找到"HTTP严格传输安全(HSTS)"
5. 点击"启用HSTS"
6. 勾选"启用includeSubDomains"
7. 设置max-age(建议至少6个月)
8. 如果需要,勾选"启用preload"
**注意**:Cloudflare的HSTS配置会覆盖源站的设置,所以如果你在Cloudflare开启了HSTS,源站就不需要再配置了。
## 如何验证修复是否生效?
修复完成后,一定要验证是否生效。推荐三种验证方法:
### 验证方法1:使用curl
```bash
curl -I https://example.com | grep -i strict
```
应该看到:
```
strict-transport-security: max-age=31536000; includeSubDomains; preload
```
### 验证方法2:使用浏览器开发者工具
1. 打开开发者工具(F12)
2. 访问你的网站
3. 查看Network标签中的第一个请求
4. 在Response Headers中确认`strict-transport-security`的值
### 验证方法3:使用Security Headers在线工具
访问 https://securityheaders.com,输入你的域名,点击"Scan"。
在结果页面中,找到HSTS那一栏:
- 如果显示绿色,且包含`includeSubDomains`,说明配置正确
- 如果显示黄色或者红色,根据提示进行调整
## 常见问题与解决方法
### 问题1:配置了includeSubDomains后,子域名访问不了
**原因**:子域名可能没有配置HTTPS证书,或者证书已过期。
**解决方法**:
1. 为子域名申请SSL证书(可以使用Let's Encrypt免费证书)
2. 确保子域名的HTTPS配置正确
3. 如果子域名暂时无法支持HTTPS,可以分阶段部署:
- 第一阶段:只为子域名配置HTTPS,但不开启HSTS
- 第二阶段:所有子域名都支持HTTPS后,再添加`includeSubDomains`
### 问题2:includeSubDomains导致preload申请被拒
**原因**:HSTS preload列表要求非常严格,必须确保所有子域名都支持HTTPS。
**解决方法**:
1. 访问 https://hstspreload.org
2. 输入你的域名,查看具体的拒绝原因
3. 根据提示修复问题(通常是某个子域名不支持HTTPS)
4. 修复后重新提交申请
### 问题3:Nginx配置后不生效
**原因**:可能是`add_header`指令的继承问题。
**解决方法**:
1. 确保在正确的`server`块中配置
2. 如果有多个`add_header`指令,确保它们在同一层级
3. 使用`nginx -T`命令查看最终生效的配置
4. 确认配置文件中没有重复的HSTS头(可能导致冲突)
## 最佳实践建议
根据我的经验,配置HSTS(包含includeSubDomains)时,建议遵循以下最佳实践:
### 1. 分阶段部署
不要一次性在所有子域名上开启`includeSubDomains`,而是分阶段进行:
**第一阶段**:测试环境验证
- 在测试环境配置HSTS(max-age设为较小值,比如300秒)
- 验证所有功能正常
**第二阶段**:生产环境小范围试点
- 选择一个不太重要的子域名,配置完整的HSTS
- 观察是否有问题
**第三阶段**:全量部署
- 所有子域名都支持HTTPS后,在主域名配置`includeSubDomains`
- 逐步增大max-age的值,最终设置为1年(31536000秒)
### 2. 使用相同的max-age
确保所有子域名的HSTS `max-age`值相同,避免浏览器缓存不一致导致的问题。
### 3. 定期检查
建议每个月使用自动化脚本检查一次所有子域名的安全响应头配置,及时发现问题。
可以用这个curl脚本批量检测:
```bash
#!/bin/bash
domains=("example.com" "www.example.com" "api.example.com" "admin.example.com")
for domain in "${domains[@]}"; do
echo "Checking $domain..."
curl -I -s "https://$domain" | grep -i strict
echo "---"
done
```
### 4. 监控HSTS preload状态
如果你的域名在HSTS preload列表中,建议定期检查一下状态:
```bash
curl -s "https://hstspreload.org/api/v2/status?domain=example.com"
```
## 相关文章推荐
如果你对HSTS和安全响应头感兴趣,可以看看这些文章:
- [Nginx HSTS配置错误排查:常见原因与解决方法](https://www.youres.cn/?id=776) - 深入讲解HSTS配置中的各种坑
- [如何验证HSTS是否生效:4种方法让你的网站安全策略真正落地](https://www.youres.cn/?id=771) - 多种验证方法详解
- [Nginx安全响应头检查工具推荐:5款实用工具助力网站安全](https://www.youres.cn/?id=768) - 选对工具,事半功倍
## 总结
HSTS响应头缺少`includeSubDomains`是一个常见但危险的安全配置疏漏。它会导致子域名不受HSTS保护,给攻击者留下可乘之机。
修复方法并不复杂,只需要在HSTS响应头中加上`includeSubDomains`指令即可。但需要注意的是,开启这个选项前,必须确保所有子域名都支持HTTPS,否则会导致子域名无法访问。
建议按照"测试环境验证 → 小范围试点 → 全量部署"的流程来实施,避免一次性改动导致大面积故障。
最后,安全配置不是一劳永逸的事情,建议定期检查、持续优化,确保你的网站始终处于最佳的安全状态。
---
**本文关键词**:HSTS, includeSubDomains, 安全响应头, Nginx, Apache, IIS, 子域名安全, HTTPS强制跳转, 网站安全配置
**版权声明**:本文为youres原创文章,未经允许不得转载。
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论