我的机器上设置了两个 nginx 代理,一个用于解包 SSL,另一个用于执行特定于应用程序的代理(只有第二个是版本控制的)。当我只有一个代理时,我能够成功建立 Websocket 连接,但在转移到两个代理后,所有 Websocket 升级请求都会响应 502 Bad Gateway 错误。我可以确认正常的 http/https 请求适用于我的双代理设置。这是我当前的配置。
代理1
server {
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
server_name staging.ambitx.io;
location / {
proxy_pass http://127.0.0.1:81;
include proxy_params;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/staging.ambitx.io/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/staging.ambitx.io/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = staging.ambitx.io) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name staging.ambitx.io;
return 404; # managed by Certbot
}
Run Code Online (Sandbox Code Playgroud)
代理参数
proxy_set_header Host $http_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;
Run Code Online (Sandbox Code Playgroud)
代理2
(在docker上运行,主机上的端口81绑定到容器上的端口80)
resolver 127.0.0.11 ipv6=off;
server {
listen 80;
listen [::]:80;
location / {
root /var/www/staticfiles;
index index.html index.htm;
try_files $uri /index.html =404;
}
location /ws {
access_log off;
proxy_pass http://wsserver;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api {
proxy_pass http://apiserver;
}
}
Run Code Online (Sandbox Code Playgroud)
location /ws
我最初在Proxy 2 的配置块中有以下语句...
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Run Code Online (Sandbox Code Playgroud)
但我删除了它们,因为它们会覆盖 Proxy 1 设置的标头。
有任何想法吗?如果您需要更多信息,请告诉我。
当然,您不应该从任何中间代理服务器中删除 WebSocket 代理支持。WebSocket 代理是一项非常特殊的任务,为了允许协议切换并保持 WebSocket 连接的建立和活动,您也应该将其支持返回给您的第一个 nginx 代理:
...
location / {
proxy_pass http://127.0.0.1:81;
include proxy_params;
}
location /ws {
proxy_pass http://127.0.0.1:81;
include proxy_params;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
...
Run Code Online (Sandbox Code Playgroud)
从第二个 nginx 代理中删除所有三个proxy_set_header
指令也是一个坏主意。虽然X-Real-IP
和X-Forwarded-For
标头将完全按照您的第一个代理设置的方式传递到您的 WebSocket 应用程序,但该Host
标头是一个特殊的标头。除非显式设置,否则它将传递等于proxy_pass
指令中使用的上游名称,即Host: wsserver
。正如您可以从proxy_set_header
指令文档中读到的:
默认情况下,仅重新定义两个字段:
Run Code Online (Sandbox Code Playgroud)proxy_set_header Host $proxy_host; proxy_set_header Connection close;
(第二个肯定也会破坏任何建立 WebSocket 连接的尝试)。Host
因此,要保留客户端请求中的原始标头(通常是个好主意,您可以在此处阅读有关此标头的更多信息),请返回
proxy_pass Host $http_host;
Run Code Online (Sandbox Code Playgroud)
到第二个 nginx 代理配置的location / { ... }
和。location /ws { ... }
归档时间: |
|
查看次数: |
6963 次 |
最近记录: |