首页 > 解决方案 > 如何使用 Nginx 进行安全 Web 套接字连接?

问题描述

我可以通过 JavaScript 直接将 Web 套接字连接到我的 PHP 守护程序服务器: var websocket = new WebSocket("ws://IP:PORT"); 这将正确地进行握手,但是当我尝试使用 nginx 代理http://IP时,它无法接收 Sec-WebSocket-Key 的标头值并且握手失败。

-- 最近更新:JavaScript 根本没有连接,原因是:SyntaxError:指定了无效或非法的字符串!

nginx配置文件:

    上游聊天网络套接字 {
        服务器 127.0.0.1:9090;
    }
    服务器 {
       # ...
       听 80 default_server;
       地点 / {
          proxy_pass http://chatwebsocket;
          ...
          proxy_set_header Sec-WebSocket-Key $http_sec_websocket_key;
       }

变量: $http_sec_websocket_key 未设置...为什么?我应该为此使用什么变量?我的 PHP 聊天服务器没有获取名为:Sec-Websocket-Key 的 Web 套接字标头“值”。我可以手动将其设置为一些虚拟值:proxy_set_header Sec-WebSocket-Key 13; 我的 PHP 日志文件将显示它有 13 个密钥。

此外,当我访问http://IP时,我可以在浏览器控制台窗口中检查响应标头。HTTP/1.1 400 Bad Key Request 这是我在 PHP 中创建的错误,当:注意 - $headers 被转换为小写并修剪......并且工作正常......

$headers[strtolower(trim($matches[1]))] = trim($matches[2]);
    if (!isset($headers['sec-websocket-key'])) {
       返回“HTTP/1.1 400 错误密钥请求”;//...

为什么?,我想这样做是因为一旦 HTTP 工作,我想使用 HTTPS 以加密形式安全地使用 WebSocket,同时保证我的网页流量安全。

我看过这些页面:https://github.com/die-net/nginx-config-example/blob/master/include/proxy-headershttp://nginx.org/en/docs/http/ ngx_http_proxy_module.html#proxy_set_header。不知道为什么 $http_sec_websocket_key 没有得到一个值集......或者用什么变量代替它?


似乎是一个 JavaScript 问题: var websocket = new WebSocket(' http://IP '); SyntaxError:指定了无效或非法的字符串

如何将 JavaScript 页面连接到 Nginx 网页代理,可以吗?或者我如何设置服务器来执行 wss://IP

或者 PHP 中的任何小的简单代码来执行 wss 套接字?


哈,我现在明白了,这是 Nginx 配置:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

upstream chatwebsocket {
    server 127.0.0.1:9090;
}

server {
    listen 8020;
    location / {
        proxy_pass http://chatwebsocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

我错过了 proxy_set_header **

升级

** $http_upgrade;

标签: javascriptphpwebsocketnginx-reverse-proxy

解决方案


在 JavaScript 中:var websocket = new WebSocket('wss://DomainName:443');

在 Nginx 中做:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

upstream appwebsocket {
    server 127.0.0.1:9090;
}

server {
    listen   443;
    server_name YOUR_Domain_Name_HERE;

    ssl  on;
    ssl_certificate  /etc/nginx/ssl/ssl.crt;
    ssl_certificate_key  /etc/nginx/ssl/ssl.key;

    ssl_session_timeout  5m;

    ssl_protocols  SSLv3 TLSv1;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
    ssl_prefer_server_ciphers   on;

    location / {
        proxy_pass http://appwebsocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }
}

进行连接升级是让所有东西都在 Nginx 中正常工作的门票。我不需要设置 Sec-WebSocket-Key 标头(在 nginx 中)!此外,我不需要重新编写我的 PHP 应用程序!

请记住,您可以将路径添加到 nginx 位置路径,这样您就可以保持网页在线并将网络套接字路由到该路径!


推荐阅读