Tailscale - securing MQTT messages between 2 servers

I'm using a local raspberry pi a little like a hub, to connect to local IoT devices, and to pass the data via MQTT to a Oracle cloud server, to save the data on a database, and display it on Node-RED dashboards.
Having just updated both servers, I've used @BartButenaers's Tailscript guide to create a secure network.

Up to now, I've configured MQTT to work using both broker & client Public IP addresses in the normal manner, but realised that I can now reconfigure it to work completely within my Tailscale network, so I don't need TLS, certificates, etc, and trust Tailscale to ensure MQTT security & privacy.
So I thought I'd share the process here, if anyone else is interested.

  • It's important that both servers need to be in the same Tailscale network

First we need to bind the Mosquitto broker to the Tailscale IP to ensure it listens only on the tailnet, so on the broker obtain it's tailscale IPv4 address;

tailscale ip

Make a note of it, and then edit the Mosquitto config file - (typically /etc/mosquitto/mosquitto.conf or /etc/mosquitto/conf.d/default.conf)

listener 1883 100.x.x.x
allow_anonymous true

...using your desired port number, and the Tailscale IPv4 address which was obtained above.
(I listen on a different port for my local MQTT traffic)

Restart Mosquitto, usually sudo systemctl restart mosquitto

In the client MQTT node, use the same port number and also the same Tailscale IPv4 address which was obtained above.
Deploy and it should then subscribe to the broker.

NOTE!! If you setup Access Control, you may need to change or remove the ACL rule, so that the server is able to access the other server (between client & broker).

2 Likes

I did find a problem with this however.. If the system is rebooted, the Mosquitto service starts before Tailscale is fully loaded, which results in a Mosquitto error, which it does not recover from ;

1736531759: Opening ipv4 listen socket on port 1883.   <--- Local Port
1736531759: Opening ipv4 listen socket on port 2057.   <--- Tailscale Port
1736531759: Error: Cannot assign requested address

I tried adding a dependency in the Mosquitto service file;

[Unit]
After=tailscaled.service
Requires=tailscaled.service

which didn't work, I'm assuming that the Tailscale interface is not fully ready by the time the Mosquitto service starts.

So instead, added a 10 second delay to Mosquitto starting, by adding it to the Mosquitto service file;

[Service]
ExecStartPre=/bin/sleep 10

which seems a bit hacky, but none the less works reliably, although I'm open to other suggestions.

1 Like