代码之家  ›  专栏  ›  技术社区  ›  d33tah

nginx没有正确转发我的ssl websockets连接?

  •  0
  • d33tah  · 技术社区  · 6 年前

    我正在尝试将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启用/默认

    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
    

    如何调试?我还需要检查什么?

    1 回复  |  直到 6 年前
        1
  •  0
  •   d33tah    6 年前

    有史以来最奇怪的错误!看来我需要改变一下:

    proxy_pass http://localhost:13006/

    到:

    proxy_pass http://localhost:13006/ws