fix(server): 8081 也加 TLS —— HSTS 会把域名的 http 访问强制升级,仅明文监听会打不开

现象:访问过 https://www.dqrcfwpt.com 之后(该响应带 Strict-Transport-Security: max-age=86400),浏览器访问 http://www.dqrcfwpt.com:8081 会失败。原因有两层:① RFC 6797 明确规定 HSTS 策略按主机生效、覆盖该主机的**所有端口**;② 升级时**显式端口会被保留**,于是 http://host:8081 变成 https://host:8081,而 8081 原来只说纯 HTTP。实测 https://www.dqrcfwpt.com:8081 握手失败可复现。

修法:同一个 8081 端口上同时开明文块(server_name _,给 IP 与无 HSTS 记录的客户端)与 ssl 块(server_name 域名,给浏览器)。IP 入口不受 HSTS 影响,因此永远可用。
1个文件已修改
38 ■■■■■ 已修改文件
.scratch/server-testenv/nginx-talent-card.conf 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.scratch/server-testenv/nginx-talent-card.conf
@@ -4,21 +4,52 @@
#
# 端口分工:
#   8081 → **测试环境**(完整功能,用 snippets/talent-card-locations.conf)
#         同一个端口同时接受明文与 TLS:
#           http://117.172.73.106:8081/            ← IP 访问(明文;HSTS 管不到 IP,所以它永远可用)
#           https://www.dqrcfwpt.com:8081/          ← 域名访问(必须走 TLS,见下)
#   80   → 只做 301 跳到 https
#   443  → 这个域名留给**生产环境**,目前**尚未部署**,所以只显示占位页
#
# 生产上线时怎么切:把下面 443 那个 server 块里的 `root` 与两个 location 换成
# `root <生产的 dist 目录>;` + `include snippets/talent-card-locations.conf;`,
# 80 的 301 不用动。占位页在 /data/talent-card/placeholder/index.html。
# ⚠️ 为什么 8081 必须有 TLS:443 上发了 HSTS(max-age=86400),而 **HSTS 是按“主机”生效的、
#    覆盖该主机的所有端口**(RFC 6797 §8.3:「the HSTS Policy applies to HTTP over any TCP port
#    of an HSTS Host」),且升级时**显式端口会被保留**(`http://host:8081` → `https://host:8081`)。
#    所以只要浏览器收过一次 HSTS,`http://www.dqrcfwpt.com:8081` 就会被强制升级成 https;
#    8081 上没有 TLS 监听时,用户看到的就是“打不开”。加上这个 ssl 块之后才正常。
#
# 生产上线时怎么切:把 443 那个 server 块里的 `root` 与两个 location 换成
# `root <生产的 dist 目录>;` + `include snippets/talent-card-locations.conf;`,80 的 301 不用动。
#
# 证书:华为云 DV(TrustAsia 签发),SAN 覆盖 `dqrcfwpt.com` 与 `www.dqrcfwpt.com`。
#       `/etc/nginx/ssl/talent-card/server.crt` **必须含中间链**(bundle,4451 字节)。
#       **2027-02-11 到期,且不会自动续到本机** —— 到期前重新下载再传一次。
# HSTS 仍是第一步:max-age=86400,无 includeSubDomains / preload。
# 明文入口:给 IP 访问用,也给任何还没有 HSTS 记录的客户端用
server {
    listen 8081;
    server_name _;
    include snippets/talent-card-locations.conf;
}
# TLS 入口:域名 + 8081。浏览器一旦有了 HSTS 就会走这里
server {
    listen 8081 ssl;
    http2 on;
    server_name www.dqrcfwpt.com dqrcfwpt.com;
    ssl_certificate         /etc/nginx/ssl/talent-card/server.crt;
    ssl_certificate_key     /etc/nginx/ssl/talent-card/server.key;
    ssl_trusted_certificate /etc/nginx/ssl/talent-card/server.crt;
    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       1d;
    resolver 223.5.5.5 119.29.29.29 valid=300s;
    ssl_stapling on;
    ssl_stapling_verify on;
    include snippets/talent-card-locations.conf;
}
@@ -42,7 +73,6 @@
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       1d;
    # stapling 需要能解析 OCSP 响应者的域名,没有 resolver 时它会静默不生效
    resolver 223.5.5.5 119.29.29.29 valid=300s;
    ssl_stapling on;
    ssl_stapling_verify on;