0

I am running a MQTT Mosquitto server listening on port 8883 using TLS in a docker container with name 'mosquitto'.

In another docker container in the same network I am running an Apache webserver with a webpage at my_domain (at port 443).

The Apache should forward all requests to my_domain/mosquitto to the Mosquitto broker. using my_domain/mosquitto. Thus I add

  ProxyPreserveHost On
  ProxyPass /mosquitto ws://mosquitto:8883
  ProxyPassReverse /mosquitto ws://mosquitto:8883

to my httpd.conf which redirects https-browser-calls to my_domain/mosquitto to mosquitto. This of course result in an OpenSSL error at Mosquitto.

But using the MQTT client (python) results in Name or service not known

What I am doing wrong?

P.S.: The SSL keys / certificates for the Apache and the Mosquitto are different. When disabling the webserver, redirect the Mosquitto to port 443 via docker the connection is working.

LeifSec
  • 65
  • 8
  • Are you telling the python client to use the `/mosquitto` path? the default for MQTT over websockets is `/mqtt` – hardillb May 05 '21 at 10:46
  • I am telling the python client `/mosquitto` (= `my_domain/mosquitto`, I also tried `ws://my_domain/mosquitto`) because I have that `ProxyPass` in the `httpd.conf` of Apache for the sub directory `mosquitto`. In the config of mosquitto I have not enabled websockets. As I understood this is for using Mosquitto with browsers. – LeifSec May 06 '21 at 05:03
  • There 2 are two options I have found which I unfortunately cannot use: 1. Not using TLS and a Apache module for MQTT redirection 2. TLS termination in the Apache – LeifSec May 06 '21 at 05:09
  • 1
    You MUST use MQTT over Websockets in this case – hardillb May 06 '21 at 07:10

1 Answers1

1

To use a HTTP reverse proxy (Apache) to proxy for a MQTT broker you must use MQTT of Websockets (because WebSocket connections are bootstrapped over HTTP).

A native MQTT connection will just not work as Apache has no way of understanding the native protocol format.

You will need to enable a Websocket Listener in Mosquitto and tell the client to make a websocket connect.

You should also probably be using /mqtt not /mosquitto as the path to proxy as this is the default for WebSocket connects

hardillb
  • 54,545
  • 11
  • 67
  • 105
  • So `mosquitto.conf`: listener 8883 protocol websockets require_certificate true ... `httpd.conf: (mosquitto is the name of the docker container = hostname) ProxyPreserveHost On ProxyPass /mqtt wss://mosquitto:8883 ProxyPassReverse /mqtt wss://mosquitto:8883 client: (e.g. python / paho.mqtt) port = 443 broker = 'wss://domain_name/mqtt' client = mqtt_client.Client(transport="websockets") client.tls_set( ...) client.connect(broker, port) ??? – LeifSec May 06 '21 at 08:57
  • By the way: There is a Apache module for MQTT protocol processing - but this works only for none TLS connections. https://blog.benjamin-cabe.com/2015/10/01/how-to-run-your-web-server-and-mqtt-websockets-broker-on-the-same-port – LeifSec May 06 '21 at 12:52
  • 1
    No there isn't. If you read that blog post it is still using MQTT over WebSockets, it's just terminating the WebsSocket connection at Apache and then forwarding the native connection on to the broker. But given most brokers natively support WebSockets these days the module is no longer required. – hardillb May 06 '21 at 12:56
  • Activating `mod_proxy_wstunnel`, using `ProxyPass `/wss/ ws://mosquitto:8883`and `ServerName subdomain` (have now own subdomain for MQTT) did not help. The Apache Log does not show entries when trying to connect with the MQTT client (only by a browser). I have tried all mentioned combinations from https://stackoverflow.com/questions/17334319/setting-up-a-websocket-on-apache - accept the SSL termination in Apache by providing the MQTT certificates to it. – LeifSec May 06 '21 at 16:43
  • Finally It was possible using SNI and a dedicated proxy service which does not care about the content and thus, does not need to understand it. – LeifSec Jul 27 '21 at 14:28
  • This should now be possible with ALPN and something like NGINX's stream proxy, but SNI is just about which host name to pick – hardillb Jul 27 '21 at 15:43
  • Sorry I forgot to mention that I am using a own subdomain for MQTT now and thus, I can use SNI. Indeed am using NGINX's stream proxy. ALPN also works for the proxy but some MQTT clients have problems with it. – LeifSec Jul 27 '21 at 15:49