Server Certificates
Docker & Linux RPM Setup
Prerequisites
Ensure you have the following files ready before configuring Mosquitto:
- Server Certificate (
server.crt): The public server certificate. - Private Key (
server.key): The private key associated with the server certificate.
Configuring Pro Edition for Eclipse Mosquitto Broker with a Server Certificate
This document outlines the two available methods for configuring a broker with a server certificate: using a proxy for TLS termination or configuring TLS directly on the broker. In cluster environments, the use of HAProxy, as provided in the default setup, is recommended for managing TLS termination.
Pro Edition for Eclipse Mosquitto TLS termination
Open your mosquitto.conf file to add a certificate to a certain port.
Add or modify the following settings to configure the Pro Edition for Eclipse Mosquitto broker to use the server certificate:
# Enable a listener on port 8883 for SSL/TLS connections
listener 8883
protocol mqtt
# SSL/TLS certificate paths
certfile /path/to/server.crt
keyfile /path/to/server.key
- listener 8883: Sets the port for SSL/TLS communication. Port 8883 is the standard MQTT SSL/TLS port.
- certfile: Specifies the path to the server's public certificate file.
- keyfile: Specifies the path to the server's private key file.
HA Proxy TLS termination
In a cluster setup an HA Proxy is used for TLS termination. This is the default config of the frontend haproxy.cfgfile:
frontend mqtt_frontend
bind *:1883
mode tcp
default_backend mqtt_backend
timeout client 10m
In order to enable TLS termination here add the following behind the bind *:<port> parameter: ssl crt /path/to/certs/server.pem
This will do the TLS termination at the frontend stage before routing the traffic further to the set backend (here mqtt_backend ).
Client connections
Use an MQTT client to connect to the broker using the secure port (e.g., 8883) to verify that the server certificate is being used:
mosquitto_sub -h <broker-ip> -p 8883 -t test/topic --cafile /path/to/ca.crt
In this example, a --cafile parameter is added to the test because, depending on the device and the server certificate, your underlying system may not have the required CA in place to validate the server certificate you set.
Certificate access
It is important that the files from the specified path are available to Pro Edition for Eclipse Mosquitto. Ensure that the private key file is securely accessible to the Mosquitto service:
sudo chmod 640 /path/to/server.key
sudo chown mosquitto:mosquitto /path/to/server.key
This ensures that only the Mosquitto service has access to the private key, enhancing security.
To apply the changes, restart Pro Edition for Eclipse Mosquitto. Check the Mosquitto logs for troubleshooting if needed.
Configuring Cedalo Platform with a Server Certificate
You can achieve https:// access either via a reverse proxy of your choice or by adding the server certificates directly to the platform via environment variables.
Environment Variables
To configure the server certificates use the following Environment Variables:
- BASE_URL: URL the platform will be reachable at (should have the same IP/hostname as specified in the certificate)
- NEXTAUTH_URL: URL the platform will be reachable at (should have the same IP/hostname as specified in the certificate)
- MOSQUITTO_PLATFORM_HTTPS_KEY_PATH: Path to server's private key file (required)
- MOSQUITTO_PLATFORM_HTTPS_CERT_PATH: Path to server's certificate (required)
- MOSQUITTO_PLATFORM_HTTPS_CA_PATH: path to CA certificate (optional)
Example configuration
Docker
BASE_URL: https://192.168.178.27:3000
NEXTAUTH_URL: https://192.168.178.27:3000
MOSQUITTO_PLATFORM_HTTPS_KEY_PATH: /certs/cert.key
MOSQUITTO_PLATFORM_HTTPS_CERT_PATH: /certs/cert.crt
Docker compose
In docker based deployments make sure, that the linked certificates are reachable. A mount to the local directory allows you to store the used certs in the setup folders:
volumes:
...
- ./certs:/certs
RPM
export BASE_URL=https://192.168.178.27:3000
export NEXTAUTH_URL=https://192.168.178.27:3000
export MOSQUITTO_PLATFORM_HTTPS_KEY_PATH=/certs/cert.key
export MOSQUITTO_PLATFORM_HTTPS_CERT_PATH=/certs/cert.crt
Kubernetes/OpenShift TLS setup
This guide matches the 3.2 Helm charts in this repository. Chart directories:
| Platform | Single node | HA cluster (HAProxy entry point) |
|---|---|---|
| Kubernetes | mosquitto-3.2-platform-3.2-kubernetes-sn | mosquitto-3.2-platform-3.2-kubernetes-cluster |
| OpenShift | mosquitto-3.2-platform-3.2-openshift-sn | mosquitto-3.2-platform-3.2-openshift-cluster |
Throughout this document, kubectl on Kubernetes can be replaced with oc on OpenShift.
TLS configuration overview
The Helm charts support dynamic TLS configuration through values.yaml and --set flags, without manually editing packaged chart files.
| Deployment | Typical TLS approach |
|---|---|
| Single node | TLS on the Mosquitto broker only (mosquitto.serverOnlyTls). No HAProxy in front of MQTT for this topology. |
| HA cluster | Either TLS termination at HAProxy (haproxy.tls.enabled) or TLS on Mosquitto with HAProxy TCP passthrough (mosquitto.serverOnlyTls.enabled). See HA cluster TLS configuration. |
Single node TLS configuration (server-only TLS)
For single-node deployments, TLS is configured directly on the Mosquitto broker using server-only TLS. This enables one-way TLS where only the server presents a certificate to clients.
Prerequisites
Ensure you have the following files ready:
- Server certificate (
server.crt): the public server certificate - Private key (
server.key): the private key associated with the server certificate
Secret creation
Certificates can be created outside the Helm chart using kubectl or oc. This is the recommended approach for clearer secret lifecycle management. When using external secrets, set mosquitto.serverOnlyTls.createSecret=false.
Note: Secret names and paths below are defaults and can be overridden in Helm values. See Configuration parameters.
Kubernetes
NAMESPACE="your-namespace"
kubectl create secret generic mosquitto-server-tls \
--from-file=server.crt=server.crt \
--from-file=server.key=server.key \
-n $NAMESPACE
OpenShift
NAMESPACE="your-namespace"
oc create secret generic mosquitto-server-tls \
--from-file=server.crt=server.crt \
--from-file=server.key=server.key \
-n $NAMESPACE
When creating secrets externally, the secret name must match mosquitto.serverOnlyTls.secretName (default: mosquitto-server-tls) and the secret keys must match certFile and keyFile (defaults: server.crt and server.key). Set mosquitto.serverOnlyTls.createSecret=false in your Helm values or --set.
First-time installation
Kubernetes single node
NAMESPACE="your-namespace"
helm install mosquitto-platform \
./mosquitto-3.2-platform-3.2-kubernetes-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.serverOnlyTls.enabled=true \
--set mosquitto.serverOnlyTls.createSecret=false
OpenShift single node
NAMESPACE="your-namespace"
helm install mosquitto-platform \
./mosquitto-3.2-platform-3.2-openshift-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.serverOnlyTls.enabled=true \
--set mosquitto.serverOnlyTls.createSecret=false
Upgrade installation
Kubernetes single node
NAMESPACE="your-namespace"
helm upgrade mosquitto-platform \
./mosquitto-3.2-platform-3.2-kubernetes-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.serverOnlyTls.enabled=true \
--set mosquitto.serverOnlyTls.createSecret=false
OpenShift single node
NAMESPACE="your-namespace"
helm upgrade mosquitto-platform \
./mosquitto-3.2-platform-3.2-openshift-sn \
-n $NAMESPACE \
-f values.yaml \
--set mosquitto.serverOnlyTls.enabled=true \
--set mosquitto.serverOnlyTls.createSecret=false
Configuration parameters (single node)
Note: All secret names, file names, and mount paths below are defaults and can be customized via Helm values.
mosquitto.serverOnlyTls.enabled— Enables the server-only TLS listener on the secure MQTT port (default 8883 in the single-node chart). When enabled, Mosquitto presents a server certificate to clients. Default:false.mosquitto.serverOnlyTls.secretName— Kubernetes Secret name containing server TLS material. The secret must exist ifcreateSecretisfalse. Default:mosquitto-server-tls.mosquitto.serverOnlyTls.createSecret— Iftrue, Helm creates the secret fromcertContentandkeyContent. Iffalse, create the secret withkubectl/ocas above. Recommended:falsefor externally managed secrets. Default:true.mosquitto.serverOnlyTls.certFile— Key name inside the Secret for the certificate (must match how you created the secret). Default:server.crt.mosquitto.serverOnlyTls.keyFile— Key name inside the Secret for the private key. Default:server.key.mosquitto.serverOnlyTls.tlsMountPath— Directory only where certificates are mounted in the container (e.g./mosquitto/certs). Do not append a filename. Default:/mosquitto/certs.mosquitto.serverOnlyTls.certName— Filename only as seen inside the container (e.g.server.crt). Full path:tlsMountPath+/+certName. Default:server.crt.mosquitto.serverOnlyTls.keyName— Filename only for the key (e.g.server.key). Default:server.key.mosquitto.serverOnlyTls.certContent/keyContent— Base64-encoded material; used only whencreateSecret: true. Ignored whencreateSecret: false.
Helm value spelling: the chart uses serverOnlyTls (camelCase with lowercase s in “Tls”), e.g. mosquitto.serverOnlyTls.enabled, not serverOnlyTLS.
What happens under the hood (single node)
When you enable mosquitto.serverOnlyTls, the chart:
Mounts the Secret as a volume on the Mosquitto workload at the configured mount path (default
/mosquitto/certs).Updates
mosquitto.confwith a TLS listener on the secure port, for example:listener 8883
protocol mqtt
certfile /mosquitto/certs/server.crt
keyfile /mosquitto/certs/server.keyActual paths are built from
tlsMountPath/certNameandtlsMountPath/keyNamewhen you override defaults.Exposes the secure listener port on the Mosquitto Service (per chart defaults).
Verify TLS configuration (single node)
# Service ports
kubectl get svc mosquitto -n $NAMESPACE
# Certificates mounted
kubectl exec mosquitto-0 -n $NAMESPACE -- ls -la /mosquitto/certs/
# Expect: server.crt and server.key
# Mosquitto config
kubectl exec mosquitto-0 -n $NAMESPACE -- grep -A 5 "listener.*8883" /mosquitto/config/mosquitto.conf
# Test TLS (use host/IP and CA that match your cert)
mosquitto_sub -h <mosquitto-external-ip> -p 8883 --cafile ca.crt -u <username> -P <password> -t '#'
Important path configuration notes (single node)
tlsMountPathmust be a directory path only (e.g./mosquitto/certs).certName/keyNamemust be filenames only (e.g.server.crt,server.key).- Final paths:
tlsMountPath/certName,tlsMountPath/keyName. - Wrong:
tlsMountPathset to/mosquitto/certs/server.crt(includes filename). - Right:
tlsMountPath="/mosquitto/certs"andcertName="server.crt".
HA cluster TLS configuration
HA charts use HAProxy as the MQTT entry point. TLS can end either at HAProxy or at Mosquitto, controlled by different values—do not confuse them.
Two TLS modes (terminology)
| Concept | Helm flag | Where TLS terminates | What the client validates |
|---|---|---|---|
| HAProxy TLS | haproxy.tls.enabled | HAProxy decrypts TLS, then plain MQTT to Mosquitto on mosquitto.ports.listenerTarget (default 1888). | The certificate in HAProxy’s combined PEM (haproxy.tls.pemFile, default haproxy_combined.pem). |
| Server-only TLS on Mosquitto | mosquitto.serverOnlyTls.enabled | Mosquitto on mosquitto.ports.secureListenerTarget (default 8883). HAProxy binds 8883 as plain TCP and forwards bytes unchanged (passthrough). | server.crt / server.key (or your configured certFile / keyFile) in mosquitto.serverOnlyTls.secretName. |
How the flags interact
Rendered from templates/haproxy-config.yaml in the cluster charts. The secure frontend (mqtt_frontend_secure on haproxy.ports.secureListener, default 8883) behaves as follows:
- If
mosquitto.serverOnlyTls.enabledistrue(ormosquitto.mtls.enabledistrue): HAProxy binds withoutssl crt(TCP only). Traffic goes tomqtt_backend_secure→ each brokermosquitto.ports.secureListenerTarget(default 8883). Mosquitto performs the TLS handshake. - Else if
haproxy.tls.enabledistrue: HAProxy binds withssl crt <pemPath>and terminates TLS. Traffic goes tomqtt_backend→ brokers onmosquitto.ports.listenerTarget(default 1888) in plain MQTT, with optional PROXY v2 perhaproxy.proxyProtocol.
haproxy.tls.enabled=false and mosquitto.serverOnlyTls.enabled=true
- HAProxy 8883 is TCP passthrough to broker 8883.
- HAProxy does not mount the HAProxy PEM volume (
haproxy.tls.enabledgates the volume indeployment-haproxy*.yaml). - Mosquitto mounts
mosquitto.serverOnlyTlsand serves TLS as in the single node section. haproxy.proxyProtocol.enabledmust befalse. The chart fails if proxy protocol stays enabled whileserverOnlyTlsormtlsis enabled (templates/mosquitto-config.yaml).
haproxy.tls.enabled=true and mosquitto.serverOnlyTls.enabled=false
- HAProxy terminates TLS on 8883, forwards plain MQTT to 1888.
- Requires a combined PEM Secret for HAProxy (see below).
haproxy.proxyProtocol.modecannot bedirect; usetls-server,tls-mtls, ortls-mtls-cnwithhaproxy.proxyProtocol.enabled=trueso broker and HAProxy agree on PROXY v2 + TLS metadata.
Both haproxy.tls.enabled=true and mosquitto.serverOnlyTls.enabled=true
- The template still uses the passthrough branch when
serverOnlyTlsis on (same effective behavior asserverOnlyTlsalone on 8883). - If
haproxy.tls.enabledstaystrue, HAProxy still mounts the PEM Secret even though that PEM is not used for the public 8883 bind—redundant and easy to misread. - Recommendation: use one model. For TLS at Mosquitto behind HAProxy, set
haproxy.tls.enabled=falseandmosquitto.serverOnlyTls.enabled=true.
HAProxy TLS configuration parameters (HA cluster charts)
Defaults and behavior match mosquitto-3.2-platform-3.2-kubernetes-cluster / mosquitto-3.2-platform-3.2-openshift-cluster values.yaml unless noted.
haproxy.tls.enabled— Enable TLS termination on HAProxy for the secure frontend (bind … ssl crt …). Default:false.haproxy.tls.secretName— Name of the Secret that holds the combined PEM. Default:haproxy-tls-certs.haproxy.tls.createSecret— Iftrue, Helm renders the HAProxy TLS Secret frompemContent(Kubernetes cluster chart:templates/haproxy-tls-certs.yamlis conditional on this). Iffalse, create the Secret yourself before install/upgrade. Present in the Kubernetes cluster chart defaults; the OpenShift cluster chartvalues.yamlmay not list it—--setstill works if your chart revision supports the same key in templates/helpers.haproxy.tls.pemFile— Key name inside the Secret for the combined cert+key PEM file. Default:haproxy_combined.pem.haproxy.tls.pemPath— Full path passed to HAProxycrt(must match where the PEM file is mounted in the container). Default:/etc/haproxy/certs/haproxy_combined.pem.haproxy.tls.pemContent— Base64-encoded combined PEM (cert + key). Used when Helm creates the Secret (createSecret: trueon Kubernetes cluster chart, or when your OpenShift revision expects inline data in values).haproxy.haproxyCombinedPemFilePath— (Kubernetes cluster chart) Directory mount path for the HAProxy TLS Secret volume on the HAProxy pod. Default:/etc/haproxy/certs.haproxy.tls.tlsHaproxyPemDirPath— (OpenShift cluster chart) Directory mount path for the HAProxy TLS Secret volume. Default:/etc/haproxy/certs.haproxy.ports.secureListener— Service / external secure MQTT port (HAProxy listens here for the secure frontend). Default:8883.haproxy.ports.secureListenerTarget— Container port HAProxy listens on for that secure frontend. Default:8883.haproxy.ports.secureNodePort— Optional fixed NodePort when the HAProxy Service is NodePort. Default:null(auto).
Related (not under haproxy.tls, but required when only HAProxy terminates TLS):
haproxy.proxyProtocol.enabled/haproxy.proxyProtocol.mode— Withhaproxy.tls.enabledandmosquitto.serverOnlyTls.enabledfalse,modemust betls-server,tls-mtls, ortls-mtls-cn(notdirect). Withmosquitto.serverOnlyTls.enabledtrue, sethaproxy.proxyProtocol.enabledtofalse.
Mosquitto server-only TLS configuration parameters (HA cluster charts)
The same mosquitto.serverOnlyTls block applies to HA as to single node; the StatefulSet mounts the Secret and opens the secure listener on mosquitto.ports.secureListenerTarget (default 8883). HAProxy then TCP-forwards external haproxy.ports.secureListener to that port when serverOnlyTls is enabled.
mosquitto.serverOnlyTls.enabled— One-way TLS on the broker secure listener. Default:false.mosquitto.serverOnlyTls.secretName— Secret containing server cert and key. Default:mosquitto-server-tls.mosquitto.serverOnlyTls.createSecret— Helm-managed Secret fromcertContent/keyContentvs external Secret. Default:true(external creation withcreateSecret: falseis common in production).mosquitto.serverOnlyTls.certFile/mosquitto.serverOnlyTls.keyFile— Key names inside the Secret. Defaults:server.crt,server.key.mosquitto.serverOnlyTls.tlsMountPath— Mount directory in the Mosquitto container. Default:/mosquitto/certs.mosquitto.serverOnlyTls.certName/mosquitto.serverOnlyTls.keyName— Filenames as seen after mount (used inmosquitto.confcertfile/keyfile). Defaults:server.crt,server.key.mosquitto.serverOnlyTls.certContent/mosquitto.serverOnlyTls.keyContent— Base64-encoded cert/key; only used whencreateSecret: true.
Ports used with HAProxy passthrough (defaults from cluster values.yaml):
mosquitto.ports.secureListenerTarget— Broker container port for TLS MQTT (HAProxymqtt_backend_securetargets this). Default:8883.mosquitto.ports.listenerTarget— Plain cluster listener (used when HAProxy terminates TLS and forwards plain MQTT). Default:1888(cluster chart).
Certificates and secrets (HA)
HAProxy TLS (haproxy.tls.enabled=true)
Combine certificate then key (order matters for HAProxy):
cat server.crt server.key > haproxy_combined.pem
Create a Secret whose data key matches haproxy.tls.pemFile (default haproxy_combined.pem) and name matches haproxy.tls.secretName (default haproxy-tls-certs):
NAMESPACE="your-namespace"
kubectl create secret generic haproxy-tls-certs \
--namespace "$NAMESPACE" \
--from-file=haproxy_combined.pem=./haproxy_combined.pem
kubectl create secret --from-file encodes content for the Secret; you do not need a manual base64 step for this workflow.
Kubernetes cluster chart: with haproxy.tls.enabled=true, either set haproxy.tls.createSecret=true and supply haproxy.tls.pemContent as base64-encoded PEM bytes, or haproxy.tls.createSecret=false and pre-create the Secret (Helm skips templates/haproxy-tls-certs.yaml when createSecret is false).
OpenShift cluster chart: values.yaml describes pemContent as base64 of the combined PEM. templates/haproxy-tls-certs.yaml creates a Secret when haproxy.tls.enabled is true; confirm your chart revision for external vs Helm-managed PEMs.
Mosquitto server-only TLS in HA (passthrough)
Same server.crt / server.key Secret shape as single node: default name mosquitto-server-tls, keys matching mosquitto.serverOnlyTls.certFile / keyFile.
HA cluster: TLS termination at HAProxy (typical production choice)
Goal: clients use TLS to HAProxy 8883; HAProxy uses plain MQTT to brokers 1888.
- Build
haproxy_combined.pemand createhaproxy-tls-certs(or your configured names). - Set
haproxy.tls.enabled=true,mosquitto.serverOnlyTls.enabled=false. - Set
haproxy.proxyProtocol.enabled=trueandhaproxy.proxyProtocol.mode=tls-server(ortls-mtls/tls-mtls-cnif applicable).
Kubernetes
NAMESPACE="your-namespace"
helm upgrade --install mosquitto-ha ./mosquitto-3.2-platform-3.2-kubernetes-cluster \
-n $NAMESPACE \
-f values.yaml \
--set haproxy.tls.enabled=true \
--set haproxy.tls.createSecret=false \
--set haproxy.proxyProtocol.enabled=true \
--set haproxy.proxyProtocol.mode=tls-server
OpenShift
NAMESPACE="your-namespace"
helm upgrade --install mosquitto-ha ./mosquitto-3.2-platform-3.2-openshift-cluster \
-n $NAMESPACE \
-f values.yaml \
--set haproxy.tls.enabled=true \
--set haproxy.proxyProtocol.enabled=true \
--set haproxy.proxyProtocol.mode=tls-server
The OpenShift cluster chart’s values.yaml does not document haproxy.tls.createSecret the same way as the Kubernetes cluster chart; check templates/haproxy-tls-certs.yaml in your revision for whether Helm always creates the HAProxy TLS Secret when haproxy.tls.enabled is true. Supply haproxy.tls.pemContent (base64 PEM) in values if you rely on chart-managed secrets, or follow your platform team’s pattern for external PEMs.
Optional (Helm-managed HAProxy secret, Kubernetes chart): haproxy.tls.createSecret=true and set haproxy.tls.pemContent to the base64 of haproxy_combined.pem. GNU: base64 -w0 < haproxy_combined.pem; macOS: base64 < haproxy_combined.pem | tr -d '\n'.
HA cluster: TLS termination on Mosquitto (server-only TLS + HAProxy passthrough)
Goal: clients negotiate TLS with Mosquitto; HAProxy only forwards TCP to 8883.
- Create
mosquitto-server-tlswithserver.crtandserver.key(see Secret creation). - Set
mosquitto.serverOnlyTls.enabled=true,mosquitto.serverOnlyTls.createSecret=falsewhen using an external secret. - Set
haproxy.tls.enabled=false(recommended). - Set
haproxy.proxyProtocol.enabled=false.
After install or upgrade, restart HAProxy so pods load the updated ConfigMap:
kubectl rollout restart deployment haproxy -n $NAMESPACE
Verify
kubectl exec mosquitto-0 -n $NAMESPACE -- ls -la /mosquitto/certs/
kubectl exec mosquitto-0 -n $NAMESPACE -- grep -A 5 "listener.*8883" /mosquitto/config/mosquitto.conf
mosquitto_sub -h <haproxy-external-ip> -p 8883 --cafile ca.crt -u <user> -P <pass> -t '#'
Updating TLS configuration
Server-only TLS (single node, or HA with Mosquitto TLS)
Kubernetes
kubectl create secret generic mosquitto-server-tls \
--from-file=server.crt=server.crt \
--from-file=server.key=server.key \
-n $NAMESPACE \
--dry-run=client -o yaml | kubectl apply -f -
kubectl rollout restart statefulset mosquitto -n $NAMESPACE
For HA with serverOnlyTls, also restart HAProxy after broker certs change:
kubectl rollout restart deployment haproxy -n $NAMESPACE
OpenShift
oc create secret generic mosquitto-server-tls \
--from-file=server.crt=server.crt \
--from-file=server.key=server.key \
-n $NAMESPACE \
--dry-run=client -o yaml | oc apply -f -
oc rollout restart statefulset mosquitto -n $NAMESPACE
oc rollout restart deployment haproxy -n $NAMESPACE
(omit the HAProxy line on single node.)
HA cluster (HAProxy TLS termination)
Kubernetes
kubectl create secret generic haproxy-tls-certs \
--from-file=haproxy_combined.pem=./haproxy_combined.pem \
-n $NAMESPACE \
--dry-run=client -o yaml | kubectl apply -f -
kubectl rollout restart deployment haproxy -n $NAMESPACE
OpenShift
oc create secret generic haproxy-tls-certs \
--from-file=haproxy_combined.pem=./haproxy_combined.pem \
-n $NAMESPACE \
--dry-run=client -o yaml | oc apply -f -
oc rollout restart deployment haproxy -n $NAMESPACE
Troubleshooting
Single node
Connection refused on port 8883
- Confirm
mosquitto.serverOnlyTls.enabled=true. - Check the Service exposes 8883:
kubectl get svc mosquitto -n $NAMESPACE. - Confirm mounts:
kubectl exec mosquitto-0 -n $NAMESPACE -- ls -la /mosquitto/certs.
Certificate validation errors
- Certificate SAN/CN must match the hostname or IP clients use.
- Pass
--cafilewith the issuing CA if it is not in the client trust store.
HA cluster
Connection refused on 8883 (via HAProxy)
- At least one of
haproxy.tls.enabled,mosquitto.serverOnlyTls.enabled, ormosquitto.mtls.enabledmust be true for the secure Service port. kubectl get svc haproxy -n $NAMESPACE
Helm template errors
serverOnlyTls/mtlswithhaproxy.proxyProtocol.enabled=true→ sethaproxy.proxyProtocol.enabled=false.haproxy.tls.enabledonly withproxyProtocol.mode=direct→ set mode totls-server(or mtls variants).
Invalid PEM at HAProxy
- Concatenate certificate first, then key.
- Secret key name must match
haproxy.tls.pemFile.
HAProxy pod errors
kubectl logs deployment/haproxy -n $NAMESPACE- Missing or malformed combined PEM is a common cause.
External secret missing
- With
createSecret: false, create Secrets beforehelm install/helm upgradewhen chartvalidateSecretsis enabled.
Security best practices
- Use strong certificates from a trusted CA or a controlled self-signed setup.
- Never commit private keys or raw
keyContent/pemContentto version control. - Rotate certificates before expiry; automate expiry monitoring where possible.
- Store material in Kubernetes/OpenShift Secrets (or a secrets manager that syncs to Secrets).
- Restrict Secret access with RBAC.
- For HA with HAProxy TLS, in-cluster traffic from HAProxy to Mosquitto is plain MQTT on the cluster network; for end-to-end TLS to the broker, use
mosquitto.serverOnlyTlswith HAProxy passthrough and accept broker-side cert management and CPU cost.