Apache mod_proxy:将安全 websocket 转发到非安全 websocket

Apache mod_proxy:将安全 websocket 转发到非安全 websocket

我依赖的 websocket 库(PHP-Websockets) 尚不支持安全套接字 ( wss)。https但我的网站是通过此​​服务提供的,因此无法使用不安全的ws连接。

我正在尝试使用阿帕奇的mod_proxy将来自浏览器的安全请求转发到客户端。

JavaScript

var ws = new Websocket('wss://example.com/_ws_/');

Apache 虚拟主机

ProxyPass        "/_ws_/" "ws://127.0.0.1:8080/"
ProxyPassReverse "/_ws_/" "ws://127.0.0.1:8080/"
# I've also tried "/_ws_/" "ws://example.com:8080/"  Same error below

尝试连接时,浏览器会收到500 Server Error。日志显示:

对于 URL /_ws_/,没有有效的协议处理程序。如果您使用的是 mod_proxy 的 DSO 版本,请确保使用 LoadModule 将代理子模块包含在配置中。

我已经确认,如果我删除代理规则,停止将用户重定向到https并尝试从浏览器连接到不安全的套接字:new Websocket('ws://example.com/'),一切都会正常工作。

我加载的 Apache 模块包括mod_ssl.cmod_proxy.cmod_proxy_http.c

Apache 2.4

答案1

为了使它正常工作,我还需要加载mod_proxy_wstunnel

一旦我这样做了,这个规则集就可以让一切正常工作:(在VirtualHost接收和代理 websocket 请求的域中)

<IfModule mod_proxy.c>
    ProxyPass "/_ws_/" "ws://127.0.0.1:8080/"
    ProxyPassReverse "/_ws_/" "ws://127.0.0.1:8080/"
</IfModule>

然后浏览器可以通过 HTTPS 端口联系后端 WS 服务器:

var ws = new Websocket('wss://example.com/_ws_/');

答案2

我的代表没有给予我足够的权限来赞同上面的评论,我真的很难找到最好的答案,所以我将分享一个完整的例子,也许它会对你们中的一些人有所帮助。

<VirtualHost *:80>
    ServerName yourdomain.com
    DocumentRoot THEPATHGOESHERE/public
    DirectoryIndex index.php
    <Directory THEPATHGOESHERE/>
      AllowOverride All
      Order Deny,Allow
      Allow from all
    </Directory>
</VirtualHost>

<IfModule mod_ssl.c>
  <VirtualHost *:443>
      ServerName yourdomain.com
      DocumentRoot THEPATHGOESHERE/public
      DirectoryIndex index.php
      <Directory THEPATHGOESHERE/>
        AllowOverride All
        Order Deny,Allow
        Allow from all
      </Directory>

      SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/yourdomain.com/privkey.pem
      Include /etc/letsencrypt/options-ssl-apache.conf

      <IfModule mod_proxy.c>
          ProxyPass "/connection/websocket" "ws://yourdomain.com:8088/connection/websocket"
          ProxyPassReverse "/connection/websocket" "ws://yourdomain.com:8088/connection/websocket"
      </IfModule>

  </VirtualHost>
</IfModule>

答案3

我认为问题是你没有加载修改代理服务器模块。它是反向代理 WebSocket 连接所必需的。

相关内容