最後更新: 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