Apache中启用HSTS需先启用headers_module,仅在HTTPS虚拟主机中配置Header always set Strict-Transport-Security,推荐值为"max-age=31536000; includeSubDomains; preload",但includeSubDomains和preload须谨慎使用,上线前应先用短max-age测试并确保全站HTTPS稳定。

如何在Apache中启用HSTS头(Strict-Transport-Security)
直接加 Header always set Strict-Transport-Security 是最常见做法,但仅此一行往往无效——Apache默认不加载headers_module,且该指令必须在HTTPS虚拟主机内生效,HTTP站点上设置会被浏览器忽略。
实操步骤:
- 确认模块已启用:
a2enmod headers(Debian/Ubuntu)或检查LoadModule headers_module是否在httpd.conf中取消注释 - 只在启用SSL的
<virtualhost></virtualhost>块中添加配置,不要放在:80里 - 推荐写法:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" -
max-age=31536000对应1年,低于6个月(15768000)的值不会被Chrome/Edge的HSTS预加载列表接受
为什么includeSubDomains和preload不能随便加
includeSubDomains会让所有子域名强制走HTTPS,一旦某个子域名(比如dev.example.com)还没配SSL,访问就会失败;preload更危险——它意味着你申请加入浏览器内置HSTS列表,之后即使删掉响应头,浏览器仍会强制跳转HTTPS长达数月。
安全建议:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 上线前先用
max-age=300(5分钟)测试,确认全站HTTPS无误再逐步拉长 - 确保所有子域名都已部署有效证书,且能稳定响应
443端口请求 - 要进preload列表,必须同时满足:
max-age ≥ 31536000、includeSubDomains、preload,并提交到https://hstspreload.org
常见错误:HSTS头没生效的几个典型原因
浏览器开发者工具的Network标签页里看不到Strict-Transport-Security头?大概率是以下情况之一:
- 配置写在了HTTP(
:80)虚拟主机里——HSTS只对HTTPS响应生效 - Apache配置未重载:
systemctl reload apache2(不是restart)或apachectl graceful - 反向代理(如Nginx、CDN)覆盖了响应头,需在代理层也设置
Strict-Transport-Security - 响应状态码不是2xx(比如重定向链中某步返回了301但没带HSTS头),HSTS只在2xx响应中被接受
PHP或应用层能否替代Apache设置HSTS
可以,但不推荐。例如PHP中用header('Strict-Transport-Security: max-age=31536000'),问题在于:一旦某条PHP路径出错(如未认证跳转、空输出、异常终止),HSTS头就丢失;而Apache的Header always set是响应发出前强制注入,稳定性更高。
例外场景:
- 动态控制
max-age(如灰度期用短时间,全量后切长周期) - 某些PaaS环境无法修改Web服务器配置,只能靠应用层
- 注意:PHP必须在
session_start()之前调用header(),否则报headers already sent
HSTS本身不加密流量,也不防DNS污染,它只是告诉浏览器“以后别再用HTTP连我”。真正容易被忽略的是:一旦开启preload,回退成本极高——没有“关闭开关”,只能等浏览器下次更新内置列表。上线前务必用curl -I https://yoursite.com反复验证头是否稳定出现。
















