需为不同业务域名配置独立的HTTP/HTTPS server块以实现分级HTTPS跳转:主站强制301跳转+完整HSTS;后台允许302跳转+短时HSTS;API域直接444中断+严格HSTS;所有配置须显式声明server_name、禁用rewrite、校验Host头并验证证书覆盖。

要实现针对不同业务域名的分级 HTTPS 强制跳转策略,核心是**按域名区分处理逻辑,而非全局统一跳转**。比如:主站(example.com)要求严格 HSTS + 全量跳转;后台管理域(admin.example.com)允许短期过渡期 HTTP 访问;API 域(api.example.com)则必须拒绝 HTTP、直接 444 中断。这种差异化控制需通过独立 server 块 + 精确匹配 + 分级响应头组合实现。
为每个业务域名配置独立的 80 端口 server 块
不能共用一个 listen 80 块做泛跳转,否则无法分级。每个域名必须有专属 server 块,显式声明 server_name:
-
example.com和www.example.com→ 使用return 301 https://$host$request_uri; -
admin.example.com→ 可设为临时跳转,如return 302 https://$host$request_uri;,便于灰度验证 -
api.example.com→ 直接拒绝 HTTP,返回return 444;(Nginx 特有关闭连接状态码),避免暴露任何响应 - 所有块均禁用
rewrite,统一用return,性能更稳、语义更清晰
443 端口按域名启用差异化的 HSTS 策略
HSTS 不是“开或关”的开关,而是可分级部署的安全承诺。必须在对应域名的 HTTPS server 块中单独配置 add_header:
-
example.com的 443 块:加完整策略add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; -
admin.example.com的 443 块:暂不加preload,仅用"max-age=300; includeSubDomains"测试 5 分钟级缓存 -
api.example.com的 443 块:强制启用includeSubDomains且max-age设为 31536000,因 API 域通常无子域但对安全性要求最高 - 务必带
always参数,确保 404/500 等非 200 响应也携带 HSTS 头
规避跨域名污染与 Host 头注入风险
多个域名共存时,$host 或 $http_host 若未校验,可能被恶意请求篡改,导致跳转到钓鱼地址:
- 每个
server块都明确写死server_name,例如server_name example.com www.example.com;,不依赖通配符 - 在
http块顶层添加underscores_in_headers off;,防止非法 header 注入 - 禁止在跳转中拼接
$http_host,全部使用$host(由 Nginx 根据server_name匹配生成,可信) - 若使用 CDN,确认其未覆盖或剥离 HSTS 头;Cloudflare 用户需在 SSL/TLS → Edge Certificates 中开启“Always Use HTTPS”并手动启用 HSTS
上线前必须做的分级验证动作
分级策略一旦生效,尤其是带 preload 的域名,回退成本极高:
- 用
curl -I http://example.com验证是否返回 301 且Location值正确;再用curl -I https://example.com检查 HSTS 头是否存在、max-age是否符合预期 - 对
admin.example.com,用隐身窗口访问 HTTP 地址,确认跳转发生但无浏览器 HSTS 缓存拦截(因 max-age 小) - 对
api.example.com,执行curl -v http://api.example.com,确认连接被重置(无响应体,HTTP 状态不可见),而非返回 301 或 404 - 所有域名的证书必须覆盖其
server_name列表,否则启用 HSTS 后用户将遭遇浏览器硬拦截(ERR_SSL_PROTOCOL_ERROR)


















