摘要:按 nginx.org 官方文档,说明一台机器多个 HTTPS 站点怎么用 server 块 + SNI 选证书、HTTP 强制跳转 HTTPS、proxy_pass 反代上游,以及 502 时先查 error.log、上游端口与超时。查询日期 2026-10-15。无联盟链接。

一台云服务器上跑两个以上站点,最常见的做法是:Nginx 对外听 80/443,按域名把请求反代到本机不同端口或容器。证书续期、强制 HTTPS、偶发 502,几乎都会踩到。本文只依据 nginx.org 公开文档说明配置要点与排查顺序;免费证书申请与自动续期见网站 HTTPS 免费证书怎么申请和自动续期,域名解析基础见域名解析入门。

查询日期:2026-10-15(北京时间)。示例域名均为文档占位符;把 example.com 换成你的域名,路径换成你机器上的证书与上游地址。云厂商控制台链接为普通官网入口,本文暂无推广联盟账号。

反代在做什么

ngx_http_proxy_module 的作用是把请求转发到另一台(或本机另一个端口的)服务器。官方示例:

location / {
    proxy_pass       http://localhost:8000;
    proxy_set_header Host      $host;
    proxy_set_header X-Real-IP $remote_addr;
}
Nginx 反向代理多站点:证书、强制 HTTPS 与常见 502 排查(2026)-有序
nginx.org《Module ngx_http_proxy_module》Example Configuration:proxy_pass 到 localhost:8000,并设置 Host / X-Real-IP(box 内 Chrome 截图,2026-10-15)

多站点时,通常是「一个 server { ... } 对应一个域名」,在各自的 location 里 proxy_pass 到不同上游(例如 127.0.0.1:3000、127.0.0.1:8080,或 unix socket)。proxy_pass 的协议可以是 http 或 https,地址可以是域名、IP、端口或 unix: socket(见官方 proxy_pass 说明)。

Nginx 反向代理多站点:证书、强制 HTTPS 与常见 502 排查(2026)-有序
nginx.org proxy_pass 指令:Syntax 为 proxy_pass URL;可指定 http/https 与可选 URI(2026-10-15 截图)

多站点 HTTPS:每个 server 一块证书 + SNI

官方《Configuring HTTPS servers》要求:在 listen 上打开 ssl,并指定证书与私钥:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ...
}
Nginx 反向代理多站点:证书、强制 HTTPS 与常见 502 排查(2026)-有序
nginx.org《Configuring HTTPS servers》开头:listen 443 ssl 与 ssl_certificate / ssl_certificate_key(2026-10-15 截图)

同一 IP 上挂多个 HTTPS 站点时,文档「Name-based HTTPS servers」写得很清楚:若没有正确的名字识别,浏览器可能拿到默认 server 的证书。现代做法是依赖 SNI(Server Name Indication,RFC 6066):握手阶段带上要访问的域名,Nginx 再选对应证书。

Nginx 反向代理多站点:证书、强制 HTTPS 与常见 502 排查(2026)-有序
nginx.org「Name-based HTTPS servers」:同一 IP 上两个 listen 443 ssl 的 server_name 与各自证书(2026-10-15 截图)

用下面命令确认二进制是否启用了 SNI:

nginx -V 2>&1 | tr ' ' '\n' | grep -i sni
# 文档示例输出中会看到:TLS SNI support enabled
Nginx 反向代理多站点:证书、强制 HTTPS 与常见 502 排查(2026)-有序
nginx.org「Server Name Indication」:SNI 让浏览器在握手时传域名;nginx -V 可见 TLS SNI support enabled(2026-10-15 截图)

证书文件本身可用 Certbot、acme.sh 或云厂商免费证书生成;Let's Encrypt 官方入门仍推荐多数用户用 Certbot。装好后记得 nginx -t 再 reload,并把续期后的 reload 写进续期钩子(详见免费证书文)。

Nginx 反向代理多站点:证书、强制 HTTPS 与常见 502 排查(2026)-有序
Certbot 官网 Nginx + Linux (snap) 安装说明页(2026-10-15 截图)

强制 HTTPS:80 跳到 443

常见写法是单独一个只听 80 的 server,把整站重定向到 HTTPS(示例,按需改域名):

server {
    listen 80;
    server_name a.example.com b.example.com;
    return 301 https://$host$request_uri;
}

也可以在同一 server 里同时 listen 80; 与 listen 443 ssl;(官方「A single HTTP/HTTPS server」),再在 location 里按需跳转。注意:跳转死循环往往来自上游或 CDN 已做 HTTPS,回源又被你再次 301——这时要分清「浏览器到边缘」和「边缘到源站」两段。

若前面还有 Cloudflare,加密模式(Flexible / Full / Full strict)要与源站证书匹配,见Cloudflare 免费 CDN 与 SSL 接入。用宝塔图形界面改站点时,同样建议改完后到 SSH 里 nginx -t,见宝塔面板要不要装。

一份「两站点反代」骨架(示意)

把证书路径、上游端口换成你的真实值:

# /etc/nginx/sites-available/multi.conf  (路径因发行版而异)

upstream app_a { server 127.0.0.1:3000; }
upstream app_b { server 127.0.0.1:8080; }

server {
    listen 80;
    server_name a.example.com b.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name a.example.com;
    ssl_certificate     /etc/letsencrypt/live/a.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/a.example.com/privkey.pem;

    location / {
        proxy_pass http://app_a;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 60s;
        proxy_read_timeout 60s;
    }
}

server {
    listen 443 ssl;
    server_name b.example.com;
    ssl_certificate     /etc/letsencrypt/live/b.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/b.example.com/privkey.pem;

    location / {
        proxy_pass http://app_b;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

改完后:

sudo nginx -t && sudo systemctl reload nginx

常见 502:先分清是「代理」还是「上游」

502 Bad Gateway 在 Nginx 作反代时,通常表示:Nginx 没能从上游拿到一份合法响应。官方 proxy_next_upstream 等指令也把连接失败、超时、无效头等视为可切换上游的错误条件。排查建议按这个顺序:

  1. 看 error.log(路径常见 /var/log/nginx/error.log)
    · connect() failed (111: Connection refused) → 上游没在听,或 proxy_pass 端口写错;
    · upstream timed out → 上游太慢或卡住,对照 proxy_read_timeout / proxy_connect_timeout(默认常见 60s);
    · SSL handshake / SSL_do_handshake() failed → 你在用 proxy_pass https://... 回源时,证书或 SNI 不匹配,可查 proxy_ssl_server_name、proxy_ssl_verify 等指令。
  1. 绕过 Nginx 直连上游

``bashcurl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/ss -lntp | grep -E '3000|8080'``本机 curl 都失败,先修应用进程,而不是改证书。

  1. 核对 proxy_pass 是否带 URI

官方说明:proxy_pass 带 URI 时会替换 location 匹配段;不带 URI 时更接近把客户端 URI 原样传递。正则 location、rewrite + break、变量拼接时规则更绕——改完用 curl -I https://你的域名/某路径 看是否落到预期上游路径。

  1. 头信息

缺 Host / X-Forwarded-Proto 时,有的应用会重定向错误或生成错误链接,表现为「偶发 502」或跳转环,而不一定是进程挂了。

  1. 证书过期或链不完整

浏览器报证书错误时,访客侧是警告页;若是回源 HTTPS 握手失败,则更容易在代理层变成 502。用 openssl s_client -connect 127.0.0.1:443 -servername a.example.com 看链是否完整(官方 HTTPS 文也演示了如何读 Certificate chain)。

安全与运维提醒

  • 私钥文件权限应限制为 Nginx master 可读;不要把私钥提交进 Git。
  • nginx -t 失败时不要 reload,否则可能仍跑旧配置或直接起不来。
  • 国内服务器对公众提供网站内容,还需遵守 ICP 备案等要求,见ICP 备案全流程。
  • 面板(宝塔等)与手改 conf 混用时,先搞清「哪份文件才是真正被 include 的」。

风险提示

  • 错误的反代配置可能导致源站端口对外暴露、证书错配或整站不可用;生产变更前先在测试域名验证。
  • 本文不提供入侵、绕过 WAF 或未授权访问任何系统的方法。
  • 云厂商计费、流量与安全组以各官网当前说明为准;本文无联盟推广链接(affiliate_later)。

来源(查询日期 2026-10-15): Module ngx_http_proxy_module、Configuring HTTPS servers、Certbot Instructions。

相关阅读