ssl - Nginx 没有正确转发我的 SSL WebSockets 连接?
问题描述
我正在尝试将 Django 应用程序与基于 flask+gevent 的 websocket 后端(不讲 SSL)放在同一个域上。我发现虽然直接连接到 websocket 后端是可行的,但尝试通过 nginx 访问它却失败了。这是 nginx 和 websockets 服务器之间通信的 hexdump,包括我用来捕获它的命令:
# ncat -x /dev/stdout -k -vv -l 13006 --sh-exec "ncat localhost 13005"
Ncat: Version 7.60 ( https://nmap.org/ncat )
Ncat: Generating a temporary 1024-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.
Ncat: SHA-1 fingerprint: 6E88 CB89 DEA4 09E4 0863 CD09 90D8 BDFE 3030 A87A
Ncat: Listening on :::13006
Ncat: Listening on 0.0.0.0:13006
Ncat: Connection from 127.0.0.1.
Ncat: Connection from 127.0.0.1:49634.
NCAT DEBUG: Executing with shell: ncat localhost 13005
[0000] 47 45 54 20 2F 73 69 6E 67 6C 65 2F 3F 72 65 67 GET /sin gle/?reg
[0010] 65 78 3D 6F 66 6F 20 48 54 54 50 2F 31 2E 31 0D ex=ofo H TTP/1.1.
[0020] 0A 55 70 67 72 61 64 65 3A 20 77 65 62 73 6F 63 .Upgrade : websoc
[0030] 6B 65 74 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E 3A ket..Con nection:
[0040] 20 55 70 67 72 61 64 65 0D 0A 53 65 63 2D 57 65 Upgrade ..Sec-We
[0050] 62 53 6F 63 6B 65 74 2D 56 65 72 73 69 6F 6E 3A bSocket- Version:
[0060] 20 31 33 0D 0A 53 65 63 2D 57 65 62 53 6F 63 6B 13..Sec -WebSock
[0070] 65 74 2D 4B 65 79 3A 20 61 45 41 6D 30 65 50 4B et-Key: aEAm0ePK
[0080] 5A 75 65 77 61 37 48 42 73 32 32 32 76 41 3D 3D Zuewa7HB s222vA==
[0090] 0D 0A 53 65 63 2D 57 65 62 53 6F 63 6B 65 74 2D ..Sec-We bSocket-
[00a0] 45 78 74 65 6E 73 69 6F 6E 73 3A 20 70 65 72 6D Extensio ns: perm
[00b0] 65 73 73 61 67 65 2D 64 65 66 6C 61 74 65 3B 20 essage-d eflate;
[00c0] 63 6C 69 65 6E 74 5F 6D 61 78 5F 77 69 6E 64 6F client_m ax_windo
[00d0] 77 5F 62 69 74 73 0D 0A 48 6F 73 74 3A 20 6C 6F w_bits.. Host: lo
[00e0] 63 61 6C 68 6F 73 74 3A 31 33 30 30 36 0D 0A 0D calhost: 13006...
[00f0] 0A .
[0000] 48 54 54 50 2F 31 2E 31 20 31 30 31 20 53 77 69 HTTP/1.1 101 Swi
[0010] 74 63 68 69 6E 67 20 50 72 6F 74 6F 63 6F 6C 73 tching P rotocols
[0020] 0D 0A 55 70 67 72 61 64 65 3A 20 77 65 62 73 6F ..Upgrad e: webso
[0030] 63 6B 65 74 0D 0A 43 6F 6E 6E 65 63 74 69 6F 6E cket..Co nnection
[0040] 3A 20 55 70 67 72 61 64 65 0D 0A 53 65 63 2D 57 : Upgrad e..Sec-W
[0050] 65 62 53 6F 63 6B 65 74 2D 41 63 63 65 70 74 3A ebSocket -Accept:
[0060] 20 68 74 4F 6D 31 78 78 78 64 35 6C 30 48 6A 66 htOm1xx xd5l0Hjf
[0070] 4D 43 6C 72 34 54 72 35 4A 51 4D 45 3D 0D 0A 0D MClr4Tr5 JQME=...
[0080] 0A 88 00 ...
[0000] 88 80 C5 99 4F E0 ....O.
这是我正在使用的配置:
/etc/nginx/sites-enabled/default
server {
listen 80;
listen [::]:80;
server_name _;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/profound-ssl.conf;
server_name _;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_redirect off;
proxy_pass http://localhost:8000/;
}
location ^~ /ws/ {
proxy_pass http://localhost:13006/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_redirect off;
proxy_set_header Sec-WebSocket-Version $http_sec_websocket_version;
proxy_set_header Sec-WebSocket-Protocol $http_sec_websocket_protocol;
proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
proxy_set_header Sec-WebSocket-Extensions $http_sec_websocket_extensions;
proxy_set_header Sec-WebSocket-Accept $http_sec_websocket_accept;
}
}
/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
除了后端的错误之外,不会记录任何错误:
2018-11-15T13:53:17.569402589Z DEBUG:geventwebsocket.handler:Initializing WebSocket
2018-11-15T13:53:17.570682796Z DEBUG:geventwebsocket.handler:Validating WebSocket request
2018-11-15T13:53:17.570698284Z DEBUG:geventwebsocket.handler:Attempting to upgrade connection
2018-11-15T13:53:17.570701438Z DEBUG:geventwebsocket.handler:WebSocket request accepted, switching protocols
2018-11-15T13:53:17.570704839Z DEBUG:geventwebsocket.handler:Closed WebSocket
2018-11-15T13:53:17.570708858Z DEBUG:geventwebsocket.handler:Failed to write closing frame -> closing socket
2018-11-15T13:53:17.570713594Z DEBUG:geventwebsocket.handler:Closed WebSocket
我该如何调试呢?我还应该检查什么?
解决方案
史上最诡异的错误!看来我需要更改:
proxy_pass http://localhost:13006/
至:
proxy_pass http://localhost:13006/ws
推荐阅读
- arrays - 如何在 Matlab 中创建此代码的矢量化版本
- android - Android WebView 使用自定义 url 和 cookie 加载图像标签
- xml - 在 Scala 中读取带有属性名称的 XML
- java - 如何在 Apache Tomact 下接收专有协议?
- javascript - 如何在 RxDB 中的 pouchdb 实例上调用 bulkDocs 时同步修订
- mysql - 如何使用生成状态板的程序运行脚本?以及如何查阅为克雷塔罗州创建的印版?
- c# - 从 webview 中检索 JSessionId - Windows 窗体 C#
- r - readr::read_csv 使用 cols_only 和拼接列表
- javascript - 如何在 React Native 应用程序中使用 Python 实用程序,例如 (PyGaze)?
- json - JSON.Net 从 2 种 json 格式反序列化