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 and Group: Ensures the service runs as the rabbitmq 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

  1. Management Plugin: This example uses RabbitMQ’s Management Plugin to fetch messages from a specific queue via the HTTP API.
  2. Queue Name: Replace your_queue_name in the RABBITMQ_API_URL with the name of the queue you want to fetch messages from.
  3. 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 or kombu 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

2. Encrypt Communication

  • Use TLS/SSL:
    • Encrypt all communication between clients and the broker to prevent eavesdropping and tampering.
  • Steps:
    1. Generate or obtain an SSL/TLS certificate (use Let’s Encrypt or generate self-signed certificates for internal use).
    2. 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
  • 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ërenacl_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.
  • 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ërenconnection_messages 10 max_connections 100

6. Monitor and Log Activity

  • Enable logging to monitor broker activity and detect suspicious behavior.
  • Example (Mosquitto):confCode kopiërenlog_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ërenallow_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.

Resources:

Scroll to Top