【问题标题】:Can't establish a connection with javascript to a secure websocket server无法使用 javascript 建立与安全 websocket 服务器的连接
【发布时间】:2021-10-20 19:18:01
【问题描述】:

我的开发环境是这样的:

  • 操作系统:Microsoft Windows 10
  • PHP 框架:Laravel 8.0
  • PHP 7.4 版
  • Websocket 服务器:cboden/ratchet 0.4.3
  • WAMP 服务器 3.2.0 (Apache 2.4.41)
  • Firefox 91.0.1(64 位)/铬

我创建了一个新的 Laravel 应用程序来实现安全 Websocket 服务器,并在客户端使用纯 JavaScript(Laravel 刀片文件)连接到它。 websocket 服务器工作正常,据我所见,它正在运行,但网络浏览器无法连接,如图所示:

我尝试过使用不同的 URL,有或没有端口号,但无济于事。 我使用 openssl.exe 工具创建了 SSL 证书和私钥文件,并将它们放在命令文件夹中进行测试。

这是我的安全 Websocket 服务器的句柄代码:

   public function handle()
   {
      $loop   = Factory::create();
      $webSock = new SecureServer(
         new Server('0.0.0.0:8090', $loop),
         $loop,
         array(
            'local_cert'        => 'certificate.crt', 
            'local_pk'          => 'private.key', 
            'allow_self_signed' => TRUE, 
            'verify_peer' => FALSE
         )
      );

      // Ratchet magic
      $webServer = new IoServer(
         new HttpServer(
            new WsServer(
               new WebSocketController()
            )
         ),
         $webSock
      );

      $loop->run();
   }

httpd-ssl.conf 文件中的我的虚拟主机:

<VirtualHost *:443>
  ServerName ssa
  DocumentRoot "d:/web/app/ssa/public"
  SSLEngine on
  
  SSLCertificateFile "${SRVROOT}/conf/certificate.crt"
  SSLCertificateKeyFile "${SRVROOT}/conf/private.key"

  SSLVerifyClient none
  SSLVerifyDepth 10

  <Directory "d:/web/app/ssa/public">
    Options +Indexes +Includes +FollowSymLinks +MultiViews
    AllowOverride All
    Require local
  </Directory>
  
  ProxyRequests Off 
  ProxyPass /wss/  ws://ssa:8090
</VirtualHost>

已加载 Apache 模块 proxy_module、proxy_http_module 和 proxy_wstunnel_module。 Web 应用程序以 HTTPS 运行。 之前,它通过 HTTP 和 WS 运行,一切正常,但我需要保护这个应用程序,我在连接到安全的 websocket 服务器时遇到问题。

我错过了什么吗?

我的 Websocket 服务器或 Apache 配置有问题吗?

【问题讨论】:

  • 请参考this question
  • 确保ssa 注册为它运行所在位置的 DNS 别名。如果它在本地,那么通常你需要修改你的主机文件
  • 是的@apokryfos,它在 hosts 文件中,应用程序在 HTTP / WS 协议下运行良好。
  • 尝试访问https://ssa 以在您的浏览器中批准自签名证书并使用https://ssa 作为您的套接字服务器,并且不要将套接字服务器作为安全服务器启动,因为您正在运行 apache 代理反正通过 https。

标签: javascript php laravel apache websocket


【解决方案1】:

为了不让更多信息使我的第一个答案复杂化,我在此提供了对我真正有用的答案。

我按如下方式创建了 Secure Websocket Server:

public function handle() {
      $loop = Factory::create();
      $webSock = new SecureServer(
         new Server('0.0.0.0:8443', $loop),
         $loop,
         array(
            'local_cert' => 'C:/wamp64/bin/apache/apache2.4.41/conf/server.crt',
            'local_pk' => 'C:/wamp64/bin/apache/apache2.4.41/conf/server.key', 
            'allow_self_signed' => TRUE, 
            'verify_peer' => FALSE
         )
      );
      $webServer = new IoServer(
         new HttpServer(
            new WsServer(
               new WebSocketController()
            )
         ),
         $webSock
      );
      $loop->run();
}

注意我把端口号改成了8443(我觉得这没什么关系),还改了新的证书和密钥文件,生成如下:

openssl req -config config.conf -new -x509 -out server.crt -days 3650

而config.conf文件是:

[req]
default_bits = 2048
encrypt_key = no
default_md = sha256
default_keyfile = server.key
distinguished_name = req_distinguished_name
prompt = no

[req_distinguished_name]
C = KH
ST = Siem Reap
L = SR
O = AHC
OU = IT
CN = localhost

[bs_section]
CA=false

所有区别都在于最后一行 CA=false 表明我没有签署或充当证书颁发机构 (CA)。 这消除了MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY 消息。

然后,我删除了在我的 httpd-ssl.conf 文件中定义代理的行:

<VirtualHost *:443>
  ServerName ssa
  DocumentRoot "d:/web/app/ssa/public"
  SSLEngine on
  
  SSLCertificateFile "${SRVROOT}/conf/server.crt"
  SSLCertificateKeyFile "${SRVROOT}/conf/server.key"

  SSLVerifyClient none
  SSLVerifyDepth 10

  <Directory "d:/web/app/ssa/public">
    Options +Indexes +Includes +FollowSymLinks +MultiViews
    AllowOverride All
    Require local
  </Directory>
  
  #Redirect /wss /wss/
  #ProxyPass /wss/ ws://127.0.0.1:8090/
  #ProxyPassReverse /ws/ wss://127.0.0.1:8090/
</VirtualHost>

请注意,对于这个虚拟主机,我使用了与 Secure Websocket Server 相同的证书和密钥文件。

好的,这就是我的证书问题。

现在一切正常。

【讨论】:

  • 记住在控制面板的“管理计算机证书”中注册证书很重要(Windows 10),也不要忘记去about:config并设置属性security.enterprise_roots.enabledTrue
  • 嗯,在这些更改之后,需要重新启动 Apache 服务器、Websocket 服务器和 Firefox 浏览器……我决定重新启动计算机,以防万一。
【解决方案2】:

好的,正如@apokryfos 指出的那样,我尝试通过 HTTPS 代理 websocket 服务器,但我做错了。

我将我的 websocket 服务器更改为非安全服务器,并对我的虚拟主机进行了以下更改:

<VirtualHost *:443>
  ServerName ssa
  DocumentRoot "d:/web/app/ssa/public"
  SSLEngine on
  
  SSLCertificateFile "${SRVROOT}/conf/certificate.crt"
  SSLCertificateKeyFile "${SRVROOT}/conf/private.key"

  SSLVerifyClient none
  SSLVerifyDepth 10

  <Directory "d:/web/app/ssa/public">
    Options +Indexes +Includes +FollowSymLinks +MultiViews
    AllowOverride All
    Require local
  </Directory>
  
  Redirect /wss /wss/
  ProxyPass /wss/ ws://127.0.0.1:8090/
  ProxyPassReverse /ws/ wss://127.0.0.1:8090/
</VirtualHost>

在客户端,浏览器现在可以通过 HTTPS 端口联系后端 WS 服务器:

// The connection to the WebSocket Server.
var socket = new WebSocket("wss://ssa:443/wss/");

我得到了这个解决方案 Apache Config: Websockets Proxy WSS request to WS backend

现在我的非安全 Websocket 服务器通过 HTTPS 发送/接收。 当然,这不是我期望应用到我的需求的解决方案,但它确实有效。 我仍然希望找到一个正式的解决方案,在不使用代理机制的情况下将纯 JavaScript 客户端连接到 Secure Websocket Server (wss://)。

【讨论】:

  • 在 Firefox 上,在“Web 开发人员工具”窗口中,我检查了“安全”选项卡,因为我在其他任何地方都没有看到错误详细信息,并且当我尝试连接时发现有 MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT到我的安全 Websocket 服务器。我尝试了几种解决方法,我在这里找到了允许使用自签名证书,但 wss://:8443 还没有运气
  • Ehmm... 不,没有任何安全警告,因为它曾经发生在 HTTPS 网页上。我已经去检查 Firefox about:config 并将 network.stricttransportsecurity.preloadlist 设置为“False”
  • 在 Windows 10 Internet 选项对话框中,我将我的 Web 应用程序添加到受信任的站点,然后我再次转到 about:config 并将属性值设置为“True”security .enterprise_roots.enabled 并重新启动浏览器。现在我收到错误 MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY
  • 我决定在途中使用 config.conf 文件创建另一个证书,我在其中指定 CA=false 以摆脱最后一条错误消息,因为我不是证书颁发机构来签署我的本地证书并且......很高兴看到它可以在我的 Firefox 控制台上运行,但不能从我的 JavaScript 文件中使用完全相同的 url var x = new WebSocket("wss://localhost:8443");。现在可能缺少什么?
【解决方案3】:

您肯定是在尝试连接到错误的目的地。它说的是 wss:///ssa/wss/,但可能应该是 wss://your.site.domain/ssa/wss/。

那么让我们看看前端代码,看看它有什么问题。

【讨论】:

  • 不,它是 ssa 这个应用程序的本地名称,所以在网页中看起来像 https://ssa/
  • 尽管我建议你检查网络标签。
猜你喜欢
  • 2012-10-17
  • 1970-01-01
  • 2023-03-13
  • 2015-07-24
  • 1970-01-01
  • 2021-01-02
  • 2014-04-09
  • 2020-04-06
  • 2014-07-09
相关资源
最近更新 更多