This documentation is part of the "Projects with Books" initiative at zenOSmosis.
The source code for this project is available on GitHub.
Advanced Topics
Relevant source files
This page covers advanced configuration options and production-ready features available in the protected-no-wildcard branch of the repository. While the main branch provides a straightforward MQTT broker setup with anonymous access and no encryption, the advanced branch introduces ACL-based topic restrictions, encrypted retained message storage, and additional safeguards for multi-tenant environments.
For step-by-step deployment instructions, see Getting Started. For basic component documentation, see Components. This page focuses on enhanced security features and production considerations not present in the base configuration.
Sources : README.md:5-11
Advanced Branch Overview
The repository maintains two primary branches with different security and feature profiles:
| Feature | main Branch | protected-no-wildcard Branch |
|---|---|---|
| Anonymous Access | Enabled (mosquitto.conf2) | User authentication required |
| Topic Access Control | None | ACL file with user-based restrictions |
| Wildcard Topic Queries | Unrestricted | Restricted to user's own topics |
| Retained Message Storage | Plaintext | Encrypted with gocryptfs |
| Message Persistence | Manual save | Auto-save after every message |
| Use Case | Development, trusted environments | Production, multi-tenant systems |
The protected-no-wildcard branch addresses security concerns in scenarios where:
- Multiple users share a single MQTT broker
- Topic privacy between users must be enforced
- Retained messages contain sensitive data requiring encryption at rest
- Filesystem-level message persistence protection is needed
Sources : README.md:5-11
Architecture Comparison
The following diagram illustrates the architectural differences between the two branches:
Diagram: Main vs Protected Branch Architecture
graph TB
subgraph "main Branch Architecture"
direction TB
MQ_Main["mosquitto Container\n(main branch)"]
Conf_Main["mosquitto.conf\nallow_anonymous: true"]
Data_Main["data/\nPlaintext Storage"]
Conf_Main -->|Configures| MQ_Main
MQ_Main -->|Writes Retained Messages| Data_Main
end
subgraph "protected-no-wildcard Branch Architecture"
direction TB
MQ_Protected["mosquitto Container\n(protected-no-wildcard)"]
Conf_Protected["mosquitto.conf\nallow_anonymous: false\nacl_file /mosquitto/config/aclfile"]
ACL["aclfile\nUser-based Topic Rules"]
Gocryptfs["gocryptfs Container\nEncryption Layer"]
Data_Encrypted["data-encrypted/\nEncrypted Filesystem"]
Data_Decrypted["data/\nDecrypted Mount Point"]
Conf_Protected -->|Configures| MQ_Protected
ACL -->|Restricts Topics| MQ_Protected
MQ_Protected -->|Writes to| Data_Decrypted
Gocryptfs -->|Mounts| Data_Decrypted
Gocryptfs -->|Encrypts to| Data_Encrypted
end
Client_Main["MQTT Client\n(Any)"]
Client_Protected["MQTT Client\n(Authenticated)"]
Client_Main -->|Anonymous Connect| MQ_Main
Client_Protected -->|Username/Password| MQ_Protected
The protected branch introduces two key architectural components not present in the main branch:
- ACL File : Located at mosquitto/aclfile in the protected branch, this file defines user-specific topic access patterns
- Gocryptfs Layer : A separate container that provides transparent encryption for the
data/directory
Sources : README.md:5-11 mosquitto.conf:1-6
Topic Access Control (ACL)
The protected-no-wildcard branch implements an ACL (Access Control List) system that restricts MQTT topic access based on username. The implementation follows a naive but effective pattern where:
- The first level of each topic must match the authenticated username
- Users can only publish and subscribe to topics under their own namespace
- Wildcard subscriptions (
#,+) are restricted to prevent cross-user topic enumeration
Example ACL Pattern :
# User "alice" can only access topics starting with "alice/"
user alice
topic readwrite alice/#
# User "bob" can only access topics starting with "bob/"
user bob
topic readwrite bob/#
This approach prevents a scenario where user alice subscribes to bob/# or # to discover or intercept messages from other users.
For detailed ACL configuration and examples, see Topic Access Control (ACL)).
Sources : README.md7
Encrypted Retained Messages
MQTT retained messages persist on the broker's filesystem and are delivered to new subscribers. In the main branch, these messages are stored in plaintext within the data/ directory. The protected-no-wildcard branch adds filesystem-level encryption using gocryptfs.
Data Flow with Encryption :
The encryption operates transparently to Mosquitto. The broker reads and writes to data/ as if it were a normal directory, while gocryptfs handles encryption/decryption automatically. The actual encrypted data resides in data-encrypted/, which is stored on the Docker host filesystem.
Key characteristics:
- Algorithm : AES-256-GCM authenticated encryption
- Scope : Encrypts retained messages only (not in-flight messages)
- Performance : Minimal overhead for typical MQTT workloads
- Recovery : Requires the encryption password to mount the filesystem
For implementation details and configuration, see Encrypted Retained Messages.
Sources : README.md:8-9
Auto-Save Retained Messages
The protected-no-wildcard branch includes functionality to automatically persist retained messages to disk after every message write. This contrasts with Mosquitto's default behavior where:
- In-memory messages may be lost on unclean shutdown
- Persistence is typically triggered by shutdown signals or intervals
The auto-save feature ensures that:
- Each retained message write triggers a disk synchronization
- Retained messages survive unexpected container restarts
- Message persistence guarantees are stronger in high-availability scenarios
Trade-offs :
- Pros : Better data durability, reduced risk of message loss
- Cons : Increased I/O operations, potential performance impact for high-volume retained message workloads
Sources : README.md9
Branch Comparison and Migration
The following table summarizes when to use each branch:
| Scenario | Recommended Branch | Rationale |
|---|---|---|
| Local development | main | Simpler configuration, no authentication overhead |
| Single trusted user | main | Anonymous access is sufficient for trusted environments |
| IoT prototyping | main | Rapid iteration without user management |
| Multi-tenant deployment | protected-no-wildcard | Topic isolation prevents cross-user access |
| Production with sensitive data | protected-no-wildcard | Encryption protects retained messages at rest |
| High-availability requirements | protected-no-wildcard | Auto-save ensures message persistence |
| Public-facing broker | protected-no-wildcard | Authentication and ACLs prevent abuse |
Migration Path : Moving from main to protected-no-wildcard requires:
- Adding user authentication credentials to Mosquitto configuration
- Creating an ACL file with appropriate topic rules
- Configuring and initializing the
gocryptfsencrypted filesystem - Updating client applications to provide authentication credentials
- Restructuring topic hierarchies to follow the username-first pattern
Sources : README.md:5-11
Accessing Advanced Features
To explore or deploy the advanced features:
-
View the diff : Compare the branches to understand specific changes
-
Checkout the branch :
-
Review documentation : Each subsection below provides detailed configuration instructions:
- Topic Access Control (ACL)) - User authentication and ACL file configuration
- Encrypted Retained Messages - Gocryptfs setup and encryption key management
- Production Considerations - Scaling, monitoring, and hardening recommendations
Sources : README.md11
Configuration File Locations
The following files are specific to the protected-no-wildcard branch and do not exist in main:
| File Path | Purpose | Branch |
|---|---|---|
mosquitto/aclfile | Defines user-based topic access rules | protected-no-wildcard only |
mosquitto/passwordfile | Stores hashed user credentials | protected-no-wildcard only |
docker-compose.yml (modified) | Includes gocryptfs service definition | protected-no-wildcard only |
data-encrypted/ | Encrypted filesystem storage directory | protected-no-wildcard only |
Files that exist in both branches but have different configurations:
| File Path | Main Branch | Protected Branch |
|---|---|---|
| mosquitto.conf2 | allow_anonymous true | allow_anonymous false |
| mosquitto.conf | No acl_file directive | Includes acl_file /mosquitto/config/aclfile |
| mosquitto.conf | No password_file directive | Includes password_file /mosquitto/config/passwordfile |
Sources : README.md7 mosquitto.conf:1-6
Next Steps : For detailed implementation guides for each advanced feature, proceed to the subsections:
- Topic Access Control (ACL)) for multi-user topic isolation
- Encrypted Retained Messages for filesystem encryption setup
- Production Considerations for deployment best practices