我有一个使用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)遭受客户端超时(网站旋转了几分钟,然后放弃却没有加载)
我也尝试过:
proxy_socket_keepalive on
proxy_connect_timeout 7d
proxy_send_timeout 7d
proxy_read_timeout 7d
没有骰子。