HTTPS全站跳转实战:Nginx强制加密与HSTS防降级配置


一、HTTPS 跳转:全站安全的第一步

拿到 SSL 证书后,如果用户仍能用 http:// 直接访问,会绕过加密、也有被降级攻击的风险。正确做法是把所有 HTTP 请求统一 301/302 重定向到 HTTPS。Node 层最常用、性能最好的方案是用 Nginx 单独开一个 80 端口 server 块,把所有请求转发到 https。结合之前 SSL 配置文章,这里给出完整可靠的跳转配置。

二、Nginx 强制跳转配置

在 Nginx 里,http→https 跳转的一般写法:

# 强制全局跳转:所有 80 端口请求转到对应 https
server {
    listen 80;
    server_name www.example.com example.com;
    # 保留端口号(若非 443 部署)
    return 301 https://$host$request_uri;
    # 若 https 端口不是 443,可写 return 301 https://$host:8443$request_uri;
}

# https 主站(原 443 配置保持不动)
server {
    listen 443 ssl;
    server_name www.example.com;
    # ...ssl_certificate、location 等原有配置...
}
sudo nginx -t && sudo systemctl reload nginx

用 $host$request_uri 而不是写死路径,能保留用户访问的子路径与查询参数,避免跳转后丢失 URL。这是 301 永久跳转,浏览器和爬虫会记住,利于 SEO 权重集中,适合确定长期用 HTTPS 的站点。

三、精确控制:按路径/按场景跳转

并非所有请求都要整站跳转——比如 Let's Encrypt 的 ACME 验证路径 /.well-known/acme-challenge/ 常需要在 http 上直接响应。用 if 或 location 精确放行:

server {
    listen 80;
    server_name www.example.com;

    # ACME 证书验证路径放行,不跳转(供 certbot 在 http 上完成验证)
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
    }

    # 其余全部跳转 https
    location / {
        return 301 https://$host$request_uri;
    }
}

用 location 比在整块上用 if 更清晰:验证路径单独处理,其余统一 301。这样就算强制 HSTS,也能先完成 ACME 验证续期证书。

四、HSTS:让浏览器"只认 HTTPS"

301 跳转仍存在"首次访问走一次 http"的窗口。开启 HSTS(HTTP Strict Transport Security)后,浏览器在约定期限内强制用 https 访问你的域名,彻底防降级:

server {
    listen 443 ssl;
    # 开启 HSTS:max-age 单位秒,includeSubDomains 覆盖子域,preload 申请预加载列表
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}

谨慎点击 preload:一旦加入 HSTS preload 列表,想撤销过程复杂。同时应保证你所有子域名都支持 https,否则 includeSubDomains 会让不支持 https 的子域无法访问。建议先在 max-age 较小闭环测试,稳定后再加长。

五、其他跳转场景与避坑

# 裸域→www 或 www→裸域的规范化跳转
server { listen 443 ssl; server_name example.com;
         return 301 https://www.example.com$request_uri; }

# 旧路径→新路径(改版迁移)
location /old/ { return 301 https://www.example.com/new/$request_uri; }

几个高频坑与对策:

  • 跳转死循环:确认 https server 块没再往 http 跳,且 80 块 `return 301` 别指向自身 http。
  • 证书未覆盖裸域:www 与裸域都要在证书里,否则跳转后证书告警。
  • 代理链路:若前面还有 CDN/负载均衡,需把跳转放 CDN 层或正确透传 `X-Forwarded-Proto`,否则会循环跳转。
  • 回源 http 内网:Nginx 对外 https、回源后端 http 时,跳转只作用于对外入口,别误改上游。

六、验证跳转与 HSTS 是否生效

# 看 80 端口是否 301 到 https
curl -I http://www.example.com/ | grep -i HTTP
curl -I http://www.example.com/ | grep -i location

# 看 https 是否返回 HSTS 头
curl -sI https://www.example.com/ | grep -i strict-transport

# 全链路跳转测试
curl -sL -o /dev/null -w "%{url_effective}\n%{http_code}\n" http://example.com/

浏览器端可在开发者工具 Network/头部里确认 301 与实际 final url。用 curl -L 跟随重定向,能一次看清最终落到 https 的完整链路。

写在最后

全站 HTTPS 跳转是加密落地的重要一环,核心记得四步:80 端口 server 统一 `return 301 https://$host$request_uri`;ACME 验证路径用 location 放行;稳定后加 HSTS 头防降级;用 curl 验证 301 与 HSTS 头。配合证书自动续期,你的站点就能做到"从此刻起只走加密连接"。跳转配置很简单,但对"登录态会不会被劫持"这类安全体验的保障却很关键,值得认真配好。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Redis缓存实战:安装配置、PHP接入与持久化调优

uptime-kuma自建监控实战:Docker部署与HTTP告警通知指南

评 论
更换验证码