Skip to content

反向代理基础

最小配置

nginx
server {
    listen 443 ssl;
    server_name app.example.com;
    http2 on;

    ssl_certificate     /path/fullchain.pem;
    ssl_certificate_key /path/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

四个 header 基本是标配。少了 X-Forwarded-Proto,后端会以为自己是 http,生成的跳转链接会丢 https。

WebSocket

需要额外两行,否则连接会被降级成普通 HTTP:

nginx
location /ws/ {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade    $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
}

有些应用的 WebSocket 在特定路径下(比如 Vaultwarden 的 /notifications/hub),只给那个 location 加就行。

后端是 HTTPS

nginx
proxy_pass https://127.0.0.1:8443;
proxy_ssl_server_name on;
proxy_ssl_name $host;

自签证书要加 proxy_ssl_verify off

压缩

有些应用(尤其新版本)不再自己压缩响应,全靠反代层:

nginx
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
gzip_min_length 1024;

验证:

bash
curl -sv -H "Accept-Encoding: gzip, br" https://app.example.com/ -o /dev/null 2>&1 | grep -i content-encoding

常见报错

  • 502 Bad Gateway:后端没起来,或者 proxy_pass 地址错了。先 curl 一下后端地址
  • 504:后端太慢,调 proxy_read_timeout
  • 页面能开但静态资源 404:应用有 base path 配置,和反代路径对不上
  • 后端拿到的客户端 IP 全是 127.0.0.1:漏了 X-Real-IP / X-Forwarded-For,或者后端没配信任代理

个人笔记,写给未来忘事的自己。