核心是物理隔离+逻辑独立:各环境用独立server块、专属证书路径及域名/端口标识;证书按环境分目录存放并设600权限;禁用泛域名混用;通过x-env头透传可信环境标识给后端。

核心是物理隔离 + 逻辑独立:每个环境用单独的 server 块、专属证书路径、明确的域名或端口标识,不混用、不复用、不共享。
按环境分目录存放证书
避免把所有证书堆在同一个 ssl/ 目录下。推荐结构如下:
- /etc/nginx/ssl/dev/ → dev.crt + dev.key(自签名,用于 local.api 或 dev.example.com)
- /etc/nginx/ssl/staging/ → staging.pem + staging.key(Let’s Encrypt staging 环境申请)
- /etc/nginx/ssl/prod/ → fullchain.pem + privkey.pem + dhparam.pem(正式证书,含完整链)
每个证书文件权限设为 600,所属用户为 nginx 运行用户(如 www-data),防止越权读取。
每个环境配独立 server 块
不把 dev/test/prod 塞进同一个 listen 443 ssl 块里。正确做法:
- 开发环境用 dev.example.com 或本地域名(如 local.api),配合 hosts 文件,监听 443,引用 /etc/nginx/ssl/dev/ 下证书
- 预发环境用 staging.example.com,同样独立 server 块,引用 staging 证书路径
- 生产环境用 example.com 或泛域名,必须用正式证书,启用 OCSP Stapling 和 HSTS
禁用泛域名证书在非生产环境混用——哪怕证书支持多个域名,也要为每个环境显式绑定对应 server_name 和证书路径。
用端口或兜底块避免冲突
当多个环境共用一台 Nginx 实例时,容易因 SNI 匹配失败导致证书错配:
- 临时调试可用非标 HTTPS 端口(如 8443、8444),避免与生产 443 冲突
- 必须设一个 default_server 兜底块,监听 443 ssl default_server,使用仅含 IP 的自签名证书,返回 444(静默关闭连接)
- 兜底证书的 CN 和 SAN 只能填服务器 IP,不能包含任何租户或业务域名,防止信息泄露
透传可信环境标识给后端
HTTPS 终止后,后端服务需要可靠知道当前请求属于哪个环境:
- 在每个 server 块中统一注入 proxy_set_header X-Env "dev";、X-Env "staging" 等
- 禁止从 Host 头、URL 参数或 Cookie 提取环境信息——这些都可被伪造
- 后端只信任 X-Env 头,并校验其值是否在预设白名单内(如 ["dev", "staging", "prod"]),否则拒绝响应











