Streaming & Messaging AWS

HiveMQ Community Edition MQTT Broker on AWS User Guide

| Product: HiveMQ Community Edition

Overview

HiveMQ Community Edition is an open source MQTT broker built for the messaging patterns that internet of things and machine to machine systems depend on. It implements MQTT 3.1, 3.1.1 and 5.0 in full, including quality of service levels, retained messages, last will and testament, persistent sessions and shared subscriptions.

Upstream HiveMQ CE ships with no authentication at all — an open broker that accepts anonymous clients. This image does not. It preinstalls the vendor's own File RBAC access control extension in hashed password mode, ships with no user file whatsoever, and wires the broker service so it cannot start until first boot has generated a unique credential for your instance.

This is a headless product. There is no web interface: the HiveMQ Control Center is an Enterprise edition feature. You administer it over SSH and its configuration files, and clients talk MQTT.

What is included:

  • HiveMQ Community Edition 2026.5 from the official GitHub release (Apache License 2.0), sha256 verified at build time
  • OpenJDK 21 headless runtime; the broker runs as the unprivileged hivemq system user under systemd
  • The MQTT listener on 0.0.0.0:1883
  • The official HiveMQ File RBAC Auth Extension 4.6.15, sha256 verified, configured password-type HASHED
  • hivemq-firstboot.service generating a 24 character password for the cimgadmin account, PBKDF2 hashing it with the extension's own generator, and writing /root/hivemq-credentials.txt (mode 0600 root:root)
  • mosquitto-clients so you can publish and subscribe from the instance itself
  • 24/7 cloudimg support

Prerequisites

An AWS account, an EC2 key pair, and a VPC subnet. The security group should allow inbound TCP 22 (SSH) and 1883 (MQTT) from your trusted CIDR. m5.large is a comfortable default: the broker is a JVM service sized for roughly one and a half gigabytes of heap.

Connecting to your instance

SSH in as the default login user for the operating system variant you launched. This listing currently ships one variant:

OS variant SSH login user
Ubuntu 24.04 LTS ubuntu
ssh ubuntu@<public-ip>

Step 1: Launch from AWS Marketplace

Subscribe to the cloudimg HiveMQ Community Edition listing and launch an instance. Pick m5.large, choose your VPC and subnet, and attach a security group allowing inbound TCP 22 and 1883 from your trusted CIDR.

Step 2: SSH In

ssh ubuntu@<public-ip>

Step 3: Service Status and Listener

Confirm the broker is running and the MQTT listener is bound.

sudo systemctl is-active hivemq
active
sudo ss -tlnp | grep 1883 | awk '{print $1, $4}'
LISTEN 0.0.0.0:1883

The broker running under systemd on a headless OpenJDK 21 runtime with the MQTT listener bound on port 1883

Step 4: Confirm the Access Control Extension

The extension is what makes this broker closed rather than open. Confirm it is installed and set to accept only hashed passwords.

ls /opt/hivemq/current/extensions/hivemq-file-rbac-extension/
LICENSE
conf
hivemq-extension.xml
hivemq-file-rbac-extension-4.6.15.jar
sudo cat /opt/hivemq/current/extensions/hivemq-file-rbac-extension/conf/config.xml

The installed broker directory and the file based access control extension with its configuration set to hashed password mode

Step 5: Read Per-Instance Credentials

First boot generated this instance's broker password. Read it now.

sudo cat /root/hivemq-credentials.txt

Pick up HIVEMQ_ADMIN_USER (cimgadmin) and HIVEMQ_ADMIN_PASSWORD. These are unique to this instance; only the PBKDF2 hash is stored on disk in the extension's user file.

Step 6: Publish and Subscribe

Read the password into a shell variable rather than typing it, so it never lands in your shell history. Then publish a retained message and read it back.

PW=$(sudo grep -m1 '^HIVEMQ_ADMIN_PASSWORD=' /root/hivemq-credentials.txt | cut -d= -f2-)
mosquitto_pub -h 127.0.0.1 -p 1883 -u cimgadmin -P "$PW" -t cloudimg/demo -m 'hello from cloudimg' -q 1 -r
mosquitto_sub -h 127.0.0.1 -p 1883 -u cimgadmin -P "$PW" -t cloudimg/demo -C 1 -W 8 -q 1
hello from cloudimg

The -r flag retained the message on the broker, so the subscriber receives it immediately on connect rather than waiting for the next publish.

An authenticated retained publish followed by a subscribe returning the same payload

Step 7: Confirm the Broker Is Closed By Default

This is the check worth doing yourself. Both an anonymous connection and a wrong password connection must be refused.

Each check is written as an assertion: it succeeds when the connection is refused, and fails loudly if the broker ever accepts it.

if mosquitto_pub -h 127.0.0.1 -p 1883 -t cloudimg/demo -m anon 2>/dev/null; then
  echo "UNEXPECTED: anonymous connect was ACCEPTED - the broker is open"; exit 1
else
  echo "anonymous connect refused (exit $?) - correct"
fi
anonymous connect refused (exit 4) - correct
if mosquitto_pub -h 127.0.0.1 -p 1883 -u cimgadmin -P wrong-pw -t cloudimg/demo -m bad 2>/dev/null; then
  echo "UNEXPECTED: wrong password was ACCEPTED"; exit 1
else
  echo "wrong password refused (exit $?) - correct"
fi
wrong password refused (exit 5) - correct

Run either command without the if wrapper and you will see the broker's own refusal on stderr, which is what those exit codes correspond to:

Connection error: Connection Refused: bad user name or password.   # anonymous, exit 4
Connection error: Connection Refused: not authorised.              # wrong password, exit 5

If either assertion ever reports UNEXPECTED, the access control extension is not loading — check journalctl -u hivemq.

An anonymous connection and a wrong password connection both refused by the broker

Step 8: Connect Your Own Clients

From outside the instance, point your MQTT clients at <public-ip>:1883 with username cimgadmin and the generated password. Any MQTT 3.1, 3.1.1 or 5.0 client works: mosquitto_pub/mosquitto_sub, Eclipse Paho in Python, Java or JavaScript, or the MQTT client built into most IoT SDKs.

Quality of service 1 and 2 are supported for at-least-once and exactly-once delivery, retained messages give new subscribers the current value immediately, and last will and testament lets you detect ungraceful client disconnects.

Step 9: Add More Users

The extension reads a user file that first boot created with a single account. Add more users by generating a hash with the extension's own generator and adding an entry, then reload.

sudo java -jar /opt/hivemq/current/extensions/hivemq-file-rbac-extension/hivemq-file-rbac-extension-4.6.15.jar -p '<password>' -q

Add the printed hash as a new <user> block in the extension's conf/credentials.xml. The extension re-reads that file on its own reload interval, so no restart is needed. Give each application its own account rather than sharing cimgadmin.

Step 10: Production Hardening Checklist

Before exposing the broker beyond a trusted network:

  1. Add a TLS listener. Port 1883 is plaintext: MQTT credentials are sent in the CONNECT packet, so on an untrusted network they are exposed. Add a tls-tcp-listener on 8883 in /opt/hivemq/current/conf/config.xml with your certificate and key, then close 1883 in the security group.
  2. Restrict the security group. Limit 22 and 1883 (or 8883) to your device and administrator CIDRs rather than the world.
  3. One account per application. Add per client users as in Step 9 and retire the shared cimgadmin account for production traffic.
  4. Watch the logs. journalctl -u hivemq and /opt/hivemq/current/log/ show connection, authentication and extension activity.
  5. Back up the configuration. /opt/hivemq/current/conf/ and the extension's conf/ hold the listener configuration and the user file; snapshot the volume or copy them on a schedule.
  6. Keep it patched. Unattended upgrades is enabled for OS packages; review the HiveMQ release notes before replacing the broker under /opt/hivemq.

Architecture

Component Path Notes
Broker hivemq.service Runs bin/run.sh as the unprivileged hivemq user, OpenJDK 21 headless
Install root /opt/hivemq/current Symlink to the pinned hivemq-ce-2026.5 distribution
Broker config /opt/hivemq/current/conf/config.xml Vendor MQTT sample: one tcp-listener on 0.0.0.0:1883
Access control extension /opt/hivemq/current/extensions/hivemq-file-rbac-extension/ Official File RBAC extension 4.6.15
Extension config .../conf/config.xml password-type HASHED; failed auth is refused, not passed through
User file .../conf/credentials.xml Written per instance at first boot; absent from the image
Customer creds /root/hivemq-credentials.txt Mode 0600 root:root; broker address, user, password
Firstboot script /usr/local/sbin/hivemq-firstboot.sh Generates and hashes the per instance password
Firstboot sentinel /var/lib/cloudimg/hivemq-firstboot.done Created when first boot completes

The broker unit carries ConditionPathExists on the user file, so if that file is ever missing the broker will not start rather than starting open.

Support

cloudimg provides 24/7 support for this image. Open a ticket at https://www.cloudimg.co.uk/support/ with your instance ID and a brief description of the issue. Common asks: adding a TLS listener, access control and per client users, topic design, client connectivity across MQTT versions, and sizing for connection counts.