Securing MQTT and IoT messaging: TLS, authentication and topic access control
In short: MQTT has no security by default, so a broker on port 1883 with anonymous access lets anyone read and write every topic. Secure it with TLS on port 8883, authenticate every client, restrict each one to its own topics with access control lists, and keep the broker off the public internet where possible.
Why MQTT needs extra care
MQTT (Message Queuing Telemetry Transport) is a lightweight publish-subscribe protocol used by a huge number of IoT systems. Its simplicity is its strength, but the protocol leaves security to the transport and the broker. Internet scans regularly find brokers that accept anonymous connections, where anyone can subscribe to # (every topic) and read sensor data, or publish fake commands to actuators.
Encrypt with TLS
Run MQTT over TLS on port 8883 and close plain port 1883, or bind it to localhost for local tools. Use TLS 1.2 or 1.3, a certificate from your own CA or a public CA, and make clients verify the broker's certificate and hostname. A client that skips verification can be fooled by any attacker in the middle.
Authenticate every client
Two common methods:
- Client certificates (mutual TLS): strongest, because each device has its own key pair, ideally in secure hardware. The broker can use the certificate's common name as the username.
- Username and password: simpler, but use a unique password per device, store only hashes on the broker, and always run it inside TLS.
MQTT 5 also supports enhanced authentication, allowing challenge-response or token-based methods where both sides support them.
Authorise topics with ACLs
Authentication says who the client is; an ACL (access control list) says what it may do. A good topic design makes ACLs easy: put the device ID in the topic, such as site1/sensors/<device-id>/temp. Each sensor can then write only to its own branch, and only the dashboard can read everything. Here is a Mosquitto example:
# /etc/mosquitto/conf.d/secure.conf
per_listener_settings false
allow_anonymous false
listener 8883
cafile /etc/mosquitto/certs/ca.crt
certfile /etc/mosquitto/certs/broker.crt
keyfile /etc/mosquitto/certs/broker.key
tls_version tlsv1.2
require_certificate true
use_identity_as_username true
acl_file /etc/mosquitto/acl
# /etc/mosquitto/acl
# each device writes only to its own branch (%u = username from the certificate)
pattern write site1/sensors/%u/#
pattern read site1/commands/%u/#
user dashboard
topic read site1/sensors/#
On the client side, a Python program using the paho-mqtt library (version 2) verifies the broker and presents its own certificate:
import paho.mqtt.client as mqtt
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="sensor-0042")
client.tls_set(ca_certs="ca.crt", certfile="sensor-0042.crt", keyfile="sensor-0042.key")
client.connect("broker.example.com", 8883)
client.publish("site1/sensors/sensor-0042/temp", "21.4", qos=1)
client.disconnect()
Hardening the broker
- Keep the broker on a private network or behind a firewall; expose it to the internet only if you must, and then only on 8883.
- Deny wildcard subscriptions such as
#for device accounts. - Set limits on message size, connections and queued messages to resist floods.
- Log connections, failed logins and ACL denials, and send logs to your SIEM.
- Validate payloads in the application: never trust a number just because it arrived on the right topic.
- Patch the broker and libraries, and review retained messages that might hold stale or sensitive data.
Tip: test your ACLs. Connect as one device and try to publish to another device's topic; the broker should refuse it and log the attempt.
Practice
Why is subscribing to # dangerous on an open broker?
What does use_identity_as_username do in Mosquitto?
A client connects to 8883 but disables certificate verification. What risk remains?
Key takeaways
- MQTT has no built-in security; the broker and transport must provide it.
- Use TLS on 8883 and make clients verify the broker certificate.
- Authenticate each client, ideally with its own certificate.
- Design topics around device IDs so ACLs can restrict each client.
- Keep brokers private, limit wildcards, log denials and patch.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.