RMQTT on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of RMQTT on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. RMQTT is a high performance, distributed MQTT broker written in Rust. It implements the MQTT v3.1, v3.1.1 and v5.0 protocols over plain TCP, TLS and WebSocket transports, and is designed to handle very large numbers of concurrent client connections with low latency, making it a solid message backbone for IoT fleets, device telemetry and real time, event driven applications.
The image installs the official RMQTT binary (pinned at build) and runs it under systemd, so an MQTT broker is listening within minutes of launch.
Security by design — no baked MQTT password. There is no default MQTT password inside the image. A unique broker username and password are generated on this machine's first boot and written to a root only file, and the password is injected into a local authentication backend rather than stored in the broker configuration. No two machines share it and none ships inside the image.
Security by design — anonymous access disabled. Every listener (TCP, TLS and WebSocket) rejects anonymous connections. Clients must present the per VM username and password, and sensible topic access control rules are applied out of the box.
Security by design — per VM TLS certificate. A unique self signed TLS certificate for the encrypted 8883 listener is generated on first boot, so the private key is never baked into the image. You can replace it with a certificate issued by a recognised authority at any time (see Step 9).
What is included:
-
RMQTT (official pinned binary), run under systemd as the unprivileged
rmqttuser (rmqtt.service) -
The standard MQTT ports: 1883 (MQTT/TCP), 8883 (MQTT/TLS) and 8080 (MQTT/WebSocket), listening on all interfaces so the broker is reachable inside your VNet
-
A local authentication backend (
rmqtt-authd.service) that validates the per VM username and password on every connection, with anonymous access disabled -
A per VM MQTT password and a per VM self signed TLS certificate, both generated on first boot and never baked into the image
-
Full MQTT v5.0 support, retained messages, shared subscriptions, a $SYS system topic metrics tree and pluggable access control
-
The HTTP management API bound to loopback only, so it is never exposed to the network
-
Unattended security upgrades left enabled so the broker keeps receiving patches
Prerequisites
-
Active Azure subscription, SSH public key, VNet + subnet in the target region
-
Subscription to the RMQTT listing on Azure Marketplace
-
Network Security Group rules allowing TCP 22 (admin), TCP 1883 (MQTT), TCP 8883 (MQTT/TLS) and TCP 8080 (MQTT/WebSocket) from the clients that will connect
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for a small fleet. Busy brokers should use Standard_D2s_v5 or larger.
Step 1: Deploy from the Azure Portal
Search RMQTT in Marketplace, select the cloudimg publisher, and click Create. Configure the Network Security Group to allow TCP 8883 (MQTT/TLS) and, where you need them, TCP 1883 (MQTT) and TCP 8080 (MQTT/WebSocket) from your client networks, and TCP 22 for administration. Prefer 8883 for real traffic; treat plaintext 1883 as VNet internal only where you can.
Step 2: Deploy from the Azure CLI
RG="mqtt-prod"; LOCATION="eastus"; VM_NAME="mqtt1"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/rmqtt-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$GALLERY_IMAGE_ID" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
# Open the MQTT and admin ports on the VM's NSG:
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 8883 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 1883 --priority 1002
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 8080 --priority 1003
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1004
Step 3: First boot
On first boot the image resolves the VM public IP, generates a per VM MQTT password and a per VM self signed TLS certificate, writes the authentication backend credential, and starts the broker. This completes within a minute. SSH in as azureuser and read the per VM details, including the MQTT username and password:
sudo cat /root/rmqtt-credentials.txt
Step 4: Confirm the broker is running
rmqtt.service and its authentication backend rmqtt-authd.service are active, and the broker listens on 1883 (TCP), 8883 (TLS) and 8080 (WebSocket).
systemctl is-active rmqtt.service rmqtt-authd.service
ss -tln | grep -E ':1883|:8883|:8080'

Step 5: Prove a full MQTT round trip
The image ships a self test that authenticates with the per VM credential, completes a publish and subscribe message round trip on 1883, confirms that a wrong password client and an anonymous client are both rejected, and completes a TLS handshake with an authenticated publish on 8883. Run it to prove the broker is healthy and secure end to end:
sudo python3 /usr/local/lib/cloudimg/rmqtt-roundtrip.py

Step 6: Confirm the TLS listener
The encrypted listener on 8883 presents the per VM self signed certificate. Inspect the handshake and certificate with openssl:
echo | openssl s_client -connect 127.0.0.1:8883 2>/dev/null | openssl x509 -noout -subject -issuer -dates

Step 7: Publish and subscribe with an MQTT client
Any standard MQTT client can connect with the per VM username (mqttadmin) and password. The examples below use the bundled mosquitto clients against the local broker and read the password from the credentials file; from a remote client, replace 127.0.0.1 with your VM's address (the rmqtt.host value in /root/rmqtt-credentials.txt), pass the same username and password, and make sure the NSG port is open.
Publish a retained message on 1883, then subscribe and read it back:
PW="$(sudo grep '^rmqtt.mqtt.password=' /root/rmqtt-credentials.txt | cut -d= -f2)"
mosquitto_pub -h 127.0.0.1 -p 1883 -u mqttadmin -P "$PW" -t 'demo/status' -m 'online' -r
timeout 8 mosquitto_sub -h 127.0.0.1 -p 1883 -u mqttadmin -P "$PW" -t 'demo/status' -C 1
For encrypted transport, publish over TLS on 8883, trusting the per VM certificate:
PW="$(sudo grep '^rmqtt.mqtt.password=' /root/rmqtt-credentials.txt | cut -d= -f2)"
timeout 10 mosquitto_pub -h 127.0.0.1 -p 8883 --cafile /etc/rmqtt/tls/cert.pem -u mqttadmin -P "$PW" -t 'demo/secure' -m 'encrypted hello' && echo "published over TLS on 8883"
Connections that present no credentials, or the wrong password, are refused: anonymous access is disabled on every listener.
Step 8: Topic access control
Topic authorization is governed by the rmqtt-acl plugin at /etc/rmqtt/plugins/rmqtt-acl.toml. The shipped rules give loopback tools full access, let the admin user monitor the $SYS/# metrics tree, prevent any client from subscribing to the bare # firehose, and allow authenticated clients to publish and subscribe otherwise. Edit the rules to fit your topic hierarchy, then reload the broker with sudo systemctl restart rmqtt.
To add or change the MQTT username and password, edit /etc/rmqtt/auth.env (root only) and restart both services with sudo systemctl restart rmqtt-authd rmqtt. For larger deployments, RMQTT also ships HTTP and JWT authentication plugins you can enable in /etc/rmqtt/rmqtt.toml.
Step 9: Replace the self signed TLS certificate (recommended)
The image ships a per VM self signed certificate so TLS works out of the box. For production, install a certificate issued by a recognised authority. Place your certificate and private key on the VM, point the 8883 (and any WebSocket TLS) listener at them in /etc/rmqtt/rmqtt.toml, and reload:
listener.tls.external.cert = "/etc/rmqtt/tls/cert.pem"
listener.tls.external.key = "/etc/rmqtt/tls/key.pem"
Replace /etc/rmqtt/tls/cert.pem and /etc/rmqtt/tls/key.pem with your issued certificate and key (keep the key readable by the rmqtt group), then restart the service with sudo systemctl restart rmqtt.
Step 10: Security recommendations
-
Restrict the NSG. Allow 8883 (and 1883 or 8080 where you must) only from the client networks that need to connect, and TCP 22 for administration only.
-
Prefer TLS. Use port 8883 for real traffic and install a CA issued certificate (Step 9). Treat plaintext 1883 as internal or VNet only where you can.
-
Keep anonymous access disabled. Every listener requires the per VM username and password. Add per client credentials or an external authentication plugin as your fleet grows.
-
Keep the MQTT password secret. It lives only in
/root/rmqtt-credentials.txt(root only) and/etc/rmqtt/auth.env, and is unique to this VM. Rotate it by editingauth.envand restartingrmqtt-authdandrmqtt. -
Keep the management API private. The RMQTT HTTP API is bound to loopback (127.0.0.1:6060) and is not exposed; keep it that way, or front it with authentication if you must reach it remotely.
-
Keep the OS and RMQTT patched. Unattended security upgrades remain enabled on the running VM.
Step 11: Support and Licensing
RMQTT is developed by the rmqtt project and distributed under the MIT license (dual licensed MIT OR Apache-2.0). This cloudimg image bundles the unmodified official RMQTT binary. cloudimg provides the packaging, the secure by default first boot (per VM MQTT password, per VM TLS certificate, anonymous access disabled), the systemd integration, and 24/7 support with a guaranteed 24 hour response SLA.
cloudimg is not affiliated with or endorsed by the RMQTT project. RMQTT is a mark of its respective owner and is used here only to identify the software.

Deploy on Azure
Find RMQTT on Ubuntu 24.04 LTS on the Azure Marketplace, published by cloudimg. Deploy from the Portal or the Azure CLI as shown above.
Need Help?
Email support@cloudimg.co.uk for deployment help, configuration questions, or licensing enquiries.