Contents
Why TLS for MQTT?
Standard MQTT (port 1883) sends data in plaintext. TLS encryption (port 8883) protects:
What TLS Protects:
- Username/password credentials
- Sensor data payloads
- Control commands
- Client IDs and topics
- Prevents man-in-the-middle attacks
Generate Certificates
Create your own Certificate Authority (CA) and server certificates:
# Create CA private key
openssl genrsa -out ca.key 2048
# Create CA certificate
openssl req -new -x509 -days 365 -key ca.key -out ca.crt \
-subj "/C=US/ST=State/L=City/O=MyOrg/CN=MyCA"
# Create server private key
openssl genrsa -out server.key 2048
# Create CSR (Certificate Signing Request)
openssl req -new -key server.key -out server.csr \
-subj "/C=US/ST=State/L=City/O=MyOrg/CN=mqtt.example.com"
# Sign server certificate with CA
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt
# Create client certificate
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
-subj "/C=US/ST=State/L=City/O=MyOrg/CN=client1"
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out client.crt
Mosquitto Broker Setup
Configure Eclipse Mosquitto for TLS:
# /etc/mosquitto/mosquitto.conf
# Listener for insecure connections (optional)
listener 1883
# Listener for TLS connections
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /etc/mosquitto/certs/ca.crt
# Require client certificates (mutual TLS)
require_certificate true
use_identity_as_username true
# TLS version (disable old versions)
tls_version tlsv1.2 tlsv1.3
# Cipher suites (strong ciphers only)
ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
# Restart Mosquitto
sudo systemctl restart mosquitto
ESP32 Client Configuration
#include
#include
// CA Certificate (PEM format)
const char* ca_cert = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiUMA0Gcg...
-----END CERTIFICATE-----
)EOF";
WiFiClientSecure espClient;
PubSubClient client(espClient);
void setup() {
espClient.setCACert(ca_cert);
// Optional: Client certificate for mutual TLS
// espClient.setCertificate(client_cert);
// espClient.setPrivateKey(client_key);
client.setServer("mqtt.example.com", 8883);
if (client.connect("ESP32_Client", "username", "password")) {
Serial.println("Connected with TLS!");
}
}
Client Certificate Authentication
Mutual TLS (mTLS) provides strongest security:
| Auth Method | Security | Complexity |
|---|---|---|
| Username/Password | Medium | Low |
| TLS Server Auth | High | Medium |
| mTLS (Client Certs) | Very High | High |
# Mosquitto with mTLS
listener 8883
certfile /etc/mosquitto/certs/server.crt
keyfile /etc/mosquitto/certs/server.key
cafile /etc/mosquitto/certs/ca.crt
# Require client certificates
require_certificate true
use_identity_as_username true
# Client connects with certificate
# No password needed - cert proves identity
Testing & Verification
# Test TLS connection
openssl s_client -connect mqtt.example.com:8883 -CAfile ca.crt
# Test with mosquitto_pub
mosquitto_pub -h mqtt.example.com -p 8883 \
--cafile ca.crt \
--cert client.crt \
--key client.key \
-t "test/topic" -m "Hello TLS!"
# Check certificate expiry
openssl x509 -in server.crt -noout -dates
# Verify certificate chain
openssl verify -CAfile ca.crt server.crt
Security Checklist:
- ✓ Use TLS 1.2 or 1.3 only
- ✓ Disable weak cipher suites
- ✓ Set certificate expiry alerts
- ✓ Use strong key sizes (2048+ bit)
- ✓ Protect private keys
- ✓ Implement certificate rotation
- ✓ Monitor for expired certs
Next Steps
- Set up automatic certificate renewal
- Implement certificate revocation (CRL/OCSP)
- Add certificate monitoring
- Use hardware secure element for key storage