RMQTT 0.24.0
Overview
RMQTT is an open-source (MIT) MQTT broker written in Rust. It serves MQTT 5.0 and 3.1.1, the publish/subscribe protocol used by IoT devices, sensors, vehicles, home automation and mobile apps. Any MQTT client works with it, including the Mosquitto command-line tools mosquitto_pub and mosquitto_sub, Eclipse Paho (Python, Java, C, Go, JavaScript), MQTT.js and HiveMQ client libraries.
Clients publish messages to topics, such as sensors/17/temperature. The broker delivers each message to every client subscribed to a matching topic filter, such as sensors/+/temperature or sensors/#.
This guide covers launching and using the RMQTT 0.24.0 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud streaming and messaging listing on AWS Marketplace. You pick it as the software version when you subscribe.
What you get:
- MQTT over TLS only. Clients reach the broker on 8883 (MQTT over TLS 1.3 or 1.2 with AEAD cipher suites only). RMQTT's usual clear-text port 1883, its internal port 11883, WebSockets (8080 and 8443), QUIC (9443) and the HTTP management API (6060) are not configured. Nothing answers on them even if a security group allows them (Step 10).
- A certificate made on your instance. At first boot the broker gets a TLS key and an end-entity certificate for this instance's own names and addresses. It can only vouch for this broker and can never sign other certificates. You pin it in your clients (Step 5), or replace it with one from your own CA or Let's Encrypt (Step 12).
- No anonymous access and no default password. Every client logs in. First boot generates a login unique to your instance,
sac-app, with a 128-bit random password. Passwords are stored only as salted PBKDF2-SHA256 hashes, in a file the broker process itself cannot read. A separate login service,rmqtt-authd, checks them on the loopback address. - Every login confined to its own topic tree. The topic rules let each login publish and subscribe only under
<login>/#(sosac-appusessac-app/#) and deny everything else, including#and$SYS/#. There is no superuser (Step 8). - Users you can manage safely.
rmqtt-useradds a login with its password read from standard input, never a command line. A new login works at once, with no restart (Step 8). - A broker that refuses to run unsafely. Before every start, a configuration gate refuses an unsafe change: a clear-text, WebSocket or QUIC listener, anonymous clients, the HTTP API, the cluster port on a public address, topic rules that end by allowing, or a login service that fails open. After every start, a guard checks the running broker's sockets, logins and network rules, and stops it if anything is wrong. If first boot cannot finish, the broker never serves (Step 9).
- No telemetry, no instance metadata, no outbound network. RMQTT has no telemetry. The broker and the login service run with the EC2 instance metadata address blocked. A firewall table lets the broker's user reach nothing but the login service, so every outbound connection, including to your own VPC, is refused (Step 11).
- A pinned supply chain. The
rmqttdbinary comes from the RMQTT project's GitHub release0.24.0(rmqtt-0.24.0-x86_64-unknown-linux-musl.zip), checked against its SHA-256 digest. Every shipped file is recorded in/usr/share/doc/sac-rmqtt/PROVENANCE. Ubuntu 24.04 LTS is fully patched at build time. - RMQTT 0.24.0 at /usr/local/bin/rmqttd, with configuration in /etc/rmqtt/rmqtt.toml, plugin settings in /etc/rmqtt/plugins/ and logins in /etc/rmqtt-auth/
- The plugins rmqtt-acl (topic rules), rmqtt-auth-http (logins, checked by rmqtt-authd), rmqtt-retainer (retained messages) and rmqtt-shared-subscription
- The SecureAnyCloud helpers rmqtt-probe (an MQTT test client), rmqtt-selfcheck, rmqtt-user, rmqtt-set-hostname, rmqtt-install-cert and rmqtt-config-gate
Defaults: default user ubuntu, x86_64 architecture, recommended instance type m5.large.
Prerequisites
- An AWS account subscribed to the listing
- An EC2 key pair
- A VPC subnet with a route to the internet, or a private route that you use for management
- A security group that allows the two inbound rules below
Security group rules:
- Port 22, TCP, from your admin network: SSH
- Port 8883, TCP, from the networks your MQTT clients connect from: MQTT over TLS
Nothing else needs to be open. Ports 1883 and 11883 (clear-text MQTT), 8080 and 8443 (WebSockets), 9443 (QUIC), 6060 (HTTP API) and 5363 (cluster gRPC) are not served to the network, so opening them achieves nothing.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick RMQTT 0.24.0 on Ubuntu 24.04 as the software version, choose your Region, and then choose Launch through EC2.
Choose m5.large, or a larger size for many thousands of connections or high message rates. Select your key pair and a security group as described above.
To launch with the AWS CLI instead, replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=rmqtt-broker}]'The image requires IMDSv2 (session tokens).
First boot takes under a minute after the instance is running. The boot service reads the instance's EC2 names and creates the login and the certificate. Then the login service and the broker start, and the guard checks them.
Connect to your instance
The version is RMQTT 0.24.0 on Ubuntu 24.04, and the SSH user is ubuntu. Connect with the key pair you chose at launch:
ssh -i <your-key.pem> ubuntu@<public-ip>The login banner shows where to find the login and the certificate:
RMQTT 0.24.0 on Ubuntu 24.04 (sac) Login, endpoint, certificate fingerprint:
sudo cat /root/rmqtt-credentials.txt Clients: MQTT over TLS only, mqtts://<this host>:8883 (pin /etc/rmqtt/tls/cert.pem); topics <login>/# Broker: systemctl status rmqtt journalctl -u rmqtt Verify:
sudo rmqtt-selfcheck Users:
sudo rmqtt-user list User guide: https://secureanycloud.com/stacks/rmqtt-0-24-0/Check the services and listening ports
Confirm that all five services are active and that only the expected ports are listening:
systemctl is-active rmqtt-metadata-names rmqtt-firstboot rmqtt-egress-guard rmqtt-authd rmqtt
sudo ss -tlnp | grep -E ':(22|80|443|960|1883|5363|6060|8080|8443|8883|11883) '
sudo ss -ulnp | grep -E 'rmqtt|python3' || echo 'no UDP socket'active active active active active LISTEN 0 1024 0.0.0.0:8883 0.0.0.0:* users:(("rmqttd",pid=1057,fd=10)) LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1059,fd=3),("systemd",pid=1,fd=57)) LISTEN 0 128 127.0.0.1:5363 0.0.0.0:* users:(("rmqttd",pid=1057,fd=9)) LISTEN 0 256 127.0.0.1:960 0.0.0.0:* users:(("python3",pid=1050,fd=3)) LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=1059,fd=4),("systemd",pid=1,fd=58)) no UDP socketThe five services do the following:
rmqtt-metadata-namesreads this instance's EC2 names for the certificate.rmqtt-firstbootprepares the login and the certificate.rmqtt-egress-guardloads the broker's firewall table.rmqtt-authdis the login service.rmqttis the broker.
The broker listens on 8883 (every IPv4 address) for clients. RMQTT always starts a cluster gRPC server. Here it is bound to 127.0.0.1:5363, and the firewall table refuses it even on the loopback address, because this image runs a single node.
The login service listens on 127.0.0.1:960 only. That is a privileged port that no ordinary user can take over, and only the broker's user may connect to it.
Your endpoint and login
Everything generated for your instance is in /root/rmqtt-credentials.txt, readable by root only. View it all with sudo cat /root/rmqtt-credentials.txt. This command shows only the lines that are not secret:
sudo grep -E '^RMQTT_(HOST|URL|PORT|PRIVATE_IP|USER|TOPIC_PREFIX|TLS_CA_FILE|TLS_CERT_SHA256|TLS_PUBKEY_SHA256)=' /root/rmqtt-credentials.txtRMQTT_HOST=34.227.171.134 RMQTT_URL=mqtts://34.227.171.134:8883 RMQTT_PORT=8883 RMQTT_PRIVATE_IP=172.31.87.173 RMQTT_USER=sac-app RMQTT_TOPIC_PREFIX=sac-app/ RMQTT_TLS_CA_FILE=/etc/rmqtt/tls/cert.pem RMQTT_TLS_CERT_SHA256=4D:42:56:C6:24:0A:F6:AB:3B:67:E3:3B:00:93:52:1C:3F:F2:23:53:13:6C:03:6D:3E:DC:CD:B3:65:3B:66:A0 RMQTT_TLS_PUBKEY_SHA256=ea1916b7c208fe504d4fb1d553d000e5b4e6cb6a2d17924a70d8981d7cb1365dThe file also holds RMQTT_PASSWORD, the password of sac-app. That login may use only topics that start with sac-app/. Give each device type or application a login of its own (Step 8) rather than sharing this one.
Keep passwords in files with mode 0600, not in shell history or on command lines. Every user on a machine can see a command line through ps.
Check the certificate and pin it in your client
The broker's certificate is self-signed and made on your instance. Inspect it:
sudo openssl x509 -in /etc/rmqtt/tls/cert.pem -noout -subject -enddate -ext subjectAltName,basicConstraints
sudo openssl x509 -in /etc/rmqtt/tls/cert.pem -noout -fingerprint -sha256subject=CN = rmqtt-broker, O = sac notAfter=Feb 10 10:46:46 2029 GMT X509v3 Subject Alternative Name: IP Address:34.227.171.134, DNS:ec2-34-227-171-134.compute-1.amazonaws.com, IP Address:172.31.87.173, DNS:ip-172-31-87-173.ec2.internal, IP Address:127.0.0.1, DNS:localhost X509v3 Basic Constraints: critical CA:FALSE sha256 Fingerprint=4D:42:56:C6:24:0A:F6:AB:3B:67:E3:3B:00:93:52:1C:3F:F2:23:53:13:6C:03:6D:3E:DC:CD:B3:65:3B:66:A0CA:FALSE means it is an end-entity certificate that cannot sign anything else. The SHA-256 fingerprint is the RMQTT_TLS_CERT_SHA256 value in your credentials file.
Copy the certificate to each client machine. The certificate is public, and the private key never leaves the instance:
client-host$ ssh -i <your-key.pem> ubuntu@<public-ip> 'sudo cat /etc/rmqtt/tls/cert.pem' > rmqtt.crt client-host$ openssl x509 -in rmqtt.crt -noout -fingerprint -sha256Compare the fingerprint with RMQTT_TLS_CERT_SHA256 before you trust the file. Then give your client only this file as its CA file, with host name checking on. Use --cafile for mosquitto_pub and mosquitto_sub, and tls_set(ca_certs=...) in Paho.
Do not add the file to the operating system's trust store. The client should trust this one broker, not every program on the machine. Your client then refuses any other server, including a man-in-the-middle that presents a different certificate. A client that uses only its system trust store is refused with CERTIFICATE_VERIFY_FAILED.
The certificate covers the instance's public and private IPv4 addresses and EC2 DNS names, localhost and 127.0.0.1. An EC2 stop and start gives the instance a new public IP. At the next boot, the certificate is re-issued for the new names with the same key. Clients that pin the public key (RMQTT_TLS_PUBKEY_SHA256) keep working, while clients that pin the certificate file need the new copy.
Test on the instance
rmqtt-probe is a small MQTT client. It reads passwords from a file, or from the credentials file with --identity app, and trusts only the broker's certificate. Run these checks:
sudo rmqtt-probe connect --identity app
sudo rmqtt-probe connect --identity app --proto 5
sudo rmqtt-probe roundtrip --identity app --topic sac-app/guide-test
sudo rmqtt-probe acl --identity app || true
sudo rmqtt-probe connect --anonymous || true
sudo rmqtt-probe plain || trueCONNACK-OK proto=4 tls=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 CONNACK-OK proto=5 tls=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 ROUNDTRIP OK topic=sac-app/guide-test qos=1 bytes=43 proto=4 tls=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 ACL-DENIED subscribe(#,+/#,$SYS/#,other tree,$share other tree)=0x80 publish(other tree)=disconnected own-tree=ok REFUSED rc=4 bad-username-or-password proto=4 NOT-MQTT-PLAIN 15030300020232The output shows the following:
- The login connects with MQTT 3.1.1 and 5.0, subscribes to
sac-app/guide-test, publishes a message there and receives it back. aclshows the topic rules. Subscriptions to#,+/#,$SYS/#, another login's tree or a shared subscription on another tree are refused (SUBACK0x80). A publish outside the login's own tree disconnects the client, while its own tree still works.- A client without a login, with a wrong password or with an unknown user name is refused with CONNACK code 4 (MQTT 5.0: reason
0x86, bad user name or password). The broker does not say which part was wrong. - Clear-text MQTT sent to 8883 gets a TLS alert, never an MQTT answer.
rmqtt-probe exits non-zero on a refusal, hence || true.
Connect a client from another machine
On the client machine, install the Mosquitto command-line clients and copy the certificate as in Step 5. Use sudo apt-get install mosquitto-clients on Ubuntu or Debian, or brew install mosquitto on macOS.
Then put the connection settings in an options file that only you can read. mosquitto_pub and mosquitto_sub read their default options, one per line, from mosquitto_pub and mosquitto_sub files in the directory named by XDG_CONFIG_HOME (normally ~/.config). This keeps the password off the command line. A directory of its own lets you keep one set of options per broker and login:
client-host$ umask 077; mkdir -p ~/mqtt-app client-host$ printf -- '-h <public-ip>\n-p 8883\n--cafile %s/rmqtt.crt\n-u sac-app\n' "$PWD" > ~/mqtt-app/mosquitto_pub client-host$ ssh -i <your-key.pem> ubuntu@<public-ip> "sudo sed -n 's/^RMQTT_PASSWORD=/-P /p' /root/rmqtt-credentials.txt" >> ~/mqtt-app/mosquitto_pub client-host$ cp ~/mqtt-app/mosquitto_pub ~/mqtt-app/mosquitto_subSubscribe in one terminal, and publish from another:
client-host$ XDG_CONFIG_HOME=~/mqtt-app mosquitto_sub -t 'sac-app/demo/#' -q 1 -v client-host$ XDG_CONFIG_HOME=~/mqtt-app mosquitto_pub -t sac-app/demo/hello -q 1 -m 'hello from mosquitto_pub'sac-app/demo/hello hello from mosquitto_pubFor -h, use a name the certificate covers: the public or private IP, an EC2 DNS name, or your own DNS name once you have added it (Step 12).
Outside sac-app/#, the broker refuses the login's subscriptions and mosquitto_sub prints All subscription requests were denied. The broker disconnects the login when it publishes there, and mosquitto_pub prints Error: The connection was lost.
You can do the same from Python with Eclipse Paho. Install it with sudo apt-get install python3-paho-mqtt or pip install paho-mqtt:
# paho_demo.py - publish and receive through your sac RMQTT broker over MQTT/TLS (paho-mqtt 1.6 or 2.x).
# Usage:
python3 paho_demo.py <broker-host> <rmqtt.crt> <user> <password-file> <topic>
# The password is read from a file, never the command line; TLS trusts ONLY the broker's own certificate. import ssl import sys import threading import paho.mqtt.client as mqtt host, cafile, user, pwfile, topic = sys.argv[1:6] with open(pwfile) as f: password = f.read().strip() got = threading.Event() try: c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2) except AttributeError: # paho-mqtt 1.x c = mqtt.Client() c.username_pw_set(user, password) c.tls_set(ca_certs=cafile, tls_version=ssl.PROTOCOL_TLS_CLIENT) # verify against this one certificate, host name checked c.on_connect = lambda cl, *a: cl.subscribe(topic, qos=1) c.on_subscribe = lambda cl, *a: cl.publish(topic, b"hello from paho", qos=1) c.on_message = lambda cl, u, m: (print("received:", m.topic, m.payload.decode()), got.set()) c.connect(host, 8883) c.loop_start() ok = got.wait(15) c.loop_stop() c.disconnect() sys.exit(0 if ok else 1)client-host$ ssh -i <your-key.pem> ubuntu@<public-ip> "sudo sed -n 's/^RMQTT_PASSWORD=//p' /root/rmqtt-credentials.txt" > app.password client-host$ python3 paho_demo.py <public-ip> rmqtt.crt sac-app app.password sac-app/paho-demo received: sac-app/paho-demo hello from pahoThe URL form is mqtts://<public-ip>:8883. Some clients accept the login inside the URL (mqtts://sac-app:<password>@...). If yours does, build the URL inside your program from the password file. Do not write it in a configuration file or on a command line.
Add users and topic permissions
Give each device type or application its own login rather than sharing one. rmqtt-user reads the new password from standard input or a hidden prompt. It stores only the PBKDF2-SHA256 hash, and the login works at once with no broker restart:
umask 077 openssl rand -hex 16 > ~/sensors.password
sudo rmqtt-user add sensors < ~/sensors.password
sudo rmqtt-user listadded sensors: publish and subscribe under sensors/# only sac-app topics=sac-app/# (publish and subscribe; everything else denied) sensors topics=sensors/# (publish and subscribe; everything else denied)The topic rules are the same for every login. A login may publish and subscribe under its own name and nothing else, so sensors uses sensors/#. Choose login names to match the topic trees your devices use.
User names are 1 to 32 characters (a-z, 0-9, _ and -). The names sys, admin, root, rmqtt, all and anonymous are reserved. Passwords must be 16 to 128 characters.
Try the new login:
sudo rmqtt-probe acl --user sensors --password-file ~/sensors.password || true
sudo rmqtt-probe roundtrip --user sensors --password-file ~/sensors.password --topic sensors/17/temperatureACL-DENIED subscribe(#,+/#,$SYS/#,other tree,$share other tree)=0x80 publish(other tree)=disconnected own-tree=ok ROUNDTRIP OK topic=sensors/17/temperature qos=1 bytes=43 proto=4 tls=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384Hand ~/sensors.password to your application's secret store, then delete the local copy.
sudo rmqtt-user passwd <name> changes a password, reading it from standard input as add does. The old password is refused from the next login. sudo rmqtt-user remove <name> deletes a login. Clients already connected with it stay connected until they disconnect, and the last login cannot be removed.
To remove the example user again:
sudo rmqtt-user remove sensors shred -u ~/sensors.passwordWhere the topic rules live. They are in /etc/rmqtt/plugins/rmqtt-acl.toml. One rule allows %u/# (the login's own tree) for publish and subscribe, and a final rule is ["deny", "all"].
Keep the deny rule last. Rules are checked in order and the first match wins, so a rule placed after it never applies. The configuration gate refuses to start the broker if the list ends with anything else.
Logins are checked only by rmqtt-authd, never by the topic rules, and the gate refuses a rule that names a superuser. After an edit, run sudo systemctl restart rmqtt. Connected clients are disconnected and must reconnect.
The broker refuses to run unsafely
rmqtt.service runs rmqtt-config-gate before every start and rmqtt-guard after it. At any time, you can check the gate, and the whole broker as a client sees it:
sudo rmqtt-config-gate --unit && echo gate-ok
sudo rmqtt-selfcheckrmqtt-config-gate: OK (unit) gate-ok SELFCHECK OK tls-roundtrip; acl; anonymous,wrong-password,unknown-user refused; clear-text refused, 1883/8080/6060/11883 closedThe gate refuses a change, and the broker does not start, if you edit /etc/rmqtt/rmqtt.toml or a plugin file and do any of the following:
- add a clear-text, internal, WebSocket or QUIC listener
- allow anonymous clients
- move the gRPC server off
127.0.0.1 - enable the HTTP API plugin
- turn on debug logging
- end the topic rules with anything but
["deny", "all"] - set
deny_if_error = falsefor the login check - loosen the permissions of the configuration, the TLS key or the login file
journalctl -u rmqtt shows the reason.
The guard stops the running broker if it ever listens anywhere it should not, accepts an anonymous login or runs without its firewall table. If the login service stops, the broker stops with it. If the login service hangs, every login is refused rather than allowed.
Why 1883, WebSockets, the HTTP API and the cluster ports are closed
RMQTT's example configuration opens a clear-text listener on 1883 and another on 11883, WebSockets on 8080 and 8443, QUIC on 9443, an HTTP management API on 6060 and its cluster gRPC server on 5363. On a cloud instance, each of these is a way around TLS or the logins. User names, passwords and every message cross the network in clear text on 1883, and the HTTP API and the cluster port can manage the broker.
This image configures exactly one network listener, MQTT over TLS on 8883. It does this in RMQTT's own configuration rather than relying on a firewall:
- 1883 and 11883 (MQTT): not configured. Every maintained MQTT client supports TLS on 8883.
- 8080 and 8443 (WebSockets) and 9443 (QUIC): not configured. A browser application should reach MQTT through your own back end.
- 6060 (HTTP API): the
rmqtt-http-apiplugin is disabled and the gate refuses it. Manage logins withrmqtt-user. - 5363 (cluster gRPC): bound to
127.0.0.1and refused by the firewall table, because this image is a single node. - Anonymous access: refused (
allow_anonymous = false).
From another machine, even inside a security group that allows all traffic, a connection to 1883, 11883, 8080, 8443, 9443, 6060, 5363, 960, 80 or 443 is refused. Clear-text MQTT sent to 8883 gets no MQTT answer. On the instance itself, check which ports are open:
IP=$(sudo sed -n 's/^RMQTT_PRIVATE_IP=//p' /root/rmqtt-credentials.txt) for p in 1883 8080 8443 6060 5363 11883 8883; do nc -z -w 3 "$IP" "$p" 2>/dev/null && echo "$p open" || echo "$p closed"; done1883 closed 8080 closed 8443 closed 6060 closed 5363 closed 11883 closed 8883 openThe broker also limits load on 8883, so that idle or slow clients cannot keep real clients out:
- At most 1,000 connections from one source address and 12,000 in all
- At most 10,000 sessions
- A 10 second TLS handshake timeout
- A 1 MB packet limit
The instance metadata block and outbound traffic
The EC2 instance metadata service (169.254.169.254) hands out the instance's IAM role credentials to any process that asks, so a network service must not be able to reach it.
rmqtt and rmqtt-firstboot run with the metadata addresses blocked by systemd (IPAddressDeny). rmqtt-authd may reach 127.0.0.1 only. Only rmqtt-metadata-names, which reads the instance's names for the certificate, may reach the metadata service, and it may reach nothing else:
for u in rmqtt rmqtt-authd rmqtt-firstboot rmqtt-metadata-names; do printf '%-22s deny=%s allow=%s\n' "$u" "$(systemctl show -p IPAddressDeny --value "$u")" "$(systemctl show -p IPAddressAllow --value "$u")"; donermqtt deny=::ffff:168.63.129.16/128 169.254.169.254/32 168.63.129.16/32 ::ffff:169.254.169.254/128 fd00:ec2::254/128 allow= rmqtt-authd deny=::/0 0.0.0.0/0 allow=127.0.0.1/32 rmqtt-firstboot deny=169.254.169.254/32 fd00:ec2::254/128 ::ffff:169.254.169.254/128 168.63.129.16/32 ::ffff:168.63.129.16/128 allow= rmqtt-metadata-names deny=0.0.0.0/0 ::/0 allow=fd00:ec2::254/128 169.254.169.254/32On top of that, the nftables table inet sac_rmqtt_egress denies all outbound traffic, IPv4 and IPv6, for the broker's user rmqtt and the login service's user rmqtt-auth. Only the broker's answers to its clients and its own connection to the login service on 127.0.0.1:960 are allowed.
The broker cannot reach the metadata service, the internet, your VPC or DNS, whatever its configuration says. Other users are unaffected:
IP=$(sudo sed -n 's/^RMQTT_PRIVATE_IP=//p' /root/rmqtt-credentials.txt) for t in http://169.254.169.254/latest/meta-data/ https://1.1.1.1/ "http://$IP:22/"; do
sudo -u rmqtt curl -s -m 5 -o /dev/null -w "rmqtt -> $t: %{http_code} %{errormsg}\n" "$t" || true; done curl -s -m 5 -o /dev/null -w "ubuntu -> https://1.1.1.1/: %{http_code}\n" https://1.1.1.1/rmqtt -> http://169.254.169.254/latest/meta-data/: 000 Failed to connect to 169.254.169.254 port 80 after 0 ms: Couldn't connect to server rmqtt -> https://1.1.1.1/: 000 Failed to connect to 1.1.1.1 port 443 after 0 ms: Couldn't connect to server rmqtt -> http://172.31.87.173:22/: 000 Failed to connect to 172.31.87.173 port 22 after 0 ms: Couldn't connect to server ubuntu -> https://1.1.1.1/: 301rmqtt-egress-guard.service loads the table before the broker starts, and the broker requires it. If the table is removed, the guard stops the broker.
Use your own DNS name or a certificate from your CA
Point a DNS name at the instance. An Elastic IP keeps the address across stop and start. Then add the name to the certificate:
sudo rmqtt-set-hostname <dns-name>This re-issues the self-signed certificate with the same key to cover the name, updates the endpoint in /root/rmqtt-credentials.txt and restarts the broker. Copy the new certificate to clients that pin the certificate file.
To use a certificate from your own CA, or a public one such as Let's Encrypt, copy the chain (server certificate first) and its unencrypted PEM key to the instance. Then run:
sudo rmqtt-install-cert <certificate-chain.pem> <private-key.pem> <dns-name>Port 8883 then serves your certificate, and clients trust your CA instead of pinning this instance. The boot-time renewal never replaces an installed certificate. To go back to a new self-signed certificate, run sudo rmqtt-set-hostname <name>.
Both commands restart the broker when it is running. They also restart it when it has failed, for example after the configuration check refused a start, clearing the failed state first. A broker that you stopped with sudo systemctl stop rmqtt stays stopped. Start it with sudo systemctl start rmqtt when you are ready.
Logs, files and limits
- Logs. The broker log is
journalctl -u rmqtt, which records connections, TLS errors and refusals, and never a password. The login log isjournalctl -u rmqtt-authd, with one line per refused login, such asrmqtt-authd: login refused user=sac-app client=<client id> from=127.0.0.1. First boot logs tojournalctl -u rmqtt-firstboot. - Files. Configuration is in
/etc/rmqtt/rmqtt.tomland/etc/rmqtt/plugins/*.toml(root:rmqtt 0640). The gate checks them on every start, and changes take effect onsudo systemctl restart rmqtt. Logins are in/etc/rmqtt-auth/sac-users.json, which holds hashes only and cannot be read by the broker. The certificate and key are in/etc/rmqtt/tls/. - Retained messages and sessions. Retained messages (at most 5,000, each up to 64 KB) and client sessions are kept in memory. They do not survive a broker restart or a reboot. Applications that need durable messages should republish their retained state when they reconnect.
- Sandboxing. The broker runs as the unprivileged
rmqttuser in a systemd sandbox (no capabilities, a read-only system, a system-call filter, core dumps off). The login service runs asrmqtt-authwith only the right to bind its port. - Restarts. If
rmqttdcrashes, systemd starts it again after 10 seconds. A start that the configuration check or the listener guard refuses is not retried. Fix the cause, whichjournalctl -u rmqttnames, then runsudo systemctl reset-failed rmqttandsudo systemctl start rmqtt. - Clustering. This image runs a single RMQTT node. Clustering is not configured.
Support
SecureAnyCloud supports the image, including launch problems, the first-boot setup, the TLS configuration and the SecureAnyCloud helpers. Contact sales@secureanycloud.com. RMQTT itself is documented at github.com/rmqtt/rmqtt.
Deploy on AWS
Launch RMQTT 0.24.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com