rumqttd
Overview
rumqttd is a fast, lightweight MQTT broker written in Rust, from the rumqtt project (Apache-2.0). The SecureAnyCloud image ships rumqttd 0.20.0 as a single static binary managed by systemd, configured to require authentication on every connection.
The VM generates a unique broker credential on first boot, so no two deployments share a password and nothing is baked into the image.
What you get:
- rumqttd 0.20.0 (pinned static musl binary, Apache-2.0) at
/usr/local/bin/rumqttd mosquitto-clients(mosquitto_pub,mosquitto_sub) for testing- MQTT v3.1.1 listener on TCP
1883 - Per-VM SecureAnyCloud broker credential rotated at first boot into /etc/rumqttd/rumqttd.toml
- Anonymous and wrong-credential connections rejected by the broker
rumqttd.servicerunning as an unprivilegedrumqttduser- Hardened Ubuntu 24.04 LTS base, patched at build time
- 24/7 SecureAnyCloud support
Prerequisites
- An Azure VM launched from this SecureAnyCloud image (recommended size Standard_B2s or larger)
- A network security group (NSG) that allows inbound TCP 22 (SSH) and TCP 1883 (MQTT) from only the client and device networks that need them
- SSH access as
azureuser
Restrict TCP 1883 in your NSG to your device and application subnets. Do not expose the broker to the whole internet.
Verify the broker is running
SSH in as azureuser. Then confirm that the service is active and listening on 1883:
sudo systemctl status rumqttd.service --no-pager -n 0
sudo ss -tln | grep 1883 /usr/local/bin/rumqttd --versionExpected output:
● rumqttd.service - rumqttd MQTT broker (sac) Loaded: loaded (/etc/systemd/system/rumqttd.service; enabled; preset: enabled) Active: active (running) Docs: https://secureanycloud.com/stacks/rumqttd/ Main PID: 1477 (rumqttd) LISTEN 0 1024 0.0.0.0:1883 0.0.0.0:* rumqttd 0.20.0Read the per-VM broker credential
First boot writes the SecureAnyCloud username and its randomly generated password to a root-only credentials file. Read it:
sudo cat /stage/scripts/rumqttd-credentials.logExpected output (your password differs, because it is unique to this VM):
# rumqttd — Per-VM Credentials
# MQTT v3.1.1 broker, port 1883. Anonymous connections are rejected. RUMQTTD_USER=sac RUMQTTD_PASSWORD=<set-at-first-boot> RUMQTTD_HOST=<your-vm-ip> RUMQTTD_PORT=1883Publish and subscribe
Use the generated credential to prove an end-to-end publish and subscribe round trip. This snippet subscribes for two messages, then publishes them:
PASS=$(sudo grep '^RUMQTTD_PASSWORD=' /stage/scripts/rumqttd-credentials.log | cut -d= -f2-) mosquitto_sub -h 127.0.0.1 -p 1883 -u sac -P "$PASS" -t 'demo/#' -C 2 -W 5 -v & sleep 1 mosquitto_pub -h 127.0.0.1 -p 1883 -u sac -P "$PASS" -t demo/temp -m '22.5' mosquitto_pub -h 127.0.0.1 -p 1883 -u sac -P "$PASS" -t demo/state -m 'online' waitExpected output, where the subscriber receives both messages:
demo/temp 22.5 demo/state onlineTo connect from a remote client, open TCP 1883 in your NSG first. Then replace 127.0.0.1 with the VM's IP.
Anonymous connections are rejected
The broker refuses any connection that lacks the correct credential. A publish with no username fails:
if mosquitto_pub -h 127.0.0.1 -p 1883 -t demo/temp -m 'nope' 2>/dev/null; then echo 'UNEXPECTED: anonymous accepted' else echo 'anonymous connection correctly rejected' fiExpected output:
anonymous connection correctly rejectedComponents
Component Path
Broker binary /usr/local/bin/rumqttd
Config /etc/rumqttd/rumqttd.toml (mode 0640 root:rumqttd)
Config template /usr/local/share/sac/rumqttd.toml.template
systemd unit /etc/systemd/system/rumqttd.service
First-boot unit /etc/systemd/system/rumqttd-firstboot.service
Credentials /stage/scripts/rumqttd-credentials.log (mode 0600 root:root)
Service user rumqttd (unprivileged, nologin)
The authentication table lives in the config under [v4.1.connections.auth]. Its entries look like this:
[v4.1] name = "v4-1" listen = "0.0.0.0:1883" [v4.1.connections.auth] sac = "<per-VM-password>"Security hardening
- Restrict the NSG so that TCP 1883 reaches only your device and application subnets.
- Add more users by adding
username = "password"lines under[v4.1.connections.auth]in/etc/rumqttd/rumqttd.toml. Then runsudo systemctl restart rumqttd. - Enable TLS by adding a
[v4.2]server block with atlssection (certificate and key paths) that listens on 8883, as described in the rumqttd documentation. - Patch regularly with
sudo apt-get update && sudo apt-get upgrade && sudo reboot. - Rotate the password by editing the auth table and restarting the service.
Licensing
The rumqtt project distributes rumqttd under the Apache-2.0 license, and it is free to use. SecureAnyCloud provides the pre-built, hardened image and commercial support separately. For questions, contact sales@secureanycloud.com.
Deploy on Azure
Launch rumqttd MQTT Broker on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
rumqttd is a lightweight, high-performance MQTT broker written in Rust, from the rumqtt project. It implements the MQTT v3.1.1 protocol over plain TCP. It is a single self-contained static binary with no runtime and no external services, which makes it a minimal, fast message backbone for IoT fleets, device telemetry and real-time, event-driven applications.
This guide covers deploying and configuring rumqttd from the SecureAnyCloud AWS Marketplace image. The image installs the official rumqttd binary (pinned and checksum-verified at build) and runs it under systemd as an unprivileged user, so an MQTT broker is listening within minutes of launch.
No baked MQTT password. There is no default MQTT password inside the image, and the shipped broker configuration carries no real password. A unique broker username and password are generated on this machine's first boot. They are rendered into the broker configuration and written to a root-only credentials file. No two instances share them, and none ships inside the image.
Authentication required. The broker enforces a username and password on every connection using a constant-time credential comparison. It rejects anonymous connections and wrong-credential connections.
What you get:
rumqttd(official pinned binary), run under systemd as the unprivileged rumqttd user (rumqttd.service)- The standard MQTT port 1883 (MQTT/TCP), listening on all interfaces so the broker is reachable inside your VPC
- A per-instance MQTT password generated on first boot and never baked into the image
- Anonymous access rejected and wrong-credential connections refused, out of the box
- Unattended security upgrades left enabled so the broker keeps receiving patches
Connecting to your instance
Connect over SSH on port 22 with the private key you selected at launch and the login user for your image variant:
OS variant SSH login user Example
Ubuntu 24.04 ubuntu ssh -i your-key.pem ubuntu@<instance-public-ip>
Prerequisites
- An AWS account, an EC2 key pair, and a VPC and subnet in the target region
- A subscription to the rumqttd listing on AWS Marketplace
- A security group that allows TCP 22 (admin) and TCP 1883 (MQTT) from the clients that will connect
Recommended instance type: m5.large (2 vCPU, 8 GB RAM) for a small to medium fleet. Busy brokers should use a larger m5 size.
Launch from the AWS Marketplace console
Find rumqttd Lightweight MQTT Broker by SecureAnyCloud in the AWS Marketplace. Click Continue to Subscribe, accept the terms, then click Continue to Launch.
Choose the m5.large instance type and select your VPC, subnet and key pair. Attach a security group that opens TCP 22 for administration and TCP 1883 (MQTT) from your client networks.
Treat plaintext 1883 as VPC-internal wherever you can. For production, front it with TLS or keep it in a private subnet.
Launch from the AWS CLI
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--associate-public-ip-address \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=rumqttd}]'Open the MQTT and admin ports on the instance's security group. In production, restrict their source to your client networks:
for p in 22 1883; do aws ec2 authorize-security-group-ingress --group-id <security-group-id> \
--protocol tcp --port "$p" --cidr <your-mgmt-cidr> doneFirst boot
On first boot, the image resolves the instance public IP through the EC2 instance metadata service (IMDSv2) and generates a per-instance MQTT password. It renders the password into the broker configuration and a root-only credentials file, then starts the broker. This completes within a minute.
SSH in as ubuntu and read the per-instance details, including the MQTT username and password:
sudo cat /stage/scripts/rumqttd-credentials.logConfirm the broker is running
Confirm that rumqttd.service is active and that the broker listens on 1883 (MQTT/TCP) on all interfaces:
systemctl is-active rumqttd.service ss -tln | grep ':1883'Prove a full MQTT round trip
Authenticate with the per-instance credential and complete a publish and subscribe round trip on 1883. The commands read the password from the root-only credentials file and subscribe in the background. They then publish a message and read it back:
PW="$(sudo grep '^RUMQTTD_PASSWORD=' /stage/scripts/rumqttd-credentials.log | cut -d= -f2-)" timeout 8 mosquitto_sub -h 127.0.0.1 -p 1883 -u sac -P "$PW" -t 'demo/status' -C 1 & sleep 1 mosquitto_pub -h 127.0.0.1 -p 1883 -u sac -P "$PW" -t 'demo/status' -m 'online' waitConfirm the broker is secure by default
The broker rejects anonymous connections and wrong-credential connections. Both commands below should fail with a non-zero exit and a lost-connection error, which proves that no client can reach the broker without the per-instance credential:
mosquitto_pub -h 127.0.0.1 -p 1883 -t 'demo/anon' -m 'x'; echo "anonymous exit code: $?" mosquitto_pub -h 127.0.0.1 -p 1883 -u sac -P 'wrong-password' -t 'demo/anon' -m 'x'; echo "wrong password exit code: $?"Publish and subscribe from a remote MQTT client
Any standard MQTT client can connect with the per-instance SecureAnyCloud username and password. From a remote client, use your instance's address (the RUMQTTD_HOST value in the credentials file) and pass the same username and password. Make sure the security group opens TCP 1883.
mosquitto_sub -h <public-ip> -p 1883 -u sac -P '<RUMQTTD_PASSWORD>' -t '#' -vmosquitto_pub -h <public-ip> -p 1883 -u sac -P '<RUMQTTD_PASSWORD>' -t 'demo/topic' -m 'hello from my app'The broker refuses connections that present no credentials or the wrong password. Anonymous access is rejected.
Manage MQTT users
The broker configuration lives at /etc/rumqttd/rumqttd.toml (readable by the rumqttd group). The per-connection credential is defined in the [v4.1.connections.auth] table, where each entry maps an MQTT username to its password. To add or change a user, edit that table. Then restart the broker:
sudo systemctl restart rumqttdKeep the configuration file readable only by root and the rumqttd group. Keep the credentials file (/stage/scripts/rumqttd-credentials.log) readable by root only.
Security recommendations
Restrict the security group. Allow TCP 1883 only from the client networks that need to connect, and allow TCP 22 for administration only.
Front the broker with TLS. rumqttd listens with plaintext MQTT on 1883. Treat it as internal or VPC-only, or terminate TLS in front of it for traffic that crosses untrusted networks. A reverse proxy or load balancer can do this.
Keep authentication enabled. The broker requires the per-instance username and password on every connection. Add per-client credentials as your fleet grows.
Keep the MQTT password secret. It is unique to this instance and lives in /stage/scripts/rumqttd-credentials.log (root only) and in the broker configuration. Rotate it by editing the [v4.1.connections.auth] table and restarting rumqttd.
Keep the OS and rumqttd patched. Unattended security upgrades remain enabled on the running instance.
Support and Licensing
The rumqtt project develops rumqttd and distributes it under the Apache-2.0 license. This SecureAnyCloud image bundles the unmodified official rumqttd binary. SecureAnyCloud provides the packaging, the secure-by-default first boot (per-instance MQTT password, anonymous access rejected), the systemd integration and 24/7 support.
SecureAnyCloud is not affiliated with or endorsed by the rumqtt project. rumqttd is a mark of its respective owner and is used here only to identify the software.
Need Help?
Email sales@secureanycloud.com for deployment help, configuration questions or licensing inquiries.
Deploy on AWS
Launch rumqttd Lightweight MQTT Broker by SecureAnyCloud with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com