为什么Nginx反向WebSocket代理会立即关闭?

时间:2019-12-04 02:46:51

标签: nginx websocket proxy reverse-proxy

我有一个使用Hypnotoad作为Web服务器的Mojolicious应用程序(不是我创建的,我只需要管理服务器,而其他人则可以保持软件运行)。该Web应用程序同时提供标准的HTTP流量(网站)和WebSocket。

此服务器的SSL证书无效,并引起了问题,因此我决定将其放在具有有效SSL证书的nginx代理后面,以解决问题,而无需学习Mojolicious或Hypnotoad。我的nginx配置看起来像这样:

server {

        server_name example.com;

        location / {
                proxy_set_header Host $host;
                proxy_pass https://oldserver.com;
                proxy_set_header Connection "Upgrade";
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
        }


    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/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 = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80 ;
        listen [::]:80 ;
    server_name example.com;
    return 404; # managed by Certbot


}

对于标准HTTP流量,此方法工作正常。我可以打开浏览器,然后转到https://example.com并查看该应用程序。但是,websockets无法正常工作。当我使用https://www.websocket.org/echo.html之类的工具时,它表明已建立连接并 立即 关闭。没有错误,连接只是... 结束

使用cURL(对于Windows)尝试诊断该问题,我看到以下内容:

C:\Users\Stevendesu\Downloads\curl\bin>curl.exe -k -i -N -H "Host: example.com" -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: BOGUS+KEY+HERE==" https://example.com/websocket
HTTP/1.1 101 Switching Protocols
Server: nginx/1.16.1
Date: Wed, 04 Dec 2019 02:41:17 GMT
Connection: upgrade
Sec-WebSocket-Accept: 637tWmextWqH26Xu/HgQ0KokqMQ=
Upgrade: websocket

curl: (52) Empty reply from server

此后,cURL终止。

但是,如果我绕过代理服务器并直接转到旧服务器,则cURL会永远挂起,而不会显示任何消息(大概是因为WebSocket已打开)

C:\Users\Stevendesu\Downloads\curl\bin>curl.exe -k -i -N -H "Host: example.com" -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: BOGUS+KEY+HERE==" https://oldserver.com/messages
HTTP/1.1 101 Switching Protocols
Sec-WebSocket-Accept: 637tWmextWqH26Xu/HgQ0KokqMQ=
Connection: Upgrade
Upgrade: websocket
Server: Mojolicious (Perl)
Date: Wed, 04 Dec 2019 02:43:26 GMT


为什么代理会终止连接?

更新

我试图像这样修改我的nginx配置:

upstream oldserver {
    keepalive 100;
    server oldserver.com;
}

server {

        server_name example.com;

        location / {
                proxy_set_header Host $host;
                proxy_pass https://oldserver;
                proxy_set_header Connection "Upgrade";
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
        }


    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/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 = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80 ;
        listen [::]:80 ;
    server_name example.com;
    return 404; # managed by Certbot


}

我希望keepalive行能解决问题。没有。这导致 所有 连接(甚至是HTTP)遭受客户端超时(网站旋转了几分钟,然后放弃却没有加载)

更新2

我也尝试过:

  • proxy_socket_keepalive on
  • proxy_connect_timeout 7d
  • proxy_send_timeout 7d
  • proxy_read_timeout 7d

没有骰子。

0 个答案:

没有答案