MQTT brokers are surprisingly vulnerable to unauthorized access and data breaches if not properly secured.

Let’s see what a typical, insecure MQTT setup looks like, and then how we can lock it down. Imagine a simple scenario: a few sensors publishing temperature data to a central broker, and a dashboard subscribing to that data.

# mosquitto.conf (insecure example)
listener 1883
allow_anonymous true

With allow_anonymous true, anyone on the network can connect to your broker on port 1883 and either publish messages to any topic or subscribe to any topic. This is like leaving your front door wide open. A malicious actor could flood your topics with garbage data, overload your broker, or even intercept sensitive information if your "sensors" are publishing anything more than just temperature.

To harden this, we need to implement authentication and authorization.

1. Disallow Anonymous Access

The first step is to prevent unauthenticated clients from connecting.

  • Diagnosis: If you can connect to your broker using mosquitto_sub -h <broker_ip> -t "some/topic" without any username or password, it’s anonymously accessible.
  • Fix: In your mosquitto.conf file, set allow_anonymous false.
  • Why it works: This forces every client to provide credentials before the broker even considers their connection request.
# mosquitto.conf (after disallowing anonymous)
listener 1883
allow_anonymous false

2. Implement Username/Password Authentication

Now that anonymous access is off, clients must authenticate.

  • Diagnosis: Attempting to connect with mosquitto_pub -h <broker_ip> -t "some/topic" -m "hello" will now fail with a "not authorized" or similar error if no credentials are provided.
  • Fix: Create a password file (e.g., pwfile.txt) and point your broker to it. Use mosquitto_passwd to add users. For example, to add a user device1 with a password supersecretpassword:
    mosquitto_passwd -c pwfile.txt device1
    # Enter password when prompted, then again to confirm.
    
    Then, in mosquitto.conf:
    password_file /etc/mosquitto/pwfile.txt
    
    Clients will now connect like this:
    mosquitto_pub -h <broker_ip> -t "some/topic" -m "hello" -u "device1" -P "supersecretpassword"
    
  • Why it works: The broker reads the password_file, hashes the provided password, and compares it to the stored hash. A match grants access.

3. Enforce Access Control Lists (ACLs)

Just because a client can authenticate doesn’t mean they should have free rein. ACLs define what topics a user can publish to or subscribe from.

  • Diagnosis: A user authenticated with correct credentials can still publish to or subscribe from any topic if no ACLs are defined.
  • Fix: Create an ACL file (e.g., aclfile.txt) and configure the broker to use it.
    # aclfile.txt example
    # User device1 can publish to sensors/temperature/livingroom
    # and subscribe to sensors/temperature/#
    user device1
    topic write sensors/temperature/livingroom
    topic read sensors/temperature/#
    
    # User dashboard can only subscribe to all sensor data
    user dashboard
    topic read sensors/#
    
    In mosquitto.conf:
    acl_file /etc/mosquitto/aclfile.txt
    
  • Why it works: The broker checks the acl_file for rules matching the authenticated user and the requested topic/action (read/write) before allowing the operation.

4. Use TLS/SSL for Encrypted Communication

Password-based authentication is only as secure as the network it traverses. An attacker on the same network could sniff credentials without TLS.

  • Diagnosis: Network traffic to and from the broker can be inspected with tools like Wireshark, revealing plaintext credentials and message payloads.
  • Fix: Enable TLS on your broker. This involves generating or obtaining SSL certificates and configuring Mosquitto to use them.
    • Generate self-signed certificates (for testing/internal use):
      # Generate a private key
      openssl genrsa -out ca.key 2048
      # Generate a Certificate Signing Request (CSR)
      openssl req -new -key ca.key -out ca.csr
      # Generate a self-signed certificate
      openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt
      
      You’ll need to create certificates for the broker and potentially for clients. For simplicity, let’s assume you have server.crt and server.key for the broker.
    • Configure mosquitto.conf:
      # TLS settings
      listener 8883
      protocol mqtt
      tls_version tlsv1.2
      certfile /etc/mosquitto/certs/server.crt
      keyfile /etc/mosquitto/certs/server.key
      # Optional: If using client certificates for mutual TLS
      # cafile /etc/mosquitto/certs/ca.crt
      # certfile /etc/mosquitto/certs/client.crt
      # keyfile /etc/mosquitto/certs/client.key
      
    • Clients connect using mosquitto_pub -h <broker_ip> --cafile /path/to/ca.crt -t "test" -m "hello" (or specifying client certs/keys if mutual TLS is used).
  • Why it works: TLS encrypts the entire communication channel between client and broker, making credentials and message payloads unreadable to eavesdroppers.

5. Restrict Client IDs

Each MQTT client has a unique Client ID. Allowing clients to choose arbitrary IDs can lead to spoofing or denial-of-service attacks where a malicious client impersonates a legitimate one, potentially disrupting message delivery or causing confusion.

  • Diagnosis: Clients can connect with any Client ID, even those reserved for system use or identical to other clients’ IDs (though MQTT spec handles duplicate IDs by disconnecting one).
  • Fix: Use the clientid_prefix option in mosquitto.conf to enforce a naming convention for client IDs.
    # mosquitto.conf
    # ... other settings ...
    clientid_prefix sensor_
    
    Now, any client attempting to connect with a Client ID that doesn’t start with sensor_ will be rejected.
  • Why it works: This acts as a simple form of client identity validation, ensuring that only clients adhering to the expected naming scheme can connect.

6. Limit Connection Rates and Payload Sizes

A denial-of-service attack can involve a single client bombarding the broker with a high volume of connections, subscriptions, or very large messages.

  • Diagnosis: A single IP address or client can overwhelm the broker by opening many connections or sending excessively large messages.
  • Fix: Configure rate limiting and maximum payload size.
    # mosquitto.conf
    # Limit to 100 connections per IP address per minute
    max_connections_per_IP 100
    # Limit message payload to 256KB
    max_payload_size 262144
    
  • Why it works: These limits prevent a single, misbehaving client from consuming excessive resources and impacting the availability of the broker for legitimate clients.

After implementing these measures, attempting to connect anonymously or with incorrect credentials will result in connection refused or authentication failure errors. A legitimate, configured client will be able to connect, authenticate, and publish/subscribe according to its ACLs over a secure TLS channel.

The next common issue you’ll likely encounter is managing certificate revocation if a client’s key is compromised.

Want structured learning?

Take the full Mqtt course →