4. nginx websocket

最後更新: 2019-04-17

 

介紹

 

Since version 1.3.13, nginx implements special mode of operation that allows setting up a tunnel between a client and proxied server

if the proxied server returned a response with the code 101 (Switching Protocols),

and the client asked for a protocol switch via the “Upgrade” header in a request.

The "Upgrade" is a hop-by-hop header

 => it is not passed from a client to proxied server

 => "proxy_set_header   Upgrade $http_upgrade;"


Using NGINX as a WebSocket Proxy

 

/etc/nginx/nginx.conf

http {

    # Websocket Setting
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    upstream websocket {
        server 127.0.0.1:8888;
    }
 
    server {
        listen 8443 ssl http2 default_server;

        server_name _;

        ssl_certificate     "/etc/nginx/ssl/domain.crt";
        ssl_certificate_key "/etc/nginx/ssl/domain.key";

        ssl_session_cache shared:SSL:4m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        location = /favicon.ico { access_log off; log_not_found off; }
        location = /robots.txt { access_log off; log_not_found off; }

        # Websocket Setting
        location / {

            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_buffering       on;
            proxy_connect_timeout 15s;
            proxy_send_timeout    1d;
            proxy_read_timeout    1d;

            client_max_body_size       10m;

            proxy_pass http://websocket;
            
            proxy_http_version 1.1;
            proxy_set_header   Upgrade $http_upgrade;
            proxy_set_header   Connection $connection_upgrade;
        }
    }
}

Checking port

netstat -nltp | egrep -e "8888|8889"

tcp        0      0 0.0.0.0:8888            0.0.0.0:*       LISTEN      5443/php
tcp        0      0 0.0.0.0:8889            0.0.0.0:*       LISTEN      5752/nginx: master

Checking response

timeout=5
host=localhost
port=443
url="https://$host$port/wss/?token=check-db"

curl -s\
     -m $timeout \
     --include \
     --no-buffer \
     --header "Connection: Upgrade" \
     --header "Upgrade: websocket" \
     --header "Host: $host" \
     --header "Origin: https://$host" \
     --header "Sec-WebSocket-Version: 13" \
     --header "Sec-WebSocket-Key: RGF0YWh1bnRlclRlc3RXU1M" \
     $url

 


補充1: Protocol switch mechanism in HTTP/1.1

The Upgrade general-header allows the client to specify what

additional communication protocols it supports and would like to use it.

The server MUST use the Upgrade header field within a 101 (Switching Protocols) response

to indicate which protocol(s) are being switched

 

By default, the connection will be closed if the proxied server does not transmit any data within 60 seconds.

This timeout can be increased with the proxy_read_timeout directive.

Alternatively, the proxied server can be configured to periodically send WebSocket ping frames to reset the timeout and

check if the connection is still alive.

 


補充2: http header 的 cache

 

End-to-end 與 Hop-by-hop headers

End-to-end headers: for ultimate recipient

 => stored as part of a cache entry

Hop-by-hop headers: for a single transport-level connection

 => not stored by caches or forwarded by proxies

HTTP/1.1 hop-by-hop headers

  • - Connection
  • - Keep-Alive
  • - Proxy-Authenticate
  • - Proxy-Authorization
  • - TE
  • - Trailers
  • - Transfer-Encoding
  • - Upgrade

 


 

 

 

 

Creative Commons license icon Creative Commons license icon