Eclipse Mosquitto MQTT Broker on AWS User Guide
Overview
This image runs Eclipse Mosquitto, the open source MQTT broker, fully installed and configured from the official Mosquitto PPA. Mosquitto runs as a single node broker with password authentication switched on. Anonymous MQTT connections are rejected from the moment the broker starts, and the mosquitto_pub and mosquitto_sub command line tools from the mosquitto-clients package are installed for publishing and subscribing from the instance itself or remote machines.
On the first boot of every deployed instance, a one shot service generates a fresh, strong password for the cloudimg MQTT user, unique to that instance, applies it to the broker with mosquitto_passwd, and writes it to /root/mosquitto-credentials.txt (mode 0600, root only). No shared or default MQTT credentials ship in the image.
Because Mosquitto is a TCP only protocol broker, the image also runs an nginx healthcheck shim on port 80 that returns a static OK response. This gives the AWS Marketplace scanner and your own load balancer an HTTP endpoint to probe, while MQTT itself remains on port 1883.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and inbound port 1883 from any clients that will publish or subscribe
- The AWS CLI version 2 installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Eclipse Mosquitto. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger as a balanced default; size the instance to the publish and subscribe load you intend to run. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and inbound port 1883 from any clients that will connect to the broker. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes only a few seconds after the instance state becomes Running and the status checks pass: the firstboot service generates the per instance MQTT password and starts the broker.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Eclipse Mosquitto Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network and port 1883 from your client networks.
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> \
--block-device-mappings '{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}' \
--metadata-options 'HttpTokens=required,HttpEndpoint=enabled' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=mosquitto-broker}]'
Step 3: Connect to the Instance over SSH
Connect to the instance with SSH as the default login user for the operating system variant you launched. The login user differs by variant:
| Operating system variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
Replace <key-file> with the path to your private key file and <instance-public-ip> with the public IP address or DNS name of the instance.
ssh -i <key-file> ubuntu@<instance-public-ip>
Step 4: Retrieve the Per Instance MQTT Password
The first boot service writes the generated MQTT password to /root/mosquitto-credentials.txt. The file is mode 0600 and owned by root, so you read it with sudo. The file also documents the MQTT user name and port for reference.
sudo cat /root/mosquitto-credentials.txt
The MOSQUITTO_PASSWORD line carries the password generated for this instance. Keep it safe: it is the only credential that can connect to the broker by default.
Step 5: Confirm the Broker
Check that the broker and the healthcheck shim are running and that the MQTT listener is bound:
systemctl is-active mosquitto.service nginx.service
ss -tln | grep -E ':(1883|80) '
Confirm the installed version of Mosquitto:
dpkg-query -W -f='${Package} ${Version}\n' mosquitto
The HTTP healthcheck shim serves a static OK on port 80. The Marketplace scanner uses this endpoint; you can verify it manually:
curl -fsS http://127.0.0.1/
Step 6: Publish and Subscribe Locally
The mosquitto-clients package provides mosquitto_sub for subscribing and mosquitto_pub for publishing. Read the password into a shell variable, then run a subscriber in one terminal and a publisher in another to confirm the broker is delivering messages.
Subscribe to a topic (this command blocks, waiting for messages):
PASS=$(sudo grep '^MOSQUITTO_PASSWORD=' /root/mosquitto-credentials.txt | cut -d= -f2-)
mosquitto_sub -h 127.0.0.1 -u cloudimg -P "$PASS" -t 'hello/#' -v
In a second SSH session on the same instance, retrieve the password the same way and publish a message:
PASS=$(sudo grep '^MOSQUITTO_PASSWORD=' /root/mosquitto-credentials.txt | cut -d= -f2-)
mosquitto_pub -h 127.0.0.1 -u cloudimg -P "$PASS" -t hello/world -m 'first message from mosquitto'
The subscriber prints hello/world first message from mosquitto. The # wildcard subscribes to every topic under hello/, so any other hello/... topic is delivered too.
If you do not have a subscriber attached when the publisher runs, the message is dropped on delivery (MQTT QoS 0). To retain a message for new subscribers, add -r to the publish command — Mosquitto stores the last retained message on the topic and delivers it immediately to every subsequent subscriber.
To stop the subscriber, press Ctrl+C.
Step 7: Publish and Subscribe from a Remote Client
The MQTT listener binds 0.0.0.0:1883, so any host that can reach the instance on port 1883 can connect with the same credentials. Install the mosquitto-clients package on the remote host (for example sudo apt-get install -y mosquitto-clients on Ubuntu) and use the instance's public IP address or DNS name.
mosquitto_sub -h <instance-public-ip> -u cloudimg -P '<password>' -t 'hello/#' -v
mosquitto_pub -h <instance-public-ip> -u cloudimg -P '<password>' -t hello/world -m 'message from a remote client'
Make sure your security group permits inbound TCP 1883 from the source network. For production deployments, restrict 1883 to known client networks or front the broker with TLS on port 8883 (see Step 9).
Step 8: Manage MQTT Users
The image ships with one MQTT user, cloudimg. To add another MQTT user, run mosquitto_passwd against the broker's password file and reload the service so the change is picked up:
sudo mosquitto_passwd /etc/mosquitto/passwd <new-username>
sudo systemctl reload mosquitto.service
mosquitto_passwd prompts twice for the new user's password and appends it to the file. To delete a user, edit /etc/mosquitto/passwd as root and remove the line for that user, then reload the service.
Step 9: Add a TLS Listener on Port 8883
Plain MQTT on 1883 is the default. For Internet exposed deployments, add a TLS listener on the standard MQTTS port 8883. Place a certificate and private key on the instance (for example under /etc/mosquitto/certs/), then create a new drop in configuration file and reload the broker.
sudo install -d -o root -g mosquitto -m 0750 /etc/mosquitto/certs
# Copy your certificate, private key and CA bundle into /etc/mosquitto/certs/
# fullchain.pem (certificate + intermediates)
# privkey.pem (private key, mode 0640 root:mosquitto)
# ca.pem (your CA chain, optional for client cert auth)
sudo tee /etc/mosquitto/conf.d/tls.conf >/dev/null <<'CONF'
listener 8883 0.0.0.0
certfile /etc/mosquitto/certs/fullchain.pem
keyfile /etc/mosquitto/certs/privkey.pem
# Uncomment to require client certificates:
# cafile /etc/mosquitto/certs/ca.pem
# require_certificate true
CONF
sudo systemctl reload mosquitto.service
Open inbound TCP 8883 on the security group from your client networks, and connect with the mqtts:// or --cafile form of your MQTT client.
Step 10: Persistence and Broker Tuning
Mosquitto persists retained messages, queued messages for offline subscribers, and subscription state under /var/lib/mosquitto/. The default /etc/mosquitto/mosquitto.conf sets persistence true and persistence_location /var/lib/mosquitto/; the cloudimg overlay in /etc/mosquitto/conf.d/cloudimg.conf does not change those values.
For high message rate workloads, review and tune the broker on a per deployment basis. The full list of broker options is documented at https://mosquitto.org/man/mosquitto-conf-5.html. Place additional configuration in a new file under /etc/mosquitto/conf.d/, then reload the broker.
sudo systemctl reload mosquitto.service
Step 11: Maintenance
Keep the operating system patched with the standard package manager. The official Mosquitto PPA is already configured on the image, so broker upgrades are delivered through the normal package update process:
sudo apt-get update
sudo apt-get -y upgrade
Restart the broker after a Mosquitto package upgrade if the package post installation does not do so automatically:
sudo systemctl restart mosquitto.service
Inspect broker logs with journalctl while diagnosing connection or routing issues:
sudo journalctl -u mosquitto.service -n 200 --no-pager
Screenshots



Support
This Amazon Machine Image is provided by cloudimg with 24/7 technical support by email and chat. Contact cloudimg for help with MQTT broker deployment, authentication and access control, TLS configuration, bridging multiple brokers and broker tuning.
Eclipse Mosquitto is a trademark of the Eclipse Foundation. All other product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.