TroutTrout

Configure MQTT flows

Secure MQTT on an OT network with Access Gate, default-deny on port 1883, identity-scoped enclaves, topic-level control, and TLS for a broker that ships with no auth or encryption.

6 min read · Last updated 2026-07-08

MQTT is a lightweight publish/subscribe protocol used across IoT and OT for telemetry and commands: clients publish messages to topics on a broker, and other clients subscribe to those topics. It is simple and efficient, which is also its security problem. A default broker often runs with no authentication, no encryption, and no topic access control, so anything that can reach it can read every topic or publish a rogue command to a control topic. Access Gate puts identity, policy, and encryption in front of the broker so only sanctioned clients exchange MQTT messages.

What You Get

  • Default-deny on 1883. Nothing reaches the broker's MQTT port unless an explicit ACL rule allows it. That alone removes the "any host on the network can connect and publish" exposure.
  • Identity-scoped access. MQTT flows are usually machine-to-machine, a publisher pushing telemetry and a broker fanning it out. Grants are written between assets, so only the sanctioned client reaches the broker, and nothing else does.
  • TLS for a protocol that has none. MQTT on 1883 is plaintext. The gate wraps the session in TLS between the client and itself, then forwards to the broker over the protected segment, so traffic is encrypted in transit and the client device needs no broker-side crypto changes.

Why the default broker is exposed

In this example the broker is Eclipse Mosquitto 2.0.18 on Linux, with a minimal lab configuration:

# /etc/mosquitto/conf.d/lab.conf
listener 1883 0.0.0.0   # MQTT on the standard port 1883, bound to all interfaces
allow_anonymous true    # no authentication: any client can connect, publish, and subscribe

Left as-is, that broker carries several risks:

  • No authentication. With allow_anonymous true, anyone on the network can connect, publish, and subscribe with no username or password.
  • No TLS. Traffic on 1883 is plaintext, so credentials and telemetry are sniffable and the session can be tampered with in transit (MITM).
  • No topic ACLs. Any client can subscribe to everything, or publish to a control topic, for example to spoof a PLC setpoint.
  • Message injection and replay. Forged or replayed commands to actuators translate into physical-world impact in OT.
  • Denial of service. Retained-message flooding and connection exhaustion can take the broker down.
  • Broker exposure. With 1883 bound to 0.0.0.0, the broker is reachable off-segment whenever the network is not strictly isolated.

Set It Up

  1. Register the broker as an asset and set its protocol to MQTT.

    Registering the MQTT broker as an asset
    Registering the MQTT broker as an asset
  2. Add the broker to an enclave, see Protecting an asset with enclaves, then add an allow rule for the mqtt protocol scoped to the specific client that should reach it. This wraps an enclave around the MQTT flows.

    An enclave scoped around the MQTT flows
    An enclave scoped around the MQTT flows

At this point the broker is no longer wide open: the gate enforces the identity of the client and the access control rules on the flow.

Worked Example: Securing a Client-to-Broker Flow

The images below trace a message published from a client to the broker through the Access Gate. The enclave is configured so only that client can reach the broker, nothing else on the network can.

First level of security: adding authentication and access control

From the client, we publish a message to the topic. The gate allows the sanctioned client through, and the broker receives it.

Publishing a message to the broker
Publishing a message to the broker
The broker receiving the published message
The broker receiving the published message

Second level of security: adding TLS encryption

Head to the enclave, turn on TLS, and install the certificate on the client device. The gate now maintains a TLS tunnel between the client and the broker, so the same flow travels encrypted.

Publishing an encrypted message to the broker
Publishing an encrypted message to the broker
The broker receiving the encrypted message
The broker receiving the encrypted message

How the encrypted session is established

It helps to see the encrypted publish as three layers, established in order:

  1. Socket (TCP). The client opens a TCP connection to the gate on port 1883. This is just a reliable byte pipe: it carries whatever is put into it.
  2. TLS. Right after the socket opens, a TLS handshake runs inside it. The proxy presents its certificate chain, the client verifies it against its own certificate (the Access Gate one here) and checks that the hostname matches the certificate's SAN (mqtt-broker.bluelab.secure). Both sides then derive keys, and everything after this is encrypted.
  3. Message (MQTT). Only once TLS is up does MQTT run through the encrypted channel: CONNECT, the broker replies CONNACK (0) (accepted), then PUBLISH your payload to the topic plant/line1/cmd, then DISCONNECT. Exit code 0 means all three layers completed.

So TCP is the pipe, TLS is the encrypted envelope around the pipe, and MQTT is the actual conversation carried inside the envelope. The proxy's job is to refuse anything that is not wrapped in the TLS envelope.

Notes & Gotchas

  • Don't break the flow. Before enforcing, observe real MQTT traffic so you know which clients legitimately publish or subscribe.
  • Topics are the real surface. Reachability is the first control, but the damage in MQTT is done at the topic level. Scope grants to the specific clients that own a control topic so a compromised sensor cannot publish to it.
  • Store the certificate. Keep the client certificate in the device certificate store rather than passing --cafile on each command, so the encrypted flow is the default path.
  • Other OT protocols. The same default-deny, identity-scoped, TLS-wrapped model applies to the other industrial protocols on the network, MQTT is one common starting point, not the only one.

Recap

You registered the broker as an MQTT asset, wrapped an enclave around the MQTT flows with a default-deny rule scoped to the sanctioned client, and turned on TLS so a plaintext protocol travels encrypted without changing the broker. The client authenticates and encrypts against the gate, which enforces policy and forwards to the broker over the protected segment.

Reach for this to lock down an MQTT broker that ships with no authentication, no encryption, and no topic access control, where reachability equals authorization and a single rogue publish can move a physical process.