Mqtt trough Cloudflare tunnel

I have some clients that connects to my mqtt server on subdom.domain.com:1883

My mqtt servers port 1883 is routed out on my router so it is accessible.

i want to route this traffic trough a Cloudflare tunnel insted.

i have tried to set up a tcp tunel to mqtt.domain.com pointing the local server at tcp://192.168.1.150:1883
This is done in the zero trust dashboard.

But my clients can not connect to it.
i can not change anything on the clients other than the hostname

Can this be done?

This is possible with Cloudflare Gateway. If you run the WARP client on the connecting devices, you can route private IP ranges through Cloudflare towards your tunnel connector. If you’re talking about devices that you can’t run WARP on and you’re trying a regular orange cloud/proxied configuration within Cloudflare, that won’t work. You can reverse proxy HTTP(S) in this way, but that’s not the same with arbitrary protocols like MQTT.

The only option I’m aware of for this (but haven’t personally used) would be Cloudflare Spectrum - you’ll need the Enterprise tier for TCP/UDP protocols:

1 Like

Thanks for clarifying that.

Is there any other way of achieving what i’m trying to do without requiring special client software?

The clients are esp8266 devices using https://github.com/knolleary/pubsubclient library for mqtt

No.

HTTP(S) services exposed through Cloudflare Tunnel don’t require client software because Cloudflare can use a single IP for multiple customers. This is possible because HTTP requests include a Host header telling which site the request is intended for.

Most other protocols don’t have a feature like that, so Cloudflare would have to assign separate IP addresses for each application. IPv4 addresses aren’t cheap which is why this isn’t offered.

For arbitrary TCP applications such as MQTT, you have use the client software, as it can act essentially like a VPN.

Took a while to wrap my head around but i think i got it :stuck_out_tongue:

Device looks up ip trough dns and then connects to ip on a port.

Only way this could be achieved is if Cloudflare could give away ports on a ip. i could then use a custom port for my routing.
Since that is the only information it can get on how to route the traffic after the dns lookup. (when not using http)

My isp has started to give out non public ip addresses to customers.
I now have to pay extra for a public ipv4 address.

For not it is ok but i would like to have alternatives ready for the future.

Have you tried using websockets instead of standard MQTT? Some (Many? Most?) MQTT brokers let you configure a websocket connection - mosquito does, for example. And I know there’s an option to enable websockets in the tunnel config, so maybe you can get that going.

i got mqtt over websockets to work by using http service protocol and routing to local ip:port

For now i will put a separate raspberry pi on the same network as my remote device and use that to route normal mqtt to my tunel over websocket.

i got mqtt over websockets to work by using http service protocol and routing to local ip:port

For now i will put a separate raspberry pi on the same network as my remote device and use that to route normal mqtt to my tunel over websocket.

i connect from remote using “wss://subdom.domain.com/”

Hey I’m trying to achieve the same, so what are you doing with the separate RPi? some mqtt forwarder to your cloudflare tunnel? how did you configure your access on cloudflare gui?
Thanks in advance!

In Cloudflare ->Zero Trust > Access >Tunels > tunnel name > Public host

-I added a entry of type http with url http://192.168.xxx.xxx:9001 where 9001 is the wss port of mosquitto

In mosquitto.conf add


listener 9001

protocol websockets

To forward topics i use node-red’s mqtt Client

I connect to the Remote pi using wss://sub_dom.domain_name/ with user and password

in node-red i forward only some selected topics to my local mqtt server from the Remote one .
And some selected topics to the Remote mqtt server from my local one

Be carefull so you do not publish the same topics both ways. You will end up in a infinite loop.

2 Likes

I managed to make my mqtt server (rabbitmq) hosted on my RaspberryPi also from websockets

I basically created an http tunnel to the port localhost:15675 so I can access it from Websockets: ‘ws://raspberrypi-mqtt.joaosilvagomes.com /ws’

Repo: GitHub - joaosgomes/Raspberry_Pi_3_Model_A: Raspberry_Pi_3_Model_A

I appreciate this thread and used it to help me write a Docker Compose configuration with step-by-step instructions for setting it up: GitHub - jzombie/docker-mqtt-mosquitto-cloudflare-tunnel: MQTT Broker via Cloudflare Tunnels, using Docker.