TCP MQTT transport ignores TLS config, causing plain-text connection to TLS port #82

Closed
opened 2026-10-27 09:32:11 +01:00 by adam · 4 comments
Owner

When connecting to an MQTT broker over standard TCP (transport: tcp) with TLS enabled (tls.enabled: true), the client sends a plain-text MQTT CONNECT packet instead of initiating a TLS handshake. The broker (e.g. Mosquitto v2.0.18) rejects the connection immediately with a protocol error.

Mosquitto broker log:

OpenSSL Error[0]: error:0A00010B:SSL routines::wrong version number
Client <unknown> disconnected: Protocol error.

Root Cause

In _BrokerConnection.connect(), TLS setup is only performed inside the websockets transport branch. The tcp branch has no TLS logic at all:

# repeater/data_acquisition/mqtt_handler.py
if self.transport == "websockets":
    if self.tls and self.tls.get("enabled", True):
        import ssl
        self.client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT)
        self.client.tls_insecure_set(self.tls.get("insecure", False))
        self._tls_verified = True
        protocol = "wss"
    else:
        protocol = "ws"
elif self.transport == "tcp":
    protocol = "mqtt"  # ← TLS is never configured here

Fix

Apply the same TLS setup to the tcp branch:

if self.transport == "websockets":
    if self.tls and self.tls.get("enabled", True):
        import ssl
        self.client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT)
        self.client.tls_insecure_set(self.tls.get("insecure", False))
        self._tls_verified = True
        protocol = "wss"
    else:
        protocol = "ws"
elif self.transport == "tcp":
    if self.tls and self.tls.get("enabled", False):
        import ssl
        self.client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT)
        self.client.tls_insecure_set(self.tls.get("insecure", False))
        self._tls_verified = True
        protocol = "mqtts"
    else:
        protocol = "mqtt"
else:
    raise ValueError(f"Invalid transport '{self.transport}' for {self.broker['name']}")

Steps to Reproduce

  1. Configure a broker entry in mqtt_brokers with transport: tcp, port: 8883, and tls: { enabled: true }
  2. Point it at a standard Mosquitto broker with TLS enabled on port 8883
  3. Observe the wrong version number OpenSSL error on the broker and a failed connection on the client

Environment

  • Branch: fix-perfom-speed
  • Affected file: repeater/data_acquisition/mqtt_handler.py
  • Broker tested: Mosquitto v2.0.18
When connecting to an MQTT broker over standard TCP (`transport: tcp`) with TLS enabled (`tls.enabled: true`), the client sends a **plain-text MQTT CONNECT** packet instead of initiating a TLS handshake. The broker (e.g. Mosquitto v2.0.18) rejects the connection immediately with a protocol error. **Mosquitto broker log:** ``` OpenSSL Error[0]: error:0A00010B:SSL routines::wrong version number Client <unknown> disconnected: Protocol error. ``` ### Root Cause In `_BrokerConnection.connect()`, TLS setup is only performed inside the `websockets` transport branch. The `tcp` branch has no TLS logic at all: ```python # repeater/data_acquisition/mqtt_handler.py if self.transport == "websockets": if self.tls and self.tls.get("enabled", True): import ssl self.client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT) self.client.tls_insecure_set(self.tls.get("insecure", False)) self._tls_verified = True protocol = "wss" else: protocol = "ws" elif self.transport == "tcp": protocol = "mqtt" # ← TLS is never configured here ``` ### Fix Apply the same TLS setup to the `tcp` branch: ```python if self.transport == "websockets": if self.tls and self.tls.get("enabled", True): import ssl self.client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT) self.client.tls_insecure_set(self.tls.get("insecure", False)) self._tls_verified = True protocol = "wss" else: protocol = "ws" elif self.transport == "tcp": if self.tls and self.tls.get("enabled", False): import ssl self.client.tls_set(cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_TLS_CLIENT) self.client.tls_insecure_set(self.tls.get("insecure", False)) self._tls_verified = True protocol = "mqtts" else: protocol = "mqtt" else: raise ValueError(f"Invalid transport '{self.transport}' for {self.broker['name']}") ``` ### Steps to Reproduce 1. Configure a broker entry in `mqtt_brokers` with `transport: tcp`, `port: 8883`, and `tls: { enabled: true }` 2. Point it at a standard Mosquitto broker with TLS enabled on port 8883 3. Observe the `wrong version number` OpenSSL error on the broker and a failed connection on the client ### Environment - Branch: `fix-perfom-speed` - Affected file: `repeater/data_acquisition/mqtt_handler.py` - Broker tested: Mosquitto v2.0.18 <!-- github-sync-id:4319810347 -->
adam closed this issue 2026-10-27 09:32:11 +01:00
Author
Owner

@Rigear - do you mind looking at this?

@Rigear - do you mind looking at this? <!-- github-comment-id:4311650878 -->
Author
Owner

Can do

Can do <!-- github-comment-id:4313708694 -->
Author
Owner
Should be fixed by https://github.com/rightup/pyMC_Repeater/pull/204 <!-- github-comment-id:4318378077 -->
Author
Owner

Update to R:v1.0.10-dev6 and can confirm #204 fixes the TLS connection issue. My observer is now connected to @kizniche 's CoreScope server and seems to be feeding it. Thanks for such a quick fix!

Update to R:v1.0.10-dev6 and can confirm #204 fixes the TLS connection issue. My observer is now connected to @kizniche 's CoreScope server and seems to be feeding it. Thanks for such a quick fix! <!-- github-comment-id:4319703508 -->
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: adam/pyMC_Repeater#82