Skip to content

Last updated: 2026-05-15

Mosquitto TLS/SSL Configuration Guide

This guide provides recommended TLS/SSL settings for Eclipse Mosquitto MQTT broker to encrypt connections between clients and the broker. Securing MQTT with TLS is essential for IoT deployments where devices transmit sensitive telemetry and control data.

Prerequisites

  • Eclipse Mosquitto 2.0 or later
  • OpenSSL 1.1.1 or later
  • SSL certificates (server certificate, private key, and CA certificate)

Certificate Setup

Place your certificates in a dedicated directory:

mkdir -p /etc/mosquitto/ssl
chmod 750 /etc/mosquitto/ssl
chown mosquitto:mosquitto /etc/mosquitto/ssl

cp server.crt /etc/mosquitto/ssl/server-cert.pem
cp server.key /etc/mosquitto/ssl/server-key.pem
cp ca.crt /etc/mosquitto/ssl/ca.pem

chmod 640 /etc/mosquitto/ssl/*.pem
chown mosquitto:mosquitto /etc/mosquitto/ssl/*.pem

Listener TLS Configuration

Configure a TLS-encrypted listener in mosquitto.conf. The standard MQTT-over-TLS port is 8883.

Basic TLS Listener

# TLS listener on port 8883
listener 8883

# Certificate files
cafile /etc/mosquitto/ssl/ca.pem
certfile /etc/mosquitto/ssl/server-cert.pem
keyfile /etc/mosquitto/ssl/server-key.pem

# TLS protocol version
tls_version tlsv1.2

# Cipher suites (OpenSSL format)
ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

# TLS 1.3 cipher suites
ciphers_tls1.3 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

Configuration Explained

  • listener 8883 -- Opens a listener on the standard MQTTS port.
  • tls_version tlsv1.2 -- Sets the minimum TLS protocol version. Mosquitto 2.0 with OpenSSL 1.1.1+ supports both TLS 1.2 and TLS 1.3.
  • ciphers -- OpenSSL cipher string for TLS 1.2 connections.
  • ciphers_tls1.3 -- OpenSSL ciphersuites string for TLS 1.3 connections.

Client Certificate Authentication

To require clients to present a TLS certificate (mutual TLS), add these settings to the TLS listener:

require_certificate true
use_identity_as_username true
  • require_certificate true -- Clients must present a valid certificate signed by the CA in cafile.
  • use_identity_as_username true -- Uses the certificate's Common Name (CN) as the MQTT username, removing the need for password-based authentication.

See RFC 8446 ยง4.3.2 for the TLS Certificate Request specification, and Wikipedia: Mutual authentication for a general overview.

Multiple Listeners

You can run both a plaintext listener (for local trusted networks) and a TLS listener simultaneously:

# Plaintext listener on localhost only
listener 1883 127.0.0.1
allow_anonymous true

# TLS listener on all interfaces
listener 8883
cafile /etc/mosquitto/ssl/ca.pem
certfile /etc/mosquitto/ssl/server-cert.pem
keyfile /etc/mosquitto/ssl/server-key.pem
tls_version tlsv1.2
ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
ciphers_tls1.3 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

WebSocket TLS

Mosquitto can serve MQTT over WebSockets with TLS for browser-based clients:

listener 8884
protocol websockets

cafile /etc/mosquitto/ssl/ca.pem
certfile /etc/mosquitto/ssl/server-cert.pem
keyfile /etc/mosquitto/ssl/server-key.pem
tls_version tlsv1.2
ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

Complete Configuration

# Per-listener settings
per_listener_settings true

# Plaintext listener on localhost only
listener 1883 127.0.0.1
allow_anonymous true

# TLS listener on port 8883
listener 8883
cafile /etc/mosquitto/ssl/ca.pem
certfile /etc/mosquitto/ssl/server-cert.pem
keyfile /etc/mosquitto/ssl/server-key.pem
tls_version tlsv1.2
ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
ciphers_tls1.3 TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
require_certificate false

# Password file for TLS listener
password_file /etc/mosquitto/passwd

Client Connections

mosquitto_pub / mosquitto_sub

mosquitto_pub -h mqtt.example.com -p 8883 \
    --cafile /path/to/ca.pem \
    -t "test/topic" -m "Hello TLS"

mosquitto_sub -h mqtt.example.com -p 8883 \
    --cafile /path/to/ca.pem \
    -t "test/topic"

With client certificates (mutual TLS):

mosquitto_pub -h mqtt.example.com -p 8883 \
    --cafile /path/to/ca.pem \
    --cert /path/to/client-cert.pem \
    --key /path/to/client-key.pem \
    -t "test/topic" -m "Hello mTLS"

Python (paho-mqtt)

import paho.mqtt.client as mqtt
import ssl

client = mqtt.Client()
client.tls_set(
    ca_certs="/path/to/ca.pem",
    tls_version=ssl.PROTOCOL_TLS_CLIENT
)
client.connect("mqtt.example.com", 8883)

Security Notes

The cipher suite and protocol configuration in this guide addresses the following known TLS vulnerabilities:

  • POODLE (CVE-2014-3566, 2014): SSL 3.0 is disabled. TLS_FALLBACK_SCSV was added in OpenSSL 1.0.1j / 1.0.2 (October 2014); SSL 3.0 disabled by default in OpenSSL 1.1.0 (August 2016).
  • BEAST (CVE-2011-3389, 2011): Mitigated by recommending TLS 1.2 as the minimum; AEAD-only ciphers eliminate the CBC padding oracle.
  • CRIME (CVE-2012-4929, 2012): TLS compression is off by default in OpenSSL 1.1.0+; do not enable it.
  • Lucky13 (2013): AEAD-only cipher list eliminates CBC padding timing side-channels entirely.
  • FREAK (CVE-2015-0204, 2015): EXPORT-grade ciphers are excluded from the cipher string. Removed from OpenSSL 1.1.0 (August 2016).
  • LOGJAM (CVE-2015-4000, 2015): Short-key DHE is excluded; only ECDHE key exchange is recommended.
  • Sweet32 (CVE-2016-2183, 2016): 3DES is excluded from the cipher string. Disabled by default in OpenSSL 3.0 (September 2021).
  • ROBOT (CVE-2017-13099, 2017): Static RSA key exchange is excluded; only ECDHE is recommended. Fixed in OpenSSL 1.0.2m / 1.0.1v (November 2017).
  • Downgrade attacks: TLS_FALLBACK_SCSV prevents protocol version rollback.

The following are not addressable through TLS configuration alone:

  • Heartbleed (CVE-2014-0160, 2014): A memory disclosure bug in OpenSSL 1.0.1 through 1.0.1f. Fixed in OpenSSL 1.0.1g (April 7, 2014). Addressed by patching OpenSSL, not by TLS configuration.
  • BREACH (CVE-2013-3587, 2013): Not applicable. BREACH targets HTTP-level response compression; the MQTT protocol does not involve HTTP.
  • DROWN (CVE-2016-0800, 2016): Requires SSLv2 to be enabled on any server sharing the same private key. Ensure SSLv2 is disabled on all services that use the same certificate and key pair.

Verification

Test the TLS connection with openssl:

openssl s_client -connect mqtt.example.com:8883

Verify the port is listening:

ss -tlnp | grep 8883

Test publish and subscribe over TLS:

mosquitto_sub -h mqtt.example.com -p 8883 --cafile /path/to/ca.pem -t "test/#" &
mosquitto_pub -h mqtt.example.com -p 8883 --cafile /path/to/ca.pem -t "test/hello" -m "works"

Check Mosquitto logs:

grep -i tls /var/log/mosquitto/mosquitto.log

Related Guides

View all Message Brokers guides →

Configured TLS? Now Monitor It.

Generator Labs alerts you before certificates expire, get revoked, or fail chain validation — across HTTPS, SMTPS, IMAPS, LDAPS, and more.

Certificate Monitoring →