nginx https重定向需防范host头劫持:严格校验host,用map白名单匹配可信域名并返回444或400;重定向使用硬编码域名或map输出的$valid_host;启用hsts并关闭非必要http端口。

在 Nginx 中配置 HTTPS 重定向时,若仅使用简单的 return 301 https://$host$request_uri;,可能引入重定向劫持风险——攻击者可通过构造恶意 Host 头,将用户重定向到任意域名(如 https://evil.com/...),尤其在多租户、共享 IP 或未严格校验 Host 的场景下危害显著。
严格校验 Host 头,拒绝非法域名
避免直接信任客户端传入的 $host 或 $http_host。应只允许已知可信域名参与重定向:
- 用
map指令预定义合法域名列表,匹配失败时返回 444(关闭连接)或 400 - 重定向时使用白名单中的变量(如
$valid_host),而非原始$host - 示例配置中,
map可设为: map $http_host $valid_host {
default ""; # 默认为空,后续判断
example.com "example.com";
www.example.com "example.com";
}
优先使用绝对 URI 重定向,禁用协议拼接
避免拼接 https://$host... 这类易受污染的字符串。推荐用 return 301 https://example.com$request_uri;(硬编码主域名),或配合 map 输出确定值:
- 若支持多个主域名(如 www 和裸域),应在
map中统一映射到标准域名 - 不依赖
$scheme或$request_uri构造跳转目标,它们本身安全,但必须与可信 Host 绑定使用 - 禁用
proxy_set_header Host $host在重定向上下文中传递不可信 Host
启用 HSTS 并设置合理策略
HSTS 虽不直接防止首次劫持,但能大幅降低后续中间人或降级攻击风险,间接强化 HTTPS 重定向可信度:
- 在 HTTPS server 块中添加:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - 确保该头仅通过 HTTPS 发送(HTTP 块中不要设置),且
always参数保证重定向响应也携带 - 提交域名至 HSTS Preload List 可获得浏览器内置强制 HTTPS
关闭非预期端口的 HTTP 服务或做最小化响应
若业务无需 HTTP 访问,可直接关闭 80 端口监听;若需保留用于重定向,务必限制其行为边界:
- HTTP server 块中禁止任何 proxy_pass、rewrite 或动态内容处理,只做单一 301 跳转
- 对非白名单 Host 请求,返回 444(Nginx 特有,直接断连)比 301 更安全,避免被滥用为跳板
- 不记录非法 Host 请求的访问日志,减少日志污染和潜在信息泄露











