mTLS
Client certificates are a popular way of adding an extra layer of security to your client authentication. It can either be added on top or instead of the regular authentication provided by the role based authentication using username and password. While connecting, a client identifies using a client certificate. The broker has stored a client certificate authority and allows a connection, if the client certificate gets validated, the connection is allowed.
The CA Management allows the upload of client CAs to the broker via a UI.
Listener configuration
MTLS has to be activated on a port (listener) level.
Default Cloud configuration
The default broker configuration, when mTLS is selected in a cloud subscription for a port looks like this (shown with port 8883):
# Listener for the application, MQTTS over TCP with client certs
listener 8883
certfile /mosquitto/config/certs/server.pem
keyfile /mosquitto/config/certs/server.key
capath /mosquitto/config/capath_mqtts
require_certificate true
enable_control_api true
plugin /usr/lib/cedalo_certificate_management.so
If you need any changes to this default please contact our support team.
On-premises configuration
The following options can be used for mTLS configuration.
Certificate and Key Settings (Server-side)
cafile <path>: Specifies the path to the Certificate Authority (CA) file that the broker will use to validate client certificates.capath <path>: Specifies the path to the Certificate Authority (CA) folder that the broker will use to validate client certificates. This is needed if more then one file is present.certfile <path>: The server's public certificate file that will be presented to clients during the TLS handshake.keyfile <path>: The server's private key file used to establish the TLS connection. The private key should remain secure and not be shared.
The path of the capath configuration should contain at least a root CA cert.
Note: The cafile configuration with a single PEM file containing the CA
chain is currently not supported for this command.
Certificate and Key Settings (Client-side validation)
require_certificate <true|false>: Determines whether clients are required to present a valid certificate for authentication. Set this totrueto enforce mTLS.tls_version <version>: Specifies the minimum TLS version allowed for the connection. Common values includetlsv1.2ortlsv1.3to ensure a secure connection.use_identity_as_username <true|false>: If set totrue, the broker will use the client certificate's Common Name (CN) field as the client's username for authentication.
Plugin configuration
To enable the plugin it must be loaded into the broker with, by adding the
following to your mosquitto.conf:
plugin /usr/lib/cedalo_certificate_management.so
Control API
In addition to enable the brokers internal $CONTROL/broker/v1 API we need to
add:
enable_control_api true
This is required to determine the listeners identifier, where the changes should be applied to.
This plugin provides a Mosquitto control API which manages client CA certificates for
certificate based authentication/validation.
The topic of the plugin's control API is $CONTROL/certificate-management/v1.
Currently, supported commands offered by the API are insertCACertificate, which
can be used to extend the existing Certificate Authority (CA) Chain or just the
Root CA by an additional signing/validating certificate. To get rid of a
previously added CA cert, the deleteCACertificate command can be used.
Kubernetes and OpenShift Deployment
Note: For OpenShift deployments, replace kubectl with oc in all commands below. The chart directory names differ:
- Kubernetes Cluster:
mosquitto-platform-kubernetes-cluster - Kubernetes Single Node:
mosquitto-platform-kubernetes-sn - OpenShift Cluster:
mosquitto-platform-openshift-cluster - OpenShift Single Node:
mosquitto-platform-openshift-sn
Cluster Setup
Required Files
Server Certificates:
server.pem- Server certificate (can contain certificate chain)server.key- Server private key
Client CA Certificates:
ca.crt- CA certificate that signed the client certificates<hash>.0- Hash-named file for Mosquitto capath (e.g.,4b073644.0)
Secret Creation
Certificates can be created externally to Helm charts using kubectl or oc commands. This is the recommended approach as it's easier and provides better control over secret management. When using external secrets, set createSecret: false in your Helm installation.
Note: The secret names and paths mentioned here are default values and can be configured via Helm values. See the Configuration Parameters section below for customization options.
For Kubernetes:
# Set namespace
NAMESPACE="your-namespace"
# Create mTLS server certificate secret (using default secret name)
kubectl create secret generic mosquitto-mtls-server-tls \
--from-file=server.pem=server.pem \
--from-file=server.key=server.key \
-n $NAMESPACE
# Calculate CA hash and create hash-named file
HASH=$(openssl x509 -hash -noout -in ca.crt)
cp ca.crt ${HASH}.0
# Create client CA secret (using default secret name)
# IMPORTANT: Client CA secret must always be created externally
kubectl create secret generic mosquitto-client-ca \
--from-file=ca.crt=ca.crt \
--from-file=${HASH}.0=${HASH}.0 \
-n $NAMESPACE
For OpenShift:
# Set namespace
NAMESPACE="your-namespace"
# Create mTLS server certificate secret (using default secret name)
oc create secret generic mosquitto-mtls-server-tls \
--from-file=server.pem=server.pem \
--from-file=server.key=server.key \
-n $NAMESPACE
# Calculate CA hash and create hash-named file
HASH=$(openssl x509 -hash -noout -in ca.crt)
cp ca.crt ${HASH}.0
# Create client CA secret (using default secret name)
# IMPORTANT: Client CA secret must always be created externally
oc create secret generic mosquitto-client-ca \
--from-file=ca.crt=ca.crt \
--from-file=${HASH}.0=${HASH}.0 \
-n $NAMESPACE
Note: When creating secrets externally:
- Server certificate secret name must match
mosquitto.mtls.secretName(default:mosquitto-mtls-server-tls) - Server certificate secret keys must match
certFileandkeyFilevalues (defaults:server.pemandserver.key) - Client CA secret name must match
mosquitto.mtls.clientCaSecretName(default:mosquitto-client-ca) - Client CA secret must include
ca.crtand hash-named files (e.g.,4b073644.0) - Set
mosquitto.mtls.createSecret=falsein your Helm installation to use externally created server certificate secret - Client CA secret is always external and cannot be created by Helm
Certificate Mounting
The Helm chart automatically mounts certificates as follows (all values shown are defaults and can be customized):
Server Certificates:
- Secret:
mosquitto-mtls-server-tls(configurable viamosquitto.mtls.secretName) - Mount Path:
/mosquitto/config/certs/(configurable viamosquitto.mtls.tlsMountPath) - Files:
server.pem,server.key(configurable viamosquitto.mtls.certNameandmosquitto.mtls.keyName)
- Secret:
Client CA Certificates:
- Secret:
mosquitto-client-ca(configurable viamosquitto.mtls.clientCaSecretName) - Mount Path:
/mosquitto/config/capath_mqtts/(configurable viamosquitto.mtls.caMountPath) - Files:
ca.crt,<hash>.0(e.g.,4b073644.0) - An init container copies files from the secret to an
emptyDirvolume to ensure proper file permissions
- Secret:
Configuration Parameters
Note: All secret names, file names, and mount paths mentioned below are default values and can be customized via Helm values. You can override any of these defaults to match your specific requirements.
Server Certificate Configuration:
mosquitto.mtls.enabled: Enable mTLS (Mutual TLS) listener on port 8883. When enabled, both server and clients must present certificates for authentication. Default:falsemosquitto.mtls.secretName: Kubernetes Secret name containing server TLS certificates for mTLS. This secret must exist ifcreateSecretis set tofalse. Default:mosquitto-mtls-server-tlsmosquitto.mtls.createSecret: Iftrue, Helm will create the secret fromcertContentandkeyContent. Iffalse, the secret must exist externally (created viakubectloroc). Recommended approach: Set tofalseand create secrets externally usingkubectl create secretoroc create secretcommands, as this is easier and provides better control over secret management. Default:truemosquitto.mtls.certFile: Certificate file name (key) in the Kubernetes Secret. This should match the key name used when creating the secret externally. Default:server.pemmosquitto.mtls.keyFile: Private key file name (key) in the Kubernetes Secret. This should match the key name used when creating the secret externally. Default:server.keymosquitto.mtls.tlsMountPath: Directory path where server TLS certificates are mounted in the container. Should be a DIRECTORY path only (e.g.,/mosquitto/config/certs). Do not include the filename. Default:/mosquitto/config/certsmosquitto.mtls.certName: Certificate filename when mounted in the container. Should be a FILENAME only (e.g.,server.pem), no path. The final path is constructed as:tlsMountPath/certName=/mosquitto/config/certs/server.pem. Default:server.pemmosquitto.mtls.keyName: Private key filename when mounted in the container. Should be a FILENAME only (e.g.,server.key), no path. The final path is constructed as:tlsMountPath/keyName=/mosquitto/config/certs/server.key. Default:server.keymosquitto.mtls.certContent: Base64-encoded server certificate content. Only used whencreateSecret: true. IfcreateSecret: false, this parameter is ignored and the secret must be created externally with keys matchingcertFileandkeyFile. Default:""(empty string)mosquitto.mtls.keyContent: Base64-encoded server private key content. Only used whencreateSecret: true. IfcreateSecret: false, this parameter is ignored and the secret must be created externally with keys matchingcertFileandkeyFile. Default:""(empty string)
Client CA Certificate Configuration:
mosquitto.mtls.clientCaSecretName: Kubernetes Secret name containing client CA certificates. IMPORTANT: This secret must be created externally before deploying. It cannot be created by Helm. The secret must containca.crtand hash-named files (e.g.,4b073644.0). Default:mosquitto-client-camosquitto.mtls.caMountPath: Directory path where client CA certificates are mounted in the container. This is thecapathdirectory that Mosquitto uses to validate client certificates. Should be a DIRECTORY path only (e.g.,/mosquitto/config/capath_mqtts). Default:/mosquitto/config/capath_mqtts
Client Certificate Validation Configuration:
mosquitto.mtls.requireCertificate: Determines whether clients are required to present a valid certificate for authentication. Set totrueto enforce mTLS (clients must present certificates). Set tofalseto make client certificates optional. Default:truemosquitto.mtls.useIdentityAsUsername: If set totrue, the broker will use the client certificate's Common Name (CN) field as the client's username for authentication. Iffalse, clients must provide username/password separately. Default:falsemosquitto.mtls.tlsVersion: Specifies the minimum TLS version allowed for the connection. Common values includetlsv1.2ortlsv1.3to ensure a secure connection. Leave empty to use Mosquitto's default TLS version. Default:""(empty string, uses Mosquitto default)
First-Time Installation
For Kubernetes Cluster:
# Set namespace
NAMESPACE="your-namespace"
# Install with mTLS enabled
helm install mosquitto-platform \
./mosquitto-platform-kubernetes-cluster \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
# Rollout HAProxy to pick up mTLS configuration
kubectl rollout restart deployment haproxy -n $NAMESPACE
For OpenShift Cluster:
# Set namespace
NAMESPACE="your-namespace"
# Install with mTLS enabled
helm install mosquitto-platform \
./mosquitto-platform-openshift-cluster \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
# Rollout HAProxy to pick up mTLS configuration
oc rollout restart deployment haproxy -n $NAMESPACE
Upgrade Installation
For Kubernetes Cluster:
# Set namespace
NAMESPACE="your-namespace"
# Upgrade with mTLS enabled
helm upgrade mosquitto-platform \
./mosquitto-platform-kubernetes-cluster \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
# Rollout HAProxy to pick up mTLS configuration changes
kubectl rollout restart deployment haproxy -n $NAMESPACE
For OpenShift Cluster:
# Set namespace
NAMESPACE="your-namespace"
# Upgrade with mTLS enabled
helm upgrade mosquitto-platform \
./mosquitto-platform-openshift-cluster \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
# Rollout HAProxy to pick up mTLS configuration changes
oc rollout restart deployment haproxy -n $NAMESPACE
Single Node Setup
Required Files
Same as Cluster Setup:
server.pem- Server certificateserver.key- Server private keyca.crt- Client CA certificate<hash>.0- Hash-named file for Mosquitto capath
Secret Creation
Same as Cluster Setup (see above). The secret names and paths are default values and can be configured via Helm values. See the Configuration Parameters section in Cluster Setup above for customization options.
Certificate Mounting
Same mount paths as Cluster Setup (all values are defaults and can be customized):
- Server certificates:
/mosquitto/config/certs/(configurable viamosquitto.mtls.tlsMountPath) - Client CA certificates:
/mosquitto/config/capath_mqtts/(configurable viamosquitto.mtls.caMountPath)
Note: Single node deployments do not include HAProxy, so certificates are mounted directly to the Mosquitto StatefulSet.
First-Time Installation
For Kubernetes Single Node:
# Set namespace
NAMESPACE="your-namespace"
# Install with mTLS enabled
helm install mosquitto-platform \
./mosquitto-platform-kubernetes-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
For OpenShift Single Node:
# Set namespace
NAMESPACE="your-namespace"
# Install with mTLS enabled
helm install mosquitto-platform \
./mosquitto-platform-openshift-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
Upgrade Installation
For Kubernetes Single Node:
# Set namespace
NAMESPACE="your-namespace"
# Upgrade with mTLS enabled
helm upgrade mosquitto-platform \
./mosquitto-platform-kubernetes-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
For OpenShift Single Node:
# Set namespace
NAMESPACE="your-namespace"
# Upgrade with mTLS enabled
helm upgrade mosquitto-platform \
./mosquitto-platform-openshift-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.mtls.enabled=true \
--set mosquitto.mtls.createSecret=false
Verification
After installation, verify that certificates are properly mounted:
# Check server certificates
kubectl exec mosquitto-0 -n $NAMESPACE -- ls -la /mosquitto/config/certs/
# Should show: server.pem and server.key
# Check client CA certificates in capath
kubectl exec mosquitto-0 -n $NAMESPACE -- ls -la /mosquitto/config/capath_mqtts/
# Should show: ca.crt and <hash>.0 (e.g., 4b073644.0)
# Verify Mosquitto configuration
kubectl exec mosquitto-0 -n $NAMESPACE -- grep -A 10 "listener.*8883" /mosquitto/config/mosquitto.conf
# Should show mTLS listener configuration with certfile, keyfile, capath, and require_certificate
Note: For OpenShift, replace kubectl with oc in the verification commands above.