1

我有一个提供未加密 websocket 的 mqtt 代理。我想通过一个 Apache 代理它,它应该将 websocket 加密到外部。

它是 Windows 机器上的 Apache 2.4。

我的配置是:

<VirtualHost *:80>
  ServerName test.someurl.com

  RewriteEngine On
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)           ws://localhost:9876/$1 [P,L]
  
</VirtualHost>

<VirtualHost *:443>
  ServerName test.someurl.com
  
  SSLEngine on
  SSLCertificateFile "C:/Program Files (x86)/Apache24/conf/ssl/some_certificate.crt"
  SSLCertificateKeyFile "C:/Program Files (x86)/Apache24/conf/ssl/some_key.key"
  
  RewriteEngine On
  RewriteCond %{HTTP:Upgrade} =websocket [NC]
  RewriteRule /(.*)           ws://localhost:9876/$1 [P,L]

  # Websocket proxy
  # wss redirects to working ws protocol
  # ProxyPass /wss ws://127.0.0.1:9876 retry=0 keepalive=On 
  # ProxyPassReverse /wss ws://127.0.0.1:9876 retry=0
 </VirtualHost> 

我能够通过 ws / 端口 80 连接。它工作正常。但是,我无法使用 wss 进行连接。

我尝试使用重写和 proxy_pass 指令。我尝试了 100 种不同的解决方案。然而,这个看起来最有希望,因为端口 80 对 ws 有效,但对加密部分无效。任何想法?或者我只是被选项蒙蔽了O:)

4

1 回答 1

0

这是一个老问题,但因为我刚刚开始工作:

我让 Mosquitto 在端口 8000 上侦听(该端口有防火墙以阻止除本地主机以外的任何连接)

listener 8000
socket_domain ipv4
allow_anonymous true
protocol websockets

然后像这样设置apache:

<VirtualHost *:80>
  ProxyPass /ws/ ws://localhost:8000/
  ProxyPassReverse /ws/ ws://localhost:8000/
</VirtualHost>
<VirtualHost *:443>
    SSLCertificateFile ...
    SSLCertificateChainFile ...
    SSLCertificateKeyFile ...
    ProxyPass /ws/ ws://localhost:8000/
    ProxyPassReverse /ws/ ws://localhost:8000/
</VirtualHost>

最后,Web 应用程序设置为像这样连接:

mqtt.connect((window.location.protocol == "https:" ? "wss:" : "ws:") + "//example.org/ws/");

请注意,代理协议可以是“ws”或“wss”——两者似乎可以互换工作。这是apache和mosquitto之间的连接,不需要加密(它们在同一台主机上)。在路径上使用“/ws/”后缀意味着我可以不使用 mod_rewrite,而只需使用 mod_proxy。

这种方法是我在通过 HTTPS(这是公共的)而不是通过 HTTP(在防火墙后面)访问时要求身份验证的唯一方法。

于 2021-01-05T14:16:02.707 回答