## EMQX 5.x — конфиг для контейнера IoT на платформе Nubes. ## Вшит в образ naeel/iot-emqx. Auth/ACL — напрямую в PostgreSQL (iot_devices), ## без зависимости от адреса монолита: EMQX можно создать в deck ДО iot-service. ## ## ⚠ ${VAR}-интерполяция в этом конфиге НЕ работает (проверено на 5.5.1: ## значения попадают в конфиг буквально). Параметры PG задаются ТОЛЬКО ## официальными env-переопределениями (deck-UI или kubectl set env): ## EMQX_AUTHENTICATION__1__SERVER — host:port master (внутренний svc) ## EMQX_AUTHENTICATION__1__DATABASE — имя БД (iotdb) ## EMQX_AUTHENTICATION__1__USERNAME — роль (iot_service) ## EMQX_AUTHENTICATION__1__PASSWORD — пароль роли ## EMQX_AUTHORIZATION__SOURCES__1__SERVER / DATABASE / USERNAME / PASSWORD ## SSL обязателен (pg_hba платформы): ssl = {enable=true, verify=verify_none}. ## ⚠ В authz-postgresql НЕ поддерживаются плейсхолдеры ${action}/${topic} — ## action/topic возвращаются КОЛОНКАМИ результата запроса (проверено на 5.5.1: ## ${action} подставлялся как литерал "{action}" и ACL-запрос падал). node { name = "emqx@127.0.0.1" cookie = "iot-emqx-cookie-mvp" data_dir = "/opt/emqx/data" } ## Auth — PostgreSQL: устройства в iot_devices. ## username устройства = namespace || '_' || device_id; бридж: namespace='__bridge', ## username = device_id (строка создаётся монолитом EnsureBridgeDevice при старте). authentication = [ { mechanism = password_based backend = postgresql enable = true server = "127.0.0.1:5432" database = "iotdb" username = "iot_service" password = "placeholder" auto_reconnect = true pool_size = 8 ssl { enable = true verify = verify_none } password_hash_algorithm { name = plain salt_position = disable } query = "SELECT mqtt_password AS password_hash FROM iot_devices WHERE enabled = true AND (namespace || '_' || device_id = ${username} OR (namespace = '__bridge' AND ${username} = device_id)) LIMIT 1" } ] ## ACL — PostgreSQL: устройства pub/sub только в свой топик ns/telemetry/device_id, ## бридж — subscribe на "+/telemetry/+". ## no_match = deny: нет строки в iot_devices или устройство выключено — запрет. authorization { no_match = deny deny_action = disconnect cache { enable = true max_size = 32 ttl = 1m } sources = [ { type = postgresql enable = true server = "127.0.0.1:5432" database = "iotdb" username = "iot_service" password = "placeholder" auto_reconnect = true pool_size = 8 ssl { enable = true verify = verify_none } query = "SELECT 'allow' AS permission, 'subscribe' AS action, '+/telemetry/+' AS topic FROM iot_devices WHERE enabled = true AND namespace = '__bridge' AND ${username} = device_id UNION ALL SELECT 'allow' AS permission, a.action, namespace || '/telemetry/' || device_id AS topic FROM iot_devices, (VALUES ('publish'), ('subscribe')) AS a(action) WHERE enabled = true AND namespace || '_' || device_id = ${username}" } ] } mqtt { max_packet_size = 1MB max_topic_levels = 10 retain_available = false } ## Логи: console (stdout) — видны через kubectl logs платформы. ## Файловый handler отключён (у USER emqx нет прав на /var/log/emqx при deb). log { console_handler { enable = true level = warning } file_handlers.default { enable = false } } ## Listeners: WebSocket — единственный порт контейнера платформы (8083). ## TCP 1883 остаётся для диагностики (не экспонируется платформой). listeners.tcp.default { bind = "0.0.0.0:1883" max_connections = 1024 } listeners.ws.default { bind = "0.0.0.0:8083" websocket { mqtt_path = "/mqtt" } max_connections = 512 } ## Dashboard ОТКЛЮЧЁН (enable=false): на CPU-квоте 500m swagger-генерация падает ## с таймаутами и засоряет логи. Диагностика — через порт 1883/ctl. dashboard { listeners.http { enable = false } }