Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

MQTT Listeners

Relevant source files

Purpose and Scope

This document describes the MQTT listener configuration in the Mosquitto broker, specifically the two listeners defined in mosquitto.conf:1-6 It explains the purpose, protocol, and routing behavior of each listener. For broader Mosquitto broker configuration, see Mosquitto Configuration. For access control settings, see Anonymous Access. For Cloudflare tunnel routing configuration, see Cloudflared Tunnel Service.

Sources : mosquitto.conf, README.md


Listener Configuration Overview

The Mosquitto broker is configured with two distinct listeners, each serving different transport protocols and use cases. Both listeners are defined in mosquitto.conf:1-6 and operate simultaneously within the mosquitto container.

Listener Configuration Structure

ListenerPortProtocolAnonymous AccessPrimary Use Case
mosquitto.conf11883Standard MQTT/TCPEnabled globally mosquitto.conf2Direct MQTT client connections
mosquitto.conf:4-59001MQTT over WebSocketsEnabled globally mosquitto.conf2Browser-based clients, Cloudflare tunnel

Sources : mosquitto.conf


Listener 1883: Standard MQTT TCP

The first listener, configured at mosquitto.conf1 binds to port 1883 and provides standard MQTT protocol over TCP. This is the default MQTT port and is used by most native MQTT client libraries.

Configuration Directives

listener 1883
allow_anonymous true

Directive Breakdown :

  • listener 1883 mosquitto.conf1: Binds the Mosquitto broker to TCP port 1883
  • allow_anonymous true mosquitto.conf2: Applies globally to all listeners, allowing clients to connect without authentication

Protocol Characteristics

This listener implements the standard MQTT 3.1.1 and MQTT 5.0 protocols over raw TCP connections. It supports:

  • Binary MQTT protocol framing
  • Persistent TCP connections
  • Quality of Service (QoS) levels 0, 1, and 2
  • Last Will and Testament (LWT) messages
  • Retained messages

Network Accessibility

The 1883 listener is not directly exposed through the Cloudflare tunnel in the current configuration. It operates only within Docker's internal network, accessible to other containers in the same Docker Compose stack.

Sources : mosquitto.conf, README.md

graph LR
    subgraph "Docker Internal Network"
        OtherContainer["Other Docker Container"]
MosquittoPort1883["mosquitto:1883\nTCP Listener"]
end
    
    subgraph "External Network"
        Internet["Public Internet"]
end
    
 
   OtherContainer -->|Direct MQTT/TCP| MosquittoPort1883
 
   Internet -.->|Not Accessible| MosquittoPort1883

Listener 9001: MQTT over WebSockets

The second listener, configured at mosquitto.conf:4-5 binds to port 9001 and provides MQTT protocol encapsulated over WebSockets. This is the primary listener exposed to external clients via the Cloudflare tunnel.

Configuration Directives

listener 9001
protocol websockets

Directive Breakdown :

  • listener 9001 mosquitto.conf4: Binds the Mosquitto broker to TCP port 9001
  • protocol websockets mosquitto.conf5: Configures this listener to accept WebSocket connections with MQTT payloads

Protocol Characteristics

This listener encapsulates MQTT protocol messages within WebSocket frames, enabling:

  • HTTP/WebSocket upgrade handshake
  • Browser-based MQTT clients (JavaScript)
  • Compatibility with web proxies and CDNs
  • TLS/SSL termination at the proxy layer (Cloudflare)

The WebSocket protocol wrapper does not alter the MQTT protocol itself; it only provides an HTTP-compatible transport layer.

Cloudflare Tunnel Routing

The 9001 listener is configured as the target for the Cloudflare tunnel in the Zero Trust dashboard. The tunnel configuration specifies mosquitto:9001 as the service URL README.md62 routing external MQTT WebSocket connections through the cloudflared container to this listener.

sequenceDiagram
    participant Client as "External MQTT Client"
    participant CFEdge as "Cloudflare Edge"
    participant Cloudflared as "cloudflared Container"
    participant Mosquitto9001 as "mosquitto:9001\nWebSocket Listener"
    participant MosqConf as "mosquitto.conf"
    
    Note over Client: Initiates MQTT over WebSocket
    Client->>CFEdge: WebSocket Upgrade Request\nto public hostname
    CFEdge->>Cloudflared: Route through encrypted tunnel
    Cloudflared->>Mosquitto9001: HTTP proxy to mosquitto:9001
    
    Mosquitto9001->>MosqConf: Check listener configuration
    Note over MosqConf: listener 9001\nprotocol websockets\nallow_anonymous true
    MosqConf-->>Mosquitto9001: Accept WebSocket connection
    
    Mosquitto9001-->>Cloudflared: WebSocket established
    Cloudflared-->>CFEdge: Through tunnel
    CFEdge-->>Client: WebSocket connection established
    
    Note over Client,Mosquitto9001: MQTT messages flow over WebSocket

Network Accessibility

Unlike the 1883 listener, the 9001 listener is indirectly exposed to the public internet through the Cloudflare tunnel. The routing path is:

  1. External client connects to Cloudflare public hostname
  2. Cloudflare Edge routes to cloudflared container via tunnel
  3. cloudflared proxies HTTP traffic to mosquitto:9001
  4. Mosquitto 9001 listener accepts WebSocket connection

Sources : mosquitto.conf, README.md


graph TB
    subgraph "External Access"
        PublicClient["MQTT WebSocket Client\nBrowser/JS Library"]
PublicHostname["Public Hostname\nConfigured in CF Dashboard"]
end
    
    subgraph "Cloudflare Infrastructure"
        CFEdge["Cloudflare Edge Network"]
CFTunnel["Cloudflare Tunnel\nEncrypted Connection"]
end
    
    subgraph "Docker Host"
        subgraph "cloudflared Container"
            CFD["cloudflared process"]
Proxy["HTTP Proxy"]
end
        
        subgraph "mosquitto Container"
            MosqBroker["Mosquitto Broker"]
L1883["Listener 1883\nprotocol: MQTT/TCP"]
L9001["Listener 9001\nprotocol: websockets"]
end
        
        subgraph "Docker Internal Network"
            InternalClient["Internal Container\nDirect MQTT Client"]
end
    end
    
 
   PublicClient -->|MQTT over WS| PublicHostname
 
   PublicHostname --> CFEdge
 
   CFEdge -->|Encrypted Tunnel| CFTunnel
 
   CFTunnel --> CFD
 
   CFD --> Proxy
 
   Proxy -->|mosquitto:9001| L9001
    
 
   L9001 --> MosqBroker
 
   L1883 --> MosqBroker
    
 
   InternalClient -->|mosquitto:1883 Direct TCP| L1883
    
    style L9001 fill:#e1f5ff
    style L1883 fill:#fff3e1

Traffic Routing Architecture

The following diagram illustrates how traffic is routed to each listener based on the source and transport protocol:

Routing Configuration References :

Sources : mosquitto.conf, README.md


Configuration Reference

Listener Directive Syntax

The listener directive defines a network interface and port for the broker to bind to:

listener <port> [bind_address]

Current Configuration :

  • mosquitto.conf1: listener 1883 - Binds to port 1883 on all interfaces (no bind_address specified)
  • mosquitto.conf4: listener 9001 - Binds to port 9001 on all interfaces

Protocol Directive

The protocol directive specifies the transport protocol for a listener:

protocol <mqtt|websockets>

Current Configuration :

  • Listener 1883: No protocol directive (defaults to mqtt)
  • mosquitto.conf5: protocol websockets - Configures listener 9001 for WebSocket transport

Anonymous Access Directive

The allow_anonymous directive controls whether clients can connect without authentication:

allow_anonymous <true|false>

Current Configuration :

  • mosquitto.conf2: allow_anonymous true - Applies globally to all listeners

This directive appears once and affects both listeners. For production deployments requiring authentication, this should be set to false and appropriate authentication mechanisms configured. See Anonymous Access for detailed security implications.

Configuration Interaction Matrix

Configuration AspectListener 1883Listener 9001
Port1883 mosquitto.conf19001 mosquitto.conf4
ProtocolMQTT/TCP (implicit default)WebSockets mosquitto.conf5
Anonymous AccessEnabled mosquitto.conf2Enabled mosquitto.conf2
Cloudflare RoutingNot configuredConfigured README.md62
External AccessibilityDocker internal onlyVia Cloudflare tunnel

Sources : mosquitto.conf, README.md


Use Case Selection

When to Use Listener 1883 (TCP)

  • Native MQTT client libraries : Python Paho, Mosquitto C library, MQTT.js with TCP
  • High-performance IoT devices : Minimal protocol overhead
  • Internal Docker services : Direct container-to-container communication
  • Legacy MQTT applications : Standard MQTT port compatibility

When to Use Listener 9001 (WebSockets)

  • Browser-based clients : JavaScript MQTT clients in web applications
  • Cloudflare tunnel access : External clients connecting via the public hostname
  • Firewall-restricted networks : HTTP/WebSocket traffic often allowed through corporate firewalls
  • CDN/proxy compatibility : Works with HTTP-based reverse proxies

Current System Configuration

The current deployment configures the Cloudflare tunnel to route exclusively to listener 9001. This means:

  • External clients must use MQTT over WebSockets
  • The public hostname README.md60 resolves to listener 9001
  • Listener 1883 remains available only for internal Docker network access

To expose listener 1883 externally, additional Cloudflare tunnel configuration would be required, though this is uncommon since WebSocket transport provides broader compatibility.

Sources : mosquitto.conf, README.md