MQTT security requires three layers: TLS encryption (port 8883) to prevent eavesdropping, authentication (username/password or client certificates) to verify device identity, and Access Control Lists (ACLs) to restrict which topics each client can publish or subscribe to. Never deploy MQTT on unencrypted port 1883 in production – without TLS, credentials and sensor data travel in plaintext, making the entire IoT system vulnerable to interception and unauthorized control.
Key Concepts
MQTT: Message Queuing Telemetry Transport — pub/sub protocol optimized for constrained IoT devices over unreliable networks
Broker: Central server routing messages from publishers to all matching subscribers by topic pattern
Topic: Hierarchical string (e.g., home/bedroom/temperature) used to route messages to interested subscribers
QoS Level: Quality of Service 0/1/2 trading delivery guarantee for message overhead
Retained Message: Last message on a topic stored by broker for immediate delivery to new subscribers
Last Will and Testament: Pre-configured message published by broker when a client disconnects ungracefully
Persistent Session: Broker stores subscriptions and pending messages allowing clients to resume after disconnection
26.1 Introduction
Securing MQTT communications is essential for production IoT deployments. This chapter covers Transport Layer Security (TLS), authentication mechanisms, and Access Control Lists (ACLs) for robust MQTT security.
For Beginners: What is MQTT Security?
Simple Explanation: Imagine sending a postcard through the mail - anyone who handles it can read your message. That’s how unprotected MQTT works! MQTT security is like putting your message in a locked box that only the recipient can open.
Three Protections You Need:
Encryption (TLS): Scrambles your message so eavesdroppers see gibberish
Authentication: Proves you are who you say you are (like showing ID)
Authorization (ACLs): Controls what each user can access (like VIP areas)
Real-World Analogy: Think of a secure office building: - TLS = The building’s walls and locked doors (keeps outsiders out) - Authentication = Your employee badge (proves your identity) - ACLs = Your badge only opens certain floors (limits access)
Key Ports to Remember:
Port 1883 = Insecure (like an unlocked door - development only!)
Port 8883 = Secure with TLS (production use)
26.2 Learning Objectives
By the end of this chapter, you will be able to:
Implement TLS Encryption: Configure secure MQTT connections on port 8883 using self-signed or CA-issued certificates
Configure Authentication: Set up username/password and certificate-based authentication on a Mosquitto broker
Design Access Control: Create topic-level ACL policies for multi-tenant systems following the principle of least privilege
Diagnose Common Security Mistakes: Identify and remediate production security pitfalls such as plaintext credentials and overly broad ACLs
Compare Authentication Methods: Evaluate username/password versus client certificate authentication and select the appropriate approach for a given deployment scale
Assess Security Posture: Evaluate an MQTT deployment against the three-layer defense model and justify configuration choices
Minimum Viable Understanding: MQTT Security
Core Concept: MQTT security requires three layers working together: transport encryption (TLS on port 8883), authentication (username/password or certificates), and authorization (topic-level ACLs). Missing any layer leaves your IoT system vulnerable.
Why It Matters: An unprotected MQTT broker on port 1883 exposes all device communications in plaintext - attackers can read sensor data, inject malicious commands, and impersonate devices. A 2023 study found over 8,000 exposed MQTT brokers on the internet with no authentication.
Key Insight: Always use TLS (port 8883) + authentication + ACLs together. Like a bank vault needs a locked door (TLS), ID check (authentication), AND restricted access to specific boxes (ACLs) - one layer alone isn’t enough.
Critical Security Warning
NEVER use public MQTT brokers (test.mosquitto.org) for production systems! These are unencrypted, unauthenticated, and anyone can subscribe to your topics. Always use: - TLS encryption (port 8883) - Username/password OR client certificates - Topic-level ACLs - A private broker (self-hosted or managed cloud service)
For Kids: Meet the Sensor Squad! - The Secret Message Club
Sammy the Temperature Sensor says: “MQTT security is like having a super-secret club with special rules!”
26.2.1 The Sensor Squad Adventure: Protecting the Clubhouse
The Sensor Squad wanted to share secret messages about the weather, but they discovered that anyone could listen in! “This won’t do,” said Bella the Button. “We need three special protections!”
Protection 1: The Secret Language (TLS Encryption) “First,” said Lila the Light Sensor, “let’s speak in a secret code! Even if someone overhears us, they won’t understand what we’re saying.” This is like TLS - it scrambles messages so only the right receiver can unscramble them.
Protection 2: The Password (Authentication) “Second,” said Max the Motion Detector, “everyone needs a secret password to join our club!” Just like how your favorite app needs a password, MQTT devices need usernames and passwords too.
Protection 3: The Room Rules (ACLs) “Third,” said Sammy, “different members can only go into certain rooms! I can talk about temperature, but I can’t sneak into the motion detector room.” These are ACL rules - they decide who can send and receive which messages.
26.2.2 Key Words for Kids
Word
What It Means
TLS
A secret code language that scrambles messages so bad guys can’t read them
Authentication
Proving who you are with a password, like showing your library card
ACL
Access Control List - rules about who can go where and do what
Port 8883
The special secure door for MQTT messages (like a VIP entrance!)
26.2.3 Fun Fact
Did you know that MQTT was invented to help oil pipelines talk to each other in the desert? Even back then, they knew security was important!
26.3 Security Layers
MQTT security consists of three layers that work together to protect your IoT communications. Think of these as concentric walls of defense - an attacker must breach all three to compromise your system.
MQTT Security Layers: Defense in Depth Architecture
Figure 26.1: MQTT Security Layers: Defense in Depth Architecture
Layer
Purpose
Implementation
Transport
Encrypt data in transit
TLS/SSL on port 8883
Authentication
Verify client identity
Username/password, certificates
Authorization
Control topic access
Access Control Lists (ACLs)
The following diagram shows what happens when security layers are missing:
Attack Vectors When Security Layers Are Missing
Figure 26.2: Attack Vectors When Security Layers Are Missing
Quick Check: Security Layers
26.4 TLS Encryption
TLS vs SSL
TLS (Transport Layer Security) is the successor to SSL. Modern MQTT implementations use TLS 1.2 or 1.3. Always use TLS, not the deprecated SSL.
Standard Ports:
1883: Unencrypted MQTT (development only!)
8883: Encrypted MQTT over TLS (production)
443: MQTT over WebSocket with TLS (browser-based clients)
Putting Numbers to It: TLS Encryption Overhead
How much does TLS encryption actually cost in terms of packet size and processing? Let’s quantify the overhead of securing MQTT communications.
Overhead ratio: \(\frac{37}{17} \times 100\% = 217\%\) overhead for this small payload.
CPU impact: TLS 1.3 with AES-128-GCM on ESP32 (240 MHz): - Handshake: ~150-200 ms once per connection - Per-message encryption: ~0.5 ms for 17-byte payload - Energy cost: ~2 mAh for 1000 encrypted messages vs ~1.8 mAh unencrypted (~11% increase)
Key insight: TLS overhead is significant for tiny payloads but essential for production. The security benefit vastly outweighs the modest energy increase.
conn_is_secure = conn_port ===8883|| conn_port ===443conn_tls_active = conn_tls_version !=="None"conn_has_auth = conn_auth_type !=="None"conn_issues = {const issues = [];if (conn_port ===1883&&!conn_tls_active) issues.push("Port 1883 without TLS exposes all traffic in plaintext");if (conn_port ===8883&&!conn_tls_active) issues.push("Port 8883 expects TLS -- connection will fail without it");if (!conn_has_auth) issues.push("No authentication allows anyone to connect to the broker");if (conn_tls_version ==="None"&& conn_has_auth) issues.push("Credentials sent in plaintext without TLS -- easily captured");if (conn_auth_type ==="Username/Password"&& conn_tls_active) issues.push("Consider client certificates for stronger device identity");if (conn_keepalive >120) issues.push("Long keep-alive may cause stale connections on unreliable networks");return issues;}conn_code_tls = conn_tls_active ?`client.tls_set(\n ca_certs="/path/to/ca.crt",${conn_auth_type ==="Client Certificate"?'\n certfile="/path/to/client.crt",\n keyfile="/path/to/client.key",':""}\n tls_version=ssl.PROTOCOL_TLS_CLIENT\n)`:"# WARNING: No TLS configured!"conn_code_auth = conn_auth_type ==="Username/Password"?`client.username_pw_set("iotuser", os.environ.get("MQTT_PASSWORD"))`: conn_auth_type ==="Client Certificate"?"# Authentication via client certificate (configured in tls_set)":"# WARNING: No authentication configured!"conn_security_score = (conn_tls_active ?40:0) + (conn_has_auth ?30:0) + (conn_is_secure ?20:0) + (conn_auth_type ==="Client Certificate"?10:0)conn_score_color = conn_security_score >=80?"#16A085": conn_security_score >=50?"#E67E22":"#E74C3C"html`<div style="padding: 15px; background: #f8f9fa; border-left: 4px solid ${conn_score_color}; margin: 10px 0; font-family: Arial, sans-serif;"> <h4 style="margin-top: 0; color: #2C3E50;">Generated Connection Code</h4> <pre style="background: #2C3E50; color: #ecf0f1; padding: 12px; border-radius: 4px; font-size: 0.85em; overflow-x: auto;">import paho.mqtt.client as mqttimport ssl, osclient = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)${conn_code_auth}${conn_code_tls}client.connect("${conn_host}", ${conn_port}, ${conn_keepalive})</pre> <div style="margin-top: 10px; padding: 8px; background: ${conn_security_score >=80?'#e8f5e9': conn_security_score >=50?'#fff3e0':'#ffebee'}; border-radius: 4px;"> <p style="margin: 0 0 5px 0; color: ${conn_score_color};"><strong>Security Score: ${conn_security_score}/100</strong></p>${conn_issues.length>0? conn_issues.map(i =>`<p style="margin: 2px 0; color: #E74C3C; font-size: 0.85em;">⚠ ${i}</p>`).join("") :'<p style="margin: 2px 0; color: #16A085; font-size: 0.85em;">✓ Configuration looks good for production use</p>'} </div></div>`
26.6 Access Control Lists (ACLs)
ACLs control which clients can publish/subscribe to which topics. This is the authorization layer - even authenticated users should only access topics they need (principle of least privilege).
Topic-Level Access Control: Different Users, Different Permissions
Figure 26.4: Topic-Level Access Control: Different Users, Different Permissions
26.6.1 Mosquitto ACL Configuration
Create /etc/mosquitto/acl:
# Admin can access everythinguseradmintopicreadwrite## Sensor devices can only publish to their topicsusersensor_001topicwritesensors/001/#topicreadcommands/001# Dashboard can read everything, write nothinguserdashboardtopicreadsensors/#topicreaddevices/## Default: deny everythingtopicdeny#