SSL 上帶有 Sails.js/Node.js 和 NGINX 的 Socket.io:網關錯誤
我剛開始涉足 NGINX 和 SSL。
使用 Ubuntu 16.04。
我在標準的 1337 埠上執行 Sails 伺服器,並使用 SSL 設置 NGINX(使用letsencrypt)。埠 80 被重定向到 443,上游轉到 Sails。
我還有一個 Tomcat 伺服器在 8080 上偵聽並使用 NGINX 以相同的方式重定向。
一切正常:我可以在 https 上瀏覽兩台伺服器,而無需瀏覽器上的特殊埠。
我已將 socket.io 設置為僅使用 websockets 協議(無輪詢)。這是在伺服器和瀏覽器客戶端上設置的。
但是,socket.io (sails.io) 在瀏覽器中拋出 502 錯誤。(投票也出錯了)
這是我的 NGINX 站點,可用於 Sails 伺服器:
upstream sails { server 127.0.0.1:1337 fail_timeout=0; } server { listen 80; listen [::]:80; server_name mysails.server.com; return 301 https://$server_name$request_uri; } server { listen 443; listen [::]:443 ssl http2; server_name mysails.server.com; include snippets/ssl-mysails.server.conf; include snippers/ssl-params.conf; large_client_header_buffers 8 32k; location / { proxy_pass http://sails/; proxy_http_version 1.1; proxy_redirect off; proxy_set_header Host $host; proxy_set_header Port $server_port; proxy_set_header X-Real-IP $remot_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_pass_request_headers on; } location /socket.io/ { proxy_pass http://sails/; proxy_http_version 1.1; proxy_redirect off; proxy_set_header Host $host; proxy_set_header Port $server_port; proxy_set_header X-Real-IP $remot_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; proxy_pass_request_headers on; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffers 8 32k; proxy_buffer_size 64k; } }
和
snippets/ssl-mysails.server.conf
文件snippers/ssl-params.conf
包含:ssl_certificate /path/to/letsencrypt/fullchain.pem; ssl_certificate_key /path/to/letsencrypt/privkey.pem;
和
# from https://cipherli.st/ # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Disable preloading HSTS for now. You can use the commented out header line that includes # the "preload" directive if you understand the implications. #add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/ssl/certs/dhparam.pem;
任何人都知道發生了什麼……?
更新錯誤日誌和奇怪的行為
我的 nginx 錯誤日誌這樣說:
upstream prematurely closed connection while reading response header from upstream, client: XXXXXXXX, server: mysals.server.com, request: "GET /socket.io/?__sails_io_sdk_version=0.13.8&__sails_io_sdk_platform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=websocket HTTP/1.1", upstream: "http://127.0.0.1:1337/?__sails_io_sdk_version=0.13.8&__sails_io_sdk_platform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=websocket", host: "mysails.server.com"
而且我的 Sails 詳細日誌不一致。它可能會這樣說:
*verbose*: Rendering view: "homepage" (located @ "/opt/FillForm/views/homepage") *verbose*: • using configured layout:: layout (located @ "/opt/FillForm/views/layout") *verbose*: Rendering view: "homepage" (located @ "/opt/FillForm/views/homepage") *verbose*: • using configured layout:: layout (located @ "/opt/FillForm/views/layout") *verbose*: Rendering view: "fileLink" (located @ "/opt/FillForm/views/fileLink") *verbose*: • using configured layout:: layout (located @ "/opt/FillForm/views/layout") *verbose*: Sending 404 ("Not Found") response *verbose*: Sending 404 ("Not Found") response *verbose*: Rendering view: "fileLink" (located @ "/opt/FillForm/views/fileLink") *verbose*: • using configured layout:: layout (located @ "/opt/FillForm/views/layout") *verbose*: Sending 404 ("Not Found") response *verbose*: Sending 404 ("Not Found") response
/opt/FillForm/views/fileLink
這很奇怪,因為視圖/頁面應該只有一個請求。如果您刷新頁面 (F5),瀏覽器上的 Javascript 控制台可能只會顯示:
Socket is trying to reconnect to Sails... _-|>_- (attempt #7)
每次嘗試都會導致一系列
verbose: Rendering view: "homepage" (located @ "/opt/FillForm/views/homepage") verbose: • using configured layout:: layout (located @ "/opt/FillForm/views/layout")
Sails 詳細日誌上的消息。為什麼套接字請求會導致 Sails 呈現首頁視圖?
如果您使用忽略記憶體 (shift+F5) 刷新,Javascript 控制台開始顯示嘗試和 502 bad gateway 消息:
WebSocket connection to 'wss://mysqils.server.com/socket.io/?__sails_io_sdk_version=0.13.8&__sails_io_s…tform=browser&__sails_io_sdk_language=javascript&EIO=3&transport=websocket' failed: Error during WebSocket handshake: Unexpected response code: 502 Socket is trying to reconnect to Sails... _-|>_- (attempt #20)
Sails 詳細日誌僅顯示以下消息的兩個實例:
verbose: Sending 404 ("Not Found") response verbose: Sending 404 ("Not Found") response
並且它停止顯示任何其他錯誤(不像在前面的場景中,每次 websocket 嘗試都會導致視圖呈現消息。)
在這種情況下,似乎 wss 請求沒有通過 Nginx 到達 Sails。
所以問題是 NGINX sites-avalable conf 文件的錯誤配置。
location /socket.io/ { proxy_pass http://sails/; ... }
應該
location /socket.io/ { proxy_pass http://sails/socket.io/; ... }
非常基本的東西:“位置”沒有轉發到 proxy_pass(為什麼會這樣,對嗎?)——所以你需要確保套接字請求被重定向到確切的套接字端點。