# EMQX 6 Configuration for Certificate-Based Device Authentication # # This configuration file contains the essential TLS and authentication settings # for EMQX 6 to use certificate-based authentication for Raspberry Pi devices. # # Place this in your EMQX configuration directory or merge with your existing emqx.conf # # Docker Compose: Mount as volume at /etc/emqx/emqx.conf # Standalone: Copy to /etc/emqx/emqx.conf # Kubernetes/Helm: Add to ConfigMap and reference in values.yaml ##============================================================================== ## LISTENER - TLS/SSL (MQTT over TLS) ##============================================================================== ## ## TCP/IP listener for TLS/SSL connections ## Port: 8883 (standard MQTT Secure port) listeners.ssl.default { # Bind address and port bind = "0.0.0.0:8883" # Number of worker threads for this listener acceptors = 32 # Maximum concurrent connections # max_connections = 1024000 ##============================================================================ ## Server Certificates ##============================================================================ ## These certificates are presented to clients during TLS handshake ## Use a valid certificate (Let's Encrypt, Cloudflare, etc.) in production # Path to server certificate (public key) certfile = "/etc/emqx/certs/server.crt" # Path to server private key keyfile = "/etc/emqx/certs/server.key" ##============================================================================ ## Client Certificate Validation (Mutual TLS) ##============================================================================ ## Configure how EMQX validates client certificates # Path to CA certificate for validating client certificates cacertfile = "/etc/emqx/certs/ca.crt" # Certificate verification mode # Options: # verify_none - Don't request client certificate # verify_peer - Request certificate, but don't require it # verify_peer (this is used below for mutual TLS enforcement) verify = verify_peer # Require client to present valid certificate # Set to true for mandatory mutual TLS fail_if_no_peer_cert = true ##============================================================================ ## TLS Version and Security ##============================================================================ # Minimum TLS version: TLS 1.2 or higher # Older versions (TLS 1.0, 1.1) are insecure and unsupported tls_versions = ["tlsv1.2", "tlsv1.3"] # Cipher suites (strong, modern ciphers) # Listed in order of preference (if honor_cipher_order is on) ciphers = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305" # Use server's cipher preference instead of client's honor_cipher_order = "on" # Session resumption (speeds up reconnections) session_resumption = "on" ##============================================================================ ## Performance Tuning ##============================================================================ # TCP buffer sizes (in bytes) # tcp_send_buf = "16KB" # tcp_recv_buf = "16KB" # Backlog queue size # backlog = 1024 ##============================================================================ ## Optional: Certificate Revocation (CRL) ##============================================================================ ## Enable if you need to revoke compromised device certificates # Enable CRL checking # Uncomment to enable (requires CRL file) # crl_check = true # crl_check_all = false # crl_files = ["/etc/emqx/certs/ca.crl.pem"] ##============================================================================ ## Optional: OCSP Stapling ##============================================================================ ## Online Certificate Status Protocol for certificate revocation checking # Enable OCSP stapling # ocsp_status_request = false } ##============================================================================== ## AUTHENTICATION - Certificate-Based ##============================================================================== ## ## Use X.509 certificates for device authentication instead of username/password ## The certificate's Common Name (CN) is extracted as the MQTT username authentication = [ { enable = true type = cert # Extract device identity from certificate field: # Options: # "cn" - Common Name (recommended for device ID) # "dn" - Distinguished Name # "san" - Subject Alternative Name # # Example: Certificate with subject CN=rpi-001 # becomes MQTT username: rpi-001 user_id_from = "cn" # Optional: Specify which certificate DN field to extract from # This is only used when user_id_from = "dn" # common_name_field = "CN" } ] ##============================================================================== ## AUTHORIZATION - Topic Access Control (ACLs) ##============================================================================== ## ## Restrict MQTT devices to specific topics based on their certificate identity ## Uses ${username} placeholder (derived from certificate CN) authorization { enable = true type = built_in_database # Cache ACL decisions for performance cache { enable = true max_size = 32 } } # Device-specific topic permissions # Each device (rpi-001, rpi-002, etc.) can only access their own topics acl = [ ##======================================================================== ## ADMIN USERS (Full Access) ##======================================================================== # Allow admin user 'tautvydas' full access to all topics { action = "allow" subject {type = "username", value = "tautvydas"} object {type = "topic", value = "#"} access = "all" }, # Allow admin user 'donatas' full access to all topics { action = "allow" subject {type = "username", value = "donatas"} object {type = "topic", value = "#"} access = "all" }, ##======================================================================== ## PUBLISH (Device → Broker) ##======================================================================== # Allow device to publish sensor telemetry data { action = "allow" subject {type = "username", value = "${username}"} object {type = "topic", value = "devices/${username}/telemetry"} access = "publish" }, # Alternative: Allow publish to multiple subtopics # { # action = "allow" # subject {type = "username", value = "${username}"} # object {type = "topic", value = "devices/${username}/telemetry/+"} # access = "publish" # }, ##======================================================================== ## SUBSCRIBE (Device ← Broker) ##======================================================================== # Allow device to receive commands { action = "allow" subject {type = "username", value = "${username}"} object {type = "topic", value = "devices/${username}/command"} access = "subscribe" }, # Allow device to check connection status { action = "allow" subject {type = "username", value = "${username}"} object {type = "topic", value = "$SYS/brokers/+/clients/${username}/connected"} access = "subscribe" }, # Allow device to subscribe to system status # { # action = "allow" # subject {type = "username", value = "${username}"} # object {type = "topic", value = "$SYS/brokers/+/stats"} # access = "subscribe" # }, ##======================================================================== ## DEFAULT: DENY ALL ##======================================================================== # Explicitly deny access to all other topics (security best practice) { action = "deny" subject {type = "all"} object {type = "topic", value = "#"} access = "all" } ] ##============================================================================== ## OPTIONAL: Logging Configuration ##============================================================================== ## ## Monitor TLS and authentication events for troubleshooting log { # Console logging console { enable = true level = "info" } # File logging file { enable = false level = "info" path = "/var/log/emqx/emqx.log" } } ##============================================================================== ## OPTIONAL: Node Information ##============================================================================== ## ## Custom node identification for monitoring node { name = "emqx@127.0.0.1" cookie = "emqxcookie" } ##============================================================================== ## OPTIONAL: Cluster (for HA/Load Balancing) ##============================================================================== ## ## If running multiple EMQX nodes, configure clustering # cluster { # discovery = "static" # static { # seeds = ["emqx@127.0.0.1"] # } # } ##============================================================================== ## OPTIONAL: Metrics and Monitoring ##============================================================================== ## ## Enable Prometheus metrics for monitoring # dashboard { # listeners.http { # bind = "0.0.0.0:18083" # } # } # prometheus { # enable = true # listeners.http { # bind = "0.0.0.0:8081" # path = "/metrics" # } # }