Setting Up MQTT Broker with RabbitMQ on Raspberry Pi
With the increasing demand for IoT applications, centralizing data from various sources like PLC modules is critical for effective monitoring and control. RabbitMQ, a robust message broker supporting the MQTT protocol, is an excellent choice for this purpose. In this guide, we will set up RabbitMQ with MQTT support on a Raspberry Pi running a Debian-based system.
Prerequisites
Before starting, ensure you have:
- A Raspberry Pi with a Debian-based OS installed (e.g., Raspberry Pi OS).
- Internet connectivity.
- Basic knowledge of terminal commands.
Installing RabbitMQTT on Debian
always do an update and upgrade of the system
# sync package metadata
sudo apt-get update
# install dependencies manually
sudo apt-get -y install logrotate init-system-helpers adduser
# download the package
sudo apt-get -y install wget
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v4.0.5/rabbitmq-server_4.0.5-1_all.deb
# install the package with dpkg
sudo dpkg -i rabbitmq-server_4.0.5-1_all.deb
rm rabbitmq-server_4.0.5-1_all.deb
Securing debian and RabbitMQTT
RabbitMQ Debian package will require sudo
privileges to install and manage. In environments where sudo
isn’t available, consider using the generic binary build instead.
Default User Access
The broker creates a user guest
with password guest
. Unconfigured clients will in general use these credentials. By default, these credentials can only be used when connecting to the broker as localhost so you will need to take action before connecting from any other machine.
See the documentation on access control for information on how to create more users and delete the guest
user.
(more on this topic at the end of the page)
Run and Getting the data from RabbitMQTT
systemctl start rabbitmq-server
sudo journalctl --system | grep rabbitmq
Check the output of the installed and running RabbitMQ, this is the output you should get
ug 26 11:03:04 localhost rabbitmq-server[968]: ## ##
Aug 26 11:03:04 localhost rabbitmq-server[968]: ## ## RabbitMQ 4.0.5. Copyright (c) 2005-2025 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
Aug 26 11:03:04 localhost rabbitmq-server[968]: ########## Licensed under the MPL 2.0. Website: https://www.rabbitmq.com/
Aug 26 11:03:04 localhost rabbitmq-server[968]: ###### ##
Aug 26 11:03:04 localhost rabbitmq-server[968]: ########## Logs: /var/log/rabbitmq/rabbit@localhost.log
Aug 26 11:03:04 localhost rabbitmq-server[968]: /var/log/rabbitmq/rabbit@localhost_upgrade.log
Aug 26 11:03:04 localhost rabbitmq-server[968]: Starting broker...
Aug 26 11:03:05 localhost rabbitmq-server[968]: systemd unit for activation check: "rabbitmq-server.service"
Aug 26 11:03:06 localhost rabbitmq-server[968]: completed with 6 plugins.
Autostart RabbitMQ service
I called mine rabbitmq-server.service
create a service file in /etc/systemd/system/rabbitmq-server.service
[Unit]
Description=RabbitMQ Messaging Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/rabbitmq-server -detached
ExecStop=/usr/sbin/rabbitmqctl stop
Restart=on-failure
User=rabbitmq
Group=rabbitmq
[Install]
WantedBy=multi-user.target
Key Sections:
ExecStart
: Specifies the command to start RabbitMQ.ExecStop
: Specifies the command to stop RabbitMQ gracefully.User
andGroup
: Ensures the service runs as therabbitmq
user and group.Restart
: Restarts the service on failure.
reload the systemd Daemon
sudo systemctl daemon-reload
Enable the Service
Enable RabbitMQ to start at boot:
sudo systemctl enable rabbitmq-server
Reboot the system and check if the service runs automatically
sudo systemctl status rabbitmq-server
Python example (can be better programmed then what i show here)
import requests
import json
# RabbitMQ HTTP API credentials and settings
RABBITMQ_API_URL = "http://localhost:15672/api/queues/%2F/your_queue_name/get"
RABBITMQ_USER = "guest"
RABBITMQ_PASSWORD = "guest"
# Payload for the HTTP API request
payload = {
"count": 1, # Number of messages to fetch
"ackmode": "ack_requeue_false", # Acknowledge and don't requeue
"encoding": "auto", # Message body encoding
}
def fetch_messages():
"""Fetch messages from RabbitMQ via HTTP API."""
try:
response = requests.post(
RABBITMQ_API_URL,
auth=(RABBITMQ_USER, RABBITMQ_PASSWORD),
headers={"Content-Type": "application/json"},
data=json.dumps(payload),
)
if response.status_code == 200:
messages = response.json()
for message in messages:
print(f" [x] Received message: {message['payload']}")
else:
print(f" [!] Failed to fetch messages: {response.status_code} {response.text}")
except Exception as e:
print(f" [!] Error: {e}")
if __name__ == "__main__":
print(" [*] Fetching messages. To stop, press CTRL+C")
try:
while True:
fetch_messages()
except KeyboardInterrupt:
print("\n [!] Exiting...")
Explanation
- Management Plugin: This example uses RabbitMQ’s Management Plugin to fetch messages from a specific queue via the HTTP API.
- Queue Name: Replace
your_queue_name
in theRABBITMQ_API_URL
with the name of the queue you want to fetch messages from. - Payload:
count
: Number of messages to fetch per request.ackmode
: Determines how to acknowledge messages (ack_requeue_false
acknowledges without requiring).encoding
: Specifies message encoding.
Considerations
- This approach is polling-based, meaning it periodically fetches messages rather than receiving them in real-time.
- It is not as efficient as using a library like
pika
orkombu
for AMQP protocol communication.
security
1. Use Authentication
- Require clients to authenticate with the broker.
- Options:
- Username and Password: Set up username/password credentials for clients.
- Client Certificates: Use mutual TLS (mTLS) to verify both the client and the broker using certificates.
- Implementation:
- For Mosquitto (an MQTT broker), configure the
password_file
option. - Use tools like
mosquitto_passwd
to manage credentials:bashCode kopiërenmosquitto_passwd -c /etc/mosquitto/passwdfile username
- For Mosquitto (an MQTT broker), configure the
2. Encrypt Communication
- Use TLS/SSL:
- Encrypt all communication between clients and the broker to prevent eavesdropping and tampering.
- Steps:
- Generate or obtain an SSL/TLS certificate (use Let’s Encrypt or generate self-signed certificates for internal use).
- Configure the MQTT broker to use the certificate and private key.
- Example (Mosquitto
mosquitto.conf
):confCode kopiërenlistener 8883 cafile /path/to/ca.crt certfile /path/to/server.crt keyfile /path/to/server.key require_certificate true
- Example (Mosquitto
- Use MQTT over TLS (
mqtts
) on port 8883.
3. Enable Access Control
- Use Access Control Lists (ACLs) to limit what resources each client can access.
- Example (Mosquitto
acl_file
):bashCode kopiërenuser client1 topic read /sensor/temperature topic write /actuator/command
- Configure the broker to use the ACL file:confCode kopiëren
acl_file /etc/mosquitto/aclfile
4. Limit Open Ports and Bind to Specific Interfaces
- Disable unnecessary listeners:
- For example, disable the default unsecured port (
1883
) if only secure connections are needed.
- For example, disable the default unsecured port (
- Bind the broker to specific network interfaces to limit exposure, conf file Code
listener: 1883 127.0.0.1
5. Implement Rate Limiting
- Prevent denial-of-service (DoS) attacks by limiting the number of connections or messages per client.
- Example (Mosquitto):confCode kopiëren
connection_messages 10 max_connections 100
6. Monitor and Log Activity
- Enable logging to monitor broker activity and detect suspicious behavior.
- Example (Mosquitto):confCode kopiëren
log_type all log_dest file /var/log/mosquitto/mosquitto.log
7. Keep Software Updated
Regularly update the MQTT broker software to ensure you have the latest security patches.
8. Firewall Configuration
- Use a firewall to restrict access to the broker’s ports (e.g., 1883, 8883).
- Only allow trusted IP’s or subnets to connect.
9. Use QoS Appropriately
- Configure the Quality of Service (QoS) level based on the application’s reliability requirements:
- QoS 0: At most once.
- QoS 1: At least once.
- QoS 2: Exactly once (ensures highest reliability).
10. Disable Anonymous Connections
- Prevent unauthenticated clients from connecting to the broker.
- Example (Mosquitto):confCode kopiëren
allow_anonymous false
11. Regularly Review Security Settings
- Periodically audit configurations and logs to ensure compliance with security policies.
- Rotate credentials and certificates regularly.
12. Consider Using a Reverse Proxy
- Use a reverse proxy like NGINX to add an extra layer of security and handle TLS termination.
13. Implement a Security Policy
- Define and enforce a security policy for MQTT usage:
- Password complexity requirements.
- Certificate expiration policies.
- Regular vulnerability assessments.