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.

Protected Branch Features

Loading…

Protected Branch Features

Relevant source files

Purpose and Scope

This document describes the advanced security features available in the protected-no-wildcard branch of this repository. These features provide enhanced access control, message encryption, and persistence capabilities beyond the base configuration in the main branch.

The protected branch implements three key enhancements:

  1. ACL-based wildcard topic restrictions
  2. Encrypted storage for retained messages
  3. Automatic persistence of retained messages

For basic deployment and configuration information, see Getting Started. For general production deployment considerations, see Production Deployment Considerations.

Sources : README.md:7-13


Overview of the Protected Branch

The protected-no-wildcard branch provides an alternative deployment configuration that addresses specific security and privacy requirements for multi-tenant or privacy-sensitive MQTT deployments. Unlike the main branch which provides anonymous access and no encryption, the protected branch implements defense-in-depth security measures.

Branch Access

ResourceLocation
Protected Branch[protected-no-wildcard branch](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/protected-no-wildcard branch)
Diff from Main[main…protected-no-wildcard comparison](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/main…protected-no-wildcard comparison)
ACL Filemosquitto/aclfile (in protected branch)

The protected branch maintains the same container architecture and Cloudflare Tunnel integration as the main branch, adding security layers within the Mosquitto container and its configuration.

Sources : README.md:7-13


Wildcard Restriction via ACL File

Access Control List Implementation

The protected branch implements topic-level access control using Mosquitto’s ACL (Access Control List) system. The ACL file enforces a topic namespace convention where the first level of each topic path represents a username, preventing users from subscribing to wildcard patterns that cross user boundaries.

Topic Namespace Convention

<username>/<application>/<device>/<metric>

In this pattern:

  • <username> is the first-level topic segment
  • Users can only access topics beginning with their own username
  • Wildcard subscriptions like # or +/+/+ are restricted to prevent cross-user data access
flowchart TD
 
   Client["MQTT Client"] -->|SUBSCRIBE user1/sensors/#| CloudflareTunnel["Cloudflare Tunnel"]
CloudflareTunnel -->|Forward to mosquitto:9001| Cloudflared["cloudflared Container"]
Cloudflared --> MosquittoListener["Mosquitto WebSocket Listener\nPort 9001"]
MosquittoListener --> ACLCheck{"ACL Permission Check"}
ACLCheck -->|Load Rules| ACLFile["mosquitto/aclfile"]
ACLFile -->|Pattern Matching| ACLCheck
    
 
   ACLCheck -->|Allowed| TopicTree["Topic Subscription Tree"]
ACLCheck -->|Denied| RejectSub["SUBACK with Failure Code"]
TopicTree --> MessageRoute["Route Messages to Client"]
RejectSub --> Client
 
   MessageRoute --> Client
    
 
   Publisher["Publishing Client"] -->|PUBLISH user2/data| CloudflareTunnel
 
   CloudflareTunnel --> Cloudflared
 
   Cloudflared --> MosquittoListener
 
   MosquittoListener --> ACLCheckPub{"ACL Publish Check"}
ACLCheckPub -->|Read aclfile| ACLFile
 
   ACLCheckPub -->|Allowed| TopicTree
 
   ACLCheckPub -->|Denied| RejectPub["PUBACK with Error"]
RejectPub --> Publisher

ACL Enforcement Flow

Diagram : ACL enforcement flow showing how the aclfile mediates access to topics based on username-prefixed patterns.

Sources : README.md9


Naive Implementation Characteristics

The README describes this ACL implementation as “naive” because it relies on a simple convention rather than cryptographic authentication:

CharacteristicImplementation Detail
AuthenticationUsers are not cryptographically authenticated; ACL assumes username is provided correctly
Namespace ConventionFirst-level topic segment must match username
Wildcard BlockingPrevents # and multi-level + patterns that span users
Trust ModelAssumes clients accurately identify themselves

This approach provides separation of concerns and data isolation in scenarios where clients are trusted or authenticated through external mechanisms (e.g., Cloudflare Access policies, API tokens in headers).

Sources : README.md9


Encrypted Retained Messages with gocryptfs

flowchart TB
    subgraph "Docker Host Filesystem"
        EncryptedVol["Encrypted Volume\ngocryptfs ciphertext"]
end
    
    subgraph "mosquitto Container"
        GocryptfsMount["gocryptfs FUSE Mount"]
PlaintextView["Plaintext View\n/mosquitto/data"]
MosquittoProcess["Mosquitto Process"]
PersistenceDir["persistence_location\nConfiguration Directive"]
end
    
    subgraph "Message Lifecycle"
        RetainedMsg["Retained Message\nMQTT PUBLISH with retain=true"]
WriteOperation["Write to Persistence Store"]
ReadOperation["Read from Persistence Store"]
DecryptedMsg["Decrypted Message\nDelivered to Subscriber"]
end
    
 
   EncryptedVol <-->|FUSE System Calls| GocryptfsMount
 
   GocryptfsMount -->|Transparent Encryption| PlaintextView
 
   PlaintextView <--> MosquittoProcess
 
   MosquittoProcess -->|References| PersistenceDir
    
 
   RetainedMsg --> MosquittoProcess
 
   MosquittoProcess --> WriteOperation
 
   WriteOperation -->|Plaintext Write| PlaintextView
 
   PlaintextView -->|Encrypted on Disk| GocryptfsMount
    
 
   GocryptfsMount -->|Decrypt on Read| PlaintextView
 
   PlaintextView --> ReadOperation
 
   ReadOperation --> MosquittoProcess
 
   MosquittoProcess --> DecryptedMsg

Overview

The protected branch integrates gocryptfs to encrypt Mosquitto’s retained message store at rest. This prevents unauthorized access to message content if the underlying storage volume is compromised or accessed outside the container.

gocryptfs Integration Architecture

Diagram : gocryptfs provides transparent encryption/decryption between Mosquitto’s plaintext operations and the encrypted on-disk storage.

Sources : README.md10


Encryption Properties

PropertyValue
Encryption TypeFilesystem-level encryption via FUSE
CipherDetermined by gocryptfs (typically AES-256-GCM)
Key StorageConfigured at gocryptfs mount initialization
PerformanceFUSE overhead; transparent to Mosquitto
ScopeOnly retained messages in persistence_location

Data Flow: Publishing a Retained Message

Diagram : Sequence showing how a retained message is transparently encrypted during the persistence operation.

Sources : README.md:10-11


Auto-Save Retained Messages

Persistence Trigger Mechanism

The protected branch configures Mosquitto to automatically save retained messages to persistent storage after every message operation. This differs from the default behavior where Mosquitto may defer writes to optimize performance.

Configuration Directive

The auto-save behavior is controlled by the autosave_interval directive in mosquitto.conf:

autosave_interval 1

Setting autosave_interval to 1 instructs Mosquitto to write the in-memory retained message database to disk after every message change (publish or removal of a retained message).

Sources : README.md11


Auto-Save Behavior Comparison

ConfigurationBehaviorUse Case
Main BranchDefault interval (1800 seconds)Standard deployments with container restart tolerance
Protected BranchInterval of 1 secondData-critical deployments requiring immediate persistence

Auto-Save State Machine

Diagram : State machine showing auto-save behavior triggered after each retained message operation.

Sources : README.md11


Performance Implications

AspectImpact
Disk I/OIncreased write operations on every retained message
LatencyMinimal impact on PUBACK latency (async write)
DurabilityNear-zero data loss on container crash
ThroughputMay limit sustained retained message publish rate
flowchart LR
    subgraph "Main Branch Architecture"
        MainMosq["mosquitto Container\n- Standard config\n- Anonymous access\n- No encryption"]
MainCF["cloudflared Container\n- Standard tunnel"]
MainVol["Volume: ./mosquitto.conf"]
MainVol --> MainMosq
 
       MainCF --> MainMosq
    end
    
    subgraph "Protected Branch Architecture"
        ProtMosq["mosquitto Container\n- ACL enabled\n- autosave_interval=1\n- gocryptfs mount"]
ProtCF["cloudflared Container\n- Standard tunnel"]
ProtACL["Volume: ./mosquitto/aclfile"]
ProtConf["Volume: ./mosquitto.conf\n+ ACL directives"]
ProtCrypt["Encrypted Volume\ngocryptfs"]
ProtACL --> ProtMosq
 
       ProtConf --> ProtMosq
 
       ProtCrypt <--> ProtMosq
 
       ProtCF --> ProtMosq
    end

For deployments with high-frequency retained message updates, the default autosave_interval may provide better throughput at the cost of potential data loss during abnormal termination.


Architectural Comparison: Main vs Protected Branch

Container Architecture Differences

Diagram : Comparison of container architectures between main and protected branches, highlighting additional components in the protected configuration.

Sources : README.md:7-13


Feature Matrix

FeatureMain BranchProtected Branch
Access ControlAnonymous, unrestrictedACL-based, username-scoped
Wildcard SubscriptionsAllowed globallyRestricted to user namespace
Retained Message EncryptionNonegocryptfs transparent encryption
Persistence IntervalDefault (30 minutes)Immediate (1 second)
Additional FilesNonemosquitto/aclfile
Container ComplexityMinimalModerate (gocryptfs setup)
Suitable ForDevelopment, trusted networksMulti-tenant, privacy-sensitive

flowchart TD
    subgraph "User Isolation"
        User1["User: alice"]
User2["User: bob"]
User3["User: charlie"]
end
    
    subgraph "Topic Namespace"
        T1["alice/home/temperature"]
T2["alice/home/humidity"]
T3["bob/sensors/motion"]
T4["bob/sensors/light"]
T5["charlie/devices/status"]
end
    
    subgraph "ACL Enforcement"
        ACL["mosquitto/aclfile\npattern: topic readwrite alice/#\npattern: topic readwrite bob/#\npattern: topic readwrite charlie/#"]
end
    
 
   User1 -->|Allowed| T1
 
   User1 -->|Allowed| T2
 
   User1 -.->|Denied| T3
 
   User1 -.->|Denied| T4
    
 
   User2 -->|Allowed| T3
 
   User2 -->|Allowed| T4
 
   User2 -.->|Denied| T1
    
 
   User3 -->|Allowed| T5
 
   User3 -.->|Denied| T1
    
 
   ACL -.->|Enforces| User1
 
   ACL -.->|Enforces| User2
 
   ACL -.->|Enforces| User3

Use Cases for Protected Branch Features

Multi-Tenant Deployments

In scenarios where multiple users or applications share a single MQTT broker, the ACL-based wildcard restrictions prevent data leakage across tenant boundaries:

Diagram : ACL enforcement creating isolated topic namespaces for multiple users.


Privacy-Sensitive Applications

For deployments handling sensitive data (healthcare, financial, personal information), the gocryptfs encryption ensures that retained messages stored on disk cannot be read without the encryption key:

Use Case: Healthcare IoT
- Medical devices publish patient vitals as retained messages
- Disk snapshots or backups contain only encrypted ciphertext
- Compromise of storage volume does not expose patient data
- Encryption key is managed separately from storage

Data Integrity Critical Systems

The auto-save mechanism ensures minimal data loss in crash scenarios:

ScenarioMain Branch ImpactProtected Branch Impact
Container crashUp to 30 minutes of retained messages lostMaximum 1 second of messages lost
System power lossUp to 30 minutes of retained messages lostMaximum 1 second of messages lost
Normal shutdownAll messages persistedAll messages persisted

Migration Between Branches

Switching from Main to Protected

To adopt the protected branch features:

  1. Review ACL requirements : Determine if your topic structure follows username-prefixed convention
  2. Configure gocryptfs : Initialize encrypted volume and obtain encryption key
  3. Update docker-compose.yml : Modify to mount gocryptfs volume and ACL file
  4. Test ACL rules : Verify wildcard restrictions work as expected
  5. Backup unencrypted data : Retained messages in main branch are plaintext

Switching from Protected to Main

To revert to the simpler main branch configuration:

  1. Decrypt retained messages : Use gocryptfs to access plaintext before migration
  2. Export critical data : Publish non-retained messages if needed for recovery
  3. Remove ACL restrictions : Understand that all topics become globally accessible
  4. Switch branch : Check out main branch and restart containers

Sources : README.md13


Configuration Files in Protected Branch

Additional Files

The protected branch introduces files not present in main:

FilePurposeLocation
mosquitto/aclfileACL pattern definitionsMounted as volume in mosquitto container
Modified mosquitto.confReferences ACL file, sets autosave_interval=1Replaces main branch version
gocryptfs initialization scriptsSet up encrypted filesystemContainer initialization

Modified Configuration Directives

Expected changes to mosquitto.conf in protected branch:

# ACL Configuration
acl_file /mosquitto/config/aclfile

# Persistence Configuration
autosave_interval 1
persistence true
persistence_location /mosquitto/data/

Sources : README.md:9-11


Security Considerations

Threat Model

The protected branch defends against specific threats:

ThreatMitigation
Cross-tenant data accessACL wildcard restrictions
Disk volume compromisegocryptfs encryption at rest
Data loss on crashAuto-save immediate persistence
Unauthorized topic subscriptionACL pattern matching

Limitations

The protected branch does NOT protect against:

  • Man-in-the-middle attacks (handled by Cloudflare Tunnel TLS)
  • Compromised MQTT clients (they can still access their own namespace)
  • Memory-resident message inspection (encryption only at rest)
  • DoS attacks from authenticated users

For comprehensive security, combine protected branch features with:

  • Cloudflare Access policies (see Security Model)
  • MQTT authentication plugins
  • Rate limiting and message size restrictions
  • Network-level monitoring

Sources : README.md9


Summary

The protected-no-wildcard branch extends the base Docker MQTT Mosquitto deployment with three integrated security features:

  1. ACL-based wildcard restrictions isolate user topics using username-prefixed patterns
  2. gocryptfs encryption protects retained messages at rest with transparent filesystem encryption
  3. Auto-save persistence minimizes data loss by writing retained messages after every operation

These features are particularly valuable for multi-tenant deployments, privacy-sensitive applications, and systems requiring high data durability. The trade-offs include increased container complexity, potential performance impact from frequent disk writes, and operational overhead of managing ACL files and encryption keys.

For standard single-tenant or development deployments, the main branch provides a simpler configuration with anonymous access and no encryption. For production deployments requiring enhanced security and isolation, the protected branch implements defense-in-depth measures while maintaining the same Cloudflare Tunnel integration and container orchestration model.

Sources : README.md:7-13

Dismiss

Refresh this wiki

Enter email to refresh