wss:// 的 nginx 设置不断收到 301 重定向

Mic*_*ann 4 nginx wss websocket

无法让 wss:// (或 ws://) 在我的 Digital Ocean、使用 nginx 的 Ubuntu 服务器上工作,不断收到 301 重定向并且没有连接。

Websocket服务器:node + express + uws在http://localhost:3000/chat上提供服务(我已经通过在ufw中打开3000并直接与ws://连接进行了测试,工作正常。)

操作系统:Ubuntu 16.04.3 x64

这是我的 nginx 配置(我尝试了很多变体和选项,这是最简单的,老实说这似乎并不重要)

server {
    listen 443 ssl; # client_wss_port
    server_name www.example.org;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;


    location /chat/ {
        add_header locationischat 1; # this is a dummy header for debugging
        proxy_pass http://localhost:3000/chat/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的 nginx 版本

nginx -v
nginx version: nginx/1.10.3 (Ubuntu)
Run Code Online (Sandbox Code Playgroud)

这是我的防火墙状态

ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
80                         ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
8888                       DENY        Anywhere                  
3000                       DENY        Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
80 (v6)                    ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)             
8888 (v6)                  DENY        Anywhere (v6)             
3000 (v6)                  DENY        Anywhere (v6) 
Run Code Online (Sandbox Code Playgroud)

这是请求/响应的示例(在 Chrome 上使用智能 Websocket 客户端插件)

Request URL: wss://www.example.org/chat
Request Method: GET
Status Code: 301 Moved Permanently
Connection: keep-alive
Content-Length: 194
Content-Type: text/html
Date: Wed, 23 May 2018 10:42:35 GMT
Location: https://www.example.org/chat/
locationischat: 1
Server: nginx/1.10.3 (Ubuntu)
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: Upgrade
Host: www.example.org
Origin: chrome-extension://omalebghpgejjiaoknljcfmglgbpocdp
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: hFvk0oEAzI5FLVd4W2fgoA==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36
Run Code Online (Sandbox Code Playgroud)

这是上述请求的 nginx access.log

49.195.190.75 - - [23/May/2018:22:39:16 +0000] "GET /chat HTTP/1.1" 301 194 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
Run Code Online (Sandbox Code Playgroud)

Mic*_*ton 7

您的location指令引用了/chat/,但您尝试使用的端点是/chat

因为 alocation存在于相同的路径中,并且/附加了 a,所以 nginx 会生成内部重定向。

如果/chat是 WebSocket 端点,那么您应该使用location /chat.

您可能缺少一些其他必要的标头。这是您应该拥有的东西的一个工作示例:

    location /ws {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_set_header Proxy "";
            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;
            proxy_pass http://localhost:8080;
    }
Run Code Online (Sandbox Code Playgroud)