This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Anonymous Access
Relevant source files
This document explains the anonymous access configuration in the Mosquitto MQTT broker, including its implementation, security implications, and appropriate use cases. Anonymous access allows any MQTT client that can reach the broker to connect and publish/subscribe to any topic without authentication credentials.
For information about implementing authentication and topic-based access control, see Topic Access Control (ACL)). For the broader security architecture of the system, see Security Model.
Configuration Overview
The Mosquitto broker is configured to allow anonymous access through a single directive in the configuration file. This setting controls whether clients can connect without providing authentication credentials.
Configuration Location
The anonymous access setting is defined in mosquitto.conf2:
allow_anonymous true
This directive applies globally to all listeners defined in the configuration file. In this system, anonymous access affects both the standard MQTT listener on port 1883 and the WebSocket listener on port 9001 (see MQTT Listeners for details on these listeners).
Sources: mosquitto.conf
How Anonymous Access Works
Anonymous Access Connection Flow
When allow_anonymous true is set, the Mosquitto broker accepts MQTT CONNECT packets regardless of whether they contain username/password credentials. The broker does not perform any authentication checks and immediately grants access to all MQTT operations.
Sources: mosquitto.conf, README.md
Access Permissions
Unrestricted Topic Access
| Permission Type | Anonymous Client Capabilities |
|---|---|
| SUBSCRIBE | Can subscribe to any topic, including wildcards (#, +) |
| PUBLISH | Can publish to any topic |
| RETAIN | Can set retained messages on any topic |
| QoS Levels | Full access to QoS 0, 1, and 2 |
| Topic Restrictions | None - all topics accessible |
With anonymous access enabled and no ACL (Access Control List) file configured, clients have complete freedom to:
- Subscribe to any topic pattern, including global wildcards like
# - Publish messages to any topic
- Set and clear retained messages
- Access all Quality of Service (QoS) levels
No Authentication Layer
graph TB
Client["External MQTT Client"]
CF["cloudflared Container"]
Mosquitto["mosquitto Container"]
subgraph "Authentication Check"
CheckAnon["allow_anonymous: true"]
NoAuth["No Credential Validation"]
end
Client -->|MQTT CONNECT| CF
CF -->|Proxy to mosquitto:9001| Mosquitto
Mosquitto --> CheckAnon
CheckAnon --> NoAuth
NoAuth -->|CONNACK Success| Mosquitto
Mosquitto -->|Success| CF
CF -->|Success| Client
Note1["No username check"]
Note2["No password check"]
Note3["No ACL evaluation"]
NoAuth -.-> Note1
NoAuth -.-> Note2
NoAuth -.-> Note3
The system flow shows that no authentication validation occurs:
Sources: mosquitto.conf
Security Implications
Trust Boundary Analysis
The security model for this configuration relies entirely on network-level access control rather than application-level authentication:
| Security Layer | Protection Provided | Configuration |
|---|---|---|
| Cloudflare Edge | DDoS protection, traffic filtering | Cloudflare Dashboard |
| Cloudflare Tunnel | Encrypted transport, no inbound ports | CLOUDFLARE_TUNNEL_TOKEN |
| Docker Network | Internal isolation between containers | docker-compose.yml |
| Mosquitto Authentication | None - anonymous access enabled | allow_anonymous: true |
Sources: mosquitto.conf, README.md
Threat Model Considerations
What Anonymous Access Protects Against:
- Direct internet exposure (mitigated by Cloudflare Tunnel)
- Port scanning and direct connection attempts (no inbound firewall rules required)
- DDoS attacks at the network level (handled by Cloudflare Edge)
What Anonymous Access Does NOT Protect Against:
- Unauthorized message publication by any client that reaches the broker
- Eavesdropping on topics by any connected client
- Malicious clients subscribing to all topics using
#wildcard - Topic flooding or message spam from authenticated clients
- Multi-tenant isolation (all clients can access all topics)
Sources: README.md
Appropriate Use Cases
When Anonymous Access Is Suitable
Anonymous access is appropriate in the following scenarios:
| Scenario | Rationale |
|---|---|
| Single-User Systems | One person controls all MQTT clients and traffic |
| Private/Home Networks | Network-level security already restricts access |
| Trusted Development Environments | Quick setup for testing without credential management |
| Internal IoT Networks | All devices within a trusted network boundary |
| Proof-of-Concept Deployments | Rapid prototyping without authentication complexity |
When Authentication Is Required
Authentication should be implemented when:
- Multiple users need isolated topic spaces
- Different clients require different permission levels
- Production deployments with untrusted client access
- Compliance or audit requirements mandate access control
- Topic-level security policies need enforcement
For these scenarios, see the alternative implementation in the [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/protected-no-wildcard branch) which provides username/password authentication and ACL-based topic restrictions. Detailed documentation is available at Topic Access Control (ACL)).
Sources: README.md
Configuration File Structure
The complete Mosquitto configuration that enables anonymous access:
listener 1883
allow_anonymous true
listener 9001
protocol websockets
Configuration Analysis
| Line | Directive | Effect |
|---|---|---|
| 1 | listener 1883 | Defines standard MQTT listener |
| 2 | allow_anonymous true | Enables anonymous access globally |
| 3 | (blank) | |
| 4 | listener 9001 | Defines WebSocket listener |
| 5 | protocol websockets | Specifies WebSocket protocol for listener on 9001 |
The allow_anonymous true directive on line 2 applies to both listeners. There is no ACL file specified, no password file, and no per-listener authentication override. This creates a uniform anonymous access policy across all connection methods.
File Location: mosquitto.conf:1-6
Sources: mosquitto.conf
Relationship to System Components
Container Configuration
The mosquitto service in docker-compose.yml mounts the configuration file as a volume:
This volume mount makes the allow_anonymous true setting effective when the container starts. The Mosquitto process reads this configuration file on startup and applies the anonymous access policy to all listeners.
Sources: mosquitto.conf, docker-compose.yml (referenced in diagrams)
Comparison with Protected Configuration
The main branch uses anonymous access for simplicity. An alternative implementation exists in the [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/protected-no-wildcard branch) that demonstrates restricted access patterns.
Configuration Differences
| Aspect | Main Branch (Anonymous) | Protected-No-Wildcard Branch |
|---|---|---|
| Authentication | None required | Username/password required |
| Topic Access | Unrestricted | ACL file with per-user restrictions |
| Wildcard Subscriptions | Fully allowed | Restricted by ACL rules |
| Configuration Complexity | Minimal (6 lines) | Additional ACL file management |
| Use Case | Trusted environments | Multi-tenant or production systems |
The protected branch adds:
- An ACL file that restricts topic access by username
- Password file for credential validation
- Topic-level permissions enforcement
- Encryption for retained messages using gocryptfs
For details on implementing authentication and topic restrictions, see Topic Access Control (ACL)).
Sources: README.md
Testing Anonymous Access
The CI/CD pipeline validates that the Mosquitto broker starts successfully with anonymous access enabled. The health check in .github/workflows/ci.yml verifies the container reaches a running state but does not test authentication behavior since none is required.
Testing Approach
To manually verify anonymous access behavior:
- Start the services:
docker compose up - Connect any MQTT client to the public hostname configured in Cloudflare
- Attempt to connect without providing credentials
- Verify successful connection and message publication
No username or password should be required for successful connection and full MQTT operation.
Sources: .github/workflows/ci.yml (referenced), README.md
Migration Path to Authentication
If anonymous access proves insufficient for security requirements, the system can be migrated to authenticated access by:
- Creating a password file with
mosquitto_passwdcommand - Adding
password_file /path/to/password_filedirective to mosquitto.conf - Removing or changing
allow_anonymous truetoallow_anonymous false - Optionally adding an ACL file for topic-level restrictions
- Updating client code to provide credentials in CONNECT packets
The [protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/protected-no-wildcard branch) provides a complete reference implementation. View the [configuration differences](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/8a829fda/configuration differences) to understand required changes.
For production deployments requiring authentication, see Production Considerations and Topic Access Control (ACL)).
Sources: README.md