Nginx配置HTTP Strict
HSTS(HTTP Strict Transport Security)是一种Web安全策略,它告诉浏览器在指定时间内只能通过HTTPS访问你的网站,从而防止SSL剥离攻击和HTTP劫持。
如果你已经为Nginx配好了SSL证书,但还没启用HSTS,那么本文会带你从零开始完成配置,并验证效果。
动手前先确认这些条件
配置HSTS前,你的网站必须已经能通过HTTPS正常访问,且拥有有效的SSL证书。
如果HTTPS本身还有证书错误或混合内容问题,先解决这些,否则启用HSTS后浏览器会直接拦截访问,用户连“继续访问”的选项都没有。
检查HTTPS是否正常:
curl -I https://你的域名
返回状态码应为200或301,且没有证书报错。
另外,建议先备份Nginx配置文件:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
如果你使用的是宝塔面板,可以在网站 -> 设置 -> 配置文件中直接编辑,但同样建议先复制一份原内容保存。
在Nginx中启用HSTS响应头
HSTS的核心是让服务器在HTTPS响应中返回Strict-Transport-Security头。
配置位置通常在server块中,监听443端口的那个server里。
打开你的Nginx站点配置文件,例如/etc/nginx/conf.d/your-site.conf,找到类似下面的HTTPS server块:
server {
listen 443 ssl;
server_name example.com;
...
}
在server块内添加一行:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
参数解释:
max-age=31536000:单位是秒,表示浏览器在一年内强制使用HTTPS。测试阶段可以先设短一点,比如max-age=300,确认无误后再改大。includeSubDomains:所有子域名也强制HTTPS。如果子域名还没上HTTPS,先不要加这个参数。always:确保所有响应(包括错误页)都带上这个头。
保存后,检查Nginx配置语法:
nginx -t
如果显示syntax is ok和test is successful,就可以重载:
nginx -s reload
宝塔面板用户点击重载配置即可。
把HTTP请求永久跳转到HTTPS
HSTS只在浏览器已经通过HTTPS访问过一次后才生效,所以你需要确保HTTP的80端口请求被重定向到HTTPS。
在Nginx中通常用另一个server块处理:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
这段配置会把所有HTTP请求用301永久重定向到对应的HTTPS地址。
注意$host会自动替换为请求的域名,$request_uri保留原始路径和参数。
配置完成后同样执行nginx -t和nginx -s reload。
容易踩坑的几个地方
HSTS头重复添加:如果你在http块或上层server块已经加过一次,子server块又加一次,浏览器可能收到多个头导致行为异常。
用curl -I检查响应头,确保只有一个Strict-Transport-Security。
子域名未启用HTTPS就加includeSubDomains:这会导致所有子域名无法访问。
建议先不加该参数,等子域名证书都配好后再补上。
max-age设置过长:一旦浏览器缓存了HSTS策略,在过期前无法通过服务器端取消。
测试时用300秒,稳定后再改为一年。
忽略always参数:不加always时,Nginx只对成功响应(2xx、3xx)添加头,错误页面可能缺失,影响安全性。
证书链不完整:HSTS生效后浏览器对证书要求更严格,如果中间证书缺失,用户会直接看到拦截页面。
用openssl s_client -connect 你的域名:443 -showcerts检查证书链。
验证HSTS是否生效
重载Nginx后,用curl查看响应头:
curl -I https://你的域名
在输出中应该能看到:
Strict-Transport-Security: max-age=31536000; includeSubDomains
如果没看到,检查是否在正确的server块中添加,以及是否执行了重载。
浏览器验证:
用Chrome访问chrome:,
//net-internals/#hsts
在Query HSTS/PKP domain中输入你的域名,
点击查询,
如果显示Found并列出max-age,
说明浏览器已记录。
另外,可以访问https://你的域名,然后手动把地址改成http://你的域名,正常情况应该自动跳转到HTTPS。
常见疑问
HSTS和301跳转有什么区别?
301跳转是服务器告诉浏览器“这个地址永久变了”,但浏览器仍然可以主动发起HTTP请求。HSTS是浏览器内部记住“这个域名只能用HTTPS”,在发出请求前就把HTTP替换成HTTPS,安全性更高。两者通常配合使用。
启用HSTS后还能回退吗?
在max-age过期之前,无法通过服务器端取消。如果必须回退,只能等浏览器缓存过期,或者引导用户手动清除HSTS记录(普通用户很难操作)。所以测试阶段务必用短max-age。
多个域名共用同一台Nginx,HSTS会影响其他站点吗?
不会。HSTS是按域名生效的,你只在某个server块中添加,就只对该server_name对应的域名生效。
宝塔面板有快捷开关吗?
宝塔面板的网站设置中通常没有直接叫“HSTS”的开关,需要手动编辑配置文件。路径是:网站 -> 设置 -> 配置文件,在server块内添加add_header行即可。
配置完成后,建议用不同浏览器和无痕模式各访问一次,确认跳转和证书都正常。
如果后续要调整max-age,记得先改小再改大,避免把自己锁在外面。