Skip to content
Stand with Ukraine flag

MQTTS (MQTT over TLS)

TBMQ supports running the MQTT server and MQTT over WebSocket over SSL. Both one-way and two-way SSL are supported.

Most TBMQ environments use the load balancer as a termination point for the SSL connection between the devices and the broker. In other words, MQTT traffic is encrypted between the device and the load balancer but is decrypted between the load balancer and broker services. The advantage of such an option is minimal configuration overhead. Most cloud load balancers (AWS, Google Cloud, etc.) have built-in certificate generation tools and rich documentation on how to configure SSL over TCP. The disadvantage of such an option is that two-way SSL is not possible. The information about the client certificate is not passed from the load balancer to the broker services.

Nevertheless, it is possible to configure TBMQ for two-way SSL for MQTT and avoid SSL termination on the load balancer. Use valid SSL certificates from trusted CA authorities. Avoid spending time resolving issues with self-signed certificates. See the instructions below on how to configure SSL for certificates stored in PEM file format or Java Keystore.

Configure the following environment variables via the configuration file, docker-compose, or Kubernetes scripts.

Terminal window
export LISTENER_SSL_ENABLED=true
export LISTENER_SSL_CREDENTIALS_TYPE=PEM
export LISTENER_SSL_PEM_CERT=server.pem
export LISTENER_SSL_PEM_KEY=server_key.pem
export LISTENER_SSL_PEM_KEY_PASSWORD=secret

Where:

  • LISTENER_SSL_ENABLED — Enable/disable SSL support.
  • LISTENER_SSL_CREDENTIALS_TYPE — Server credentials type. PEM — PEM certificate file; KEYSTORE — Java keystore.
  • LISTENER_SSL_PEM_CERT — Path to the server certificate file. Holds server certificate or certificate chain; may also include the server private key.
  • LISTENER_SSL_PEM_KEY — Path to the server certificate private key file. Optional by default; required if the private key is not present in the server certificate file.
  • LISTENER_SSL_PEM_KEY_PASSWORD — Optional server certificate private key password.

After completing the setup, start or restart the TBMQ server.

Configure the following environment variables via the configuration file, docker-compose, or Kubernetes scripts.

Terminal window
export LISTENER_SSL_ENABLED=true
export LISTENER_SSL_CREDENTIALS_TYPE=KEYSTORE
export LISTENER_SSL_KEY_STORE_TYPE=PKCS12
export LISTENER_SSL_KEY_STORE=keystore.p12
export LISTENER_SSL_KEY_STORE_PASSWORD=tbmq
export LISTENER_SSL_KEY_PASSWORD=tbmq

Where:

  • LISTENER_SSL_ENABLED — Enable/disable SSL support.
  • LISTENER_SSL_CREDENTIALS_TYPE — Server credentials type. PEM — PEM certificate file; KEYSTORE — Java keystore.
  • LISTENER_SSL_KEY_STORE_TYPE — Type of the key store (JKS or PKCS12).
  • LISTENER_SSL_KEY_STORE — Path to the key store that holds the SSL certificate or certificate chain; also includes the server private key.
  • LISTENER_SSL_KEY_STORE_PASSWORD — Password used to access the key store.
  • LISTENER_SSL_KEY_PASSWORD — Password used to access the server private key.

After completing the setup, start or restart the TBMQ server.

You may configure the following additional environment variables via the configuration file, docker-compose, or Kubernetes scripts.

  • LISTENER_SSL_BIND_ADDRESS — The bind address for the MQTT server. Default value 0.0.0.0 indicates all interfaces.
  • LISTENER_SSL_BIND_PORT — The bind port for the MQTT server. Default value is 8883.
  • LISTENER_SSL_PROTOCOL — SSL protocol name. Default value is TLSv1.2. See the Java documentation for more details.

Use the instructions below to generate your own certificate files. Useful for tests, but time-consuming and not recommended for production.

You need to either create a self-signed certificate for the server or follow the advanced steps to create a CA-signed server certificate. Both methods achieve the same goal: securing your server with a valid certificate.

This method has the server generate and sign its own certificate. Useful for basic testing or small setups where you don’t need a Certificate Authority (CA).

To generate a server self-signed PEM certificate and private key:

Terminal window
openssl ecparam -out server_key.pem -name secp256r1 -genkey
openssl req -new -key server_key.pem -x509 -nodes -days 365 -out server.pem

You can add -nodes if you don’t want to protect your private key with a passphrase. Otherwise, it will prompt you for a password of at least 4 characters.

The days parameter (365) can be replaced with any number to affect the expiration date. You will then be prompted for certificate details such as “Country Name” — you can press Enter to accept the defaults.

Add -subj '/CN=localhost' to suppress questions about the certificate contents (replace localhost with your desired domain).

Self-signed certificates are not validated with any third party unless you import them to browsers previously. If you need more security, use a certificate signed by a certificate authority (CA).

Certificate PEM file signed by a Certificate Authority (CA)

Section titled “Certificate PEM file signed by a Certificate Authority (CA)”

This method creates a Certificate Authority (CA) to sign your server certificate — useful for more secure setups, particularly if you plan to manage multiple certificates or require a dedicated CA for signing.

Generate a CA private key:

Terminal window
openssl ecparam -out ca_key.pem -name secp256r1 -genkey

Generate a self-signed CA certificate:

Terminal window
openssl req -new -x509 -key ca_key.pem -days 365 -out ca.pem

This creates a self-signed CA certificate ca.pem valid for 365 days. When prompted, fill out the certificate details (e.g., Common Name: My Root CA).

Generate a private key for the server:

Terminal window
openssl ecparam -out server_key.pem -name secp256r1 -genkey

Create a Certificate Signing Request (CSR):

Terminal window
openssl req -new -key server_key.pem -out server.csr

Sign the server certificate using the CA:

Terminal window
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca_key.pem -CAcreateserial -out server.pem -days 365

The -CAcreateserial flag automatically generates a serial number file ca.srl. If you don’t want to generate this file, replace -CAcreateserial with -set_serial <serial_number>.

To achieve this, create a certificate chain by concatenating the server certificate and the CA certificate:

Terminal window
cat server.pem ca.pem > serverChain.pem

The resulting serverChain.pem file should then be configured in TBMQ by setting the following environment variable:

Terminal window
LISTENER_SSL_PEM_CERT=serverChain.pem

This ensures that both the server certificate and the CA certificate are properly recognized, enabling secure mutual authentication when client certificates are used.

In Java-based applications, a truststore is a special keystore that contains certificates of entities (Certificate Authorities or servers) that the application trusts. Adding a certificate to the truststore ensures that Java applications running with that truststore will accept SSL/TLS connections signed by that certificate or its issuing CA.

Terminal window
keytool -importcert -file CERT.pem -alias ALIAS -keystore keystore.p12 -storepass KEYSTOREPASS

Parameters:

  • -importcert — imports a certificate into the specified keystore/truststore.
  • -file CERT.pem — the path to the certificate file you want to import.
  • -alias ALIAS — a unique name to reference this certificate within the keystore.
  • -keystore keystore.p12 — the Java keystore/truststore file (.jks or .p12) to which the certificate will be added. Created if it doesn’t exist.
  • -storepass KEYSTOREPASS — the password protecting the keystore.

Make sure you have the following files:

  • server.pem — the public certificate (may include the chain).
  • server_key.pem — the private key.
  • ca.pem — root or intermediate CA certificates (optional).

Run the following command to create a PKCS12 keystore file (keystore.p12):

Terminal window
openssl pkcs12 -export \
-in server.pem \
-inkey server_key.pem \
-certfile ca.pem \
-out keystore.p12 \
-name tbmq \
-passout pass:changeit

The -certfile ca.pem line is optional — include it if you have a CA certificate chain. Replace changeit with your desired keystore password; you will reference this in your environment variables.

Tips and best practices:

  • For production use, PKCS12 (.p12) format is recommended as it is more interoperable than JKS.
  • Make sure your certificate chain is complete (including intermediates) when exporting.

To enable secure MQTT over WebSockets (WSS), follow the same SSL configuration steps described above. Use the corresponding WebSocket-specific environment variables (e.g., LISTENER_WSS_ENABLED, LISTENER_WSS_CREDENTIALS_TYPE, etc.) in your configuration file, Docker Compose, or Kubernetes manifests.

The SSL setup using PEM or Keystore works identically for both raw MQTT over TLS and WebSocket over TLS endpoints.