ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Eclipse Mosquitto 2.0.12 发布解读:安全修复、Broker 与客户端库关键变更详解

Eclipse Mosquitto 2.0.12 发布解读:安全修复、Broker 与客户端库关键变更详解 物联网消息队列后端【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mosquit/mosquitto点击查看免费下载Eclipse Mosquitto 2.0.12 是 Mosquitto 2.0 系列的一个安全与缺陷修复版本security and bugfix release发布于 2021 年 8 月底。本文以官方发布说明为主线结合当前仓库的 源码实现 与 配置文件逐项拆解本次版本在安全加固、Broker 行为、客户端库libmosquitto、命令行应用等方面的具体变更帮助读者理解每个修复背后的协议细节、代码逻辑与升级注意事项。版本概览与定位Mosquitto 2.0.12 紧承 2.0.11 之后发布属于 2.0 稳定分支上的维护版本。官方发布说明将其定性为安全与缺陷修复版本意味着本次更新不引入新的功能特性而是集中处理了三类问题安全性修复可导致拒绝服务DoS的属性解析问题、协议级漏洞CVE-2020-13849的规避、插件 ACL 权限残留问题、默认监听器配置陷阱协议与行为正确性修复 QoS 2 消息的 ACL 复查、共享订阅恢复、mount_point 清理、配置解析越界读取等构建与跨平台修复 libressl、Windows 二进制输出、WITH_TLSno 安装等构建问题。以下各节按发布说明的原始章节顺序展开并结合仓库源码给出底层证据。安全修复五个值得关注的攻击面1. MQTT v5 大量 user-property 导致的 CPU 耗尽发布说明指出一个 MQTT v5 客户端如果在连接时携带大量 user-property 属性可能造成过高的 CPU 占用进而导致性能下降甚至拒绝服务该问题已在本版本修复。在 MQTT v5 协议中user-property是允许重复出现的属性每个属性由一对 UTF-8 字符串键与值组成。在 property_broker.c 中可以看到Broker 在收到 CONNECT/PUBLISH 等报文后会遍历属性链表将MQTT_PROP_USER_PROPERTY连同content-type、correlation-data、response-topic、payload-format-indicator等属性单独摘出来保存、随 PUBLISH 转发。当单个报文携带数千甚至数万个 user-property 时链表的遍历、复制与内存管理开销会急剧放大——这正是 2.0.12 修复的 CPU 放大路径。该修复的核心思路是限制/规范属性处理过程中的资源消耗避免恶意客户端通过大量重复属性拖垮 Broker。2. max_keepalive 未对 MQTT v3.1.1 / v3.1 生效CVE-2020-13849 缓解这是本版本最重要的协议级修复之一。max_keepalive是 Broker 端的连接保活上限配置此前仅对 MQTT v5 客户端生效。修复后MQTT v3.1.1 与 v3.1 客户端若 keepalive 值超过max_keepalive也会被拒绝连接。这一改动在 handle_connect.c 中有清晰的实现if(db.config-max_keepalive (context-keepalive db.config-max_keepalive || context-keepalive 0)){ keepalive__remove(context); context-keepalive db.config-max_keepalive; keepalive__add(context); if(context-protocol mosq_p_mqtt5){ if(mosquitto_property_add_int16(connack_props, MQTT_PROP_SERVER_KEEP_ALIVE, context-keepalive)){ ... } }else{ send__connack(context, connect_ack, CONNACK_REFUSED_IDENTIFIER_REJECTED, NULL); rc MOSQ_ERR_INVAL; goto error; } }关键差异在于MQTT v5 客户端连接被接受但 Broker 通过 CONNACK 中的Server Keep Alive属性告知客户端使用收紧后的 keepalive 值协议原生支持服务端覆盖MQTT v3.1.1 / v3.1 客户端协议没有服务端下发 keepalive的机制因此直接以CONNACK_REFUSED_IDENTIFIER_REJECTED拒绝连接。该配置项在 conf.c 中解析值域为 0–65535uint16_t配置方式为max_keepalive 65535官方说明特别指出这一选项使 CVE-2020-13849 得以被规避——该 CVE 是 MQTT v3.1.1 协议本身的设计问题而非某个实现缺陷协议允许客户端声明任意大的 keepalive若 Broker 全盘接受可能长期占用连接资源。2.0.12 之前 v3.1.1 客户端不受max_keepalive约束等于完全暴露于该风险之下。此外keepalive.c 显示keepalive 机制使用基于max_keepalive*1.51容量的环形缓冲区ring buffer来安排超时检查max_keepalive配置越小缓冲区占用的内存越小。3. 未定义 listener 时使用 cafile 等监听器选项的默认监听器漏洞#2283发布说明指出如果没有定义任何 listener却使用了仅适用于监听器的配置选项例如cafile会导致一个可被远程访问且开放匿名访问的监听器被打开与文档描述相悖。2.0.12 已修复此问题。背景知识Mosquitto 2.0 起默认监听器只绑定到 localhost默认禁止匿名访问。此前若用户想只开 TLS 而不定义 listener仅在全局配置了cafile解析器会据此推断应启用默认监听器却按旧逻辑将其暴露在非本地地址且允许匿名——等于绕过了 2.0 的安全默认值。修复后此类配置不再产生一个未受约束且匿名开放的监听器用户必须显式定义 listener 及其安全参数。4. 插件撤销订阅 ACL 后持久会话客户端仍保留订阅CVE-2021-34434发布说明如果插件plugin曾授予某个持久会话durable / clean sessionFalse客户端订阅某主题的 ACL 权限之后又撤销了该权限该客户端会继续保留已有订阅。2.0.12 修复了这个问题。这一场景常见于动态 ACL 插件如仓库中的 dynamic-security 插件管理员在运行时修改了角色/ACL 规则期望立即生效并收回客户端的订阅权利但旧版本中持久会话的订阅列表在重连时不会重新经过 ACL 复查导致权限已撤销、订阅仍在生效。修复后订阅在会话恢复阶段会接受 ACL 校验权限被撤销的订阅不再被保留。5. QoS 2 未完成消息流在重连时绕过 ACL 检查发布说明当clean sessionFalse的客户端重连时尚未完成 QoS 2 流程即未完成 PUBREC/PUBREL/PUBCOMP 握手的入站消息此前不会经过 ACL 检查2.0.12 已修复。QoS 2 消息需要经过PUBLISH → PUBREC → PUBREL → PUBCOMP四步握手才能算投递完成。若消息停留在中间状态例如客户端在收到 PUBLISH 后断线旧版本会在客户端重连后直接将这部分消息重新投递而不再复查该客户端当前的 ACL 权限——这在用户名/权限已变更的场景下构成权限绕过。修复后所有待重投的 QoS 2 消息在重连恢复时统一经过 ACL 复查逻辑上与 handle_connect.c 中db__check_acl_of_all_messages(context)所体现的移除不再被 ACL 允许的排队消息的既有机制保持一致。Broker 修复健壮性与协议合规损坏配置文件的越界读取#567213发布说明指出修复了读取损坏/精心构造的配置文件时可能发生的越界内存读取。除非配置文件对不可信用户可写否则这不是风险——这是一条防御性的健壮性修复防止畸形输入触发未定义行为。max_connections 计数错误max_connections监听器级连接上限此前存在计数不准确的问题。修复后的判定逻辑可参考 net.cif((new_context-listener-max_connections 0 new_context-listener-client_count new_context-listener-max_connections) || (db.config-global_max_connections 0 HASH_CNT(hh_sock, db.contexts_by_sock) (unsigned int)db.config-global_max_connections)){ log__printf(NULL, MOSQ_LOG_NOTICE, Client connection from %s denied: max_connections exceeded., new_context-address); ... }同一逻辑在 websockets.c 中针对 WebSocket 连接重复实现。2.0.12 修复的是client_count在特定连接生命周期如被拒绝、认证失败下未正确回退导致的计数偏差。该配置项在 conf.c 中解析负值表示不限制另有全局版的global_max_connectionsconf.c。TLS 证书与 TLS-PSK 的兼容性本次修复了两个 TLS 相关问题TLS 证书与 TLS-PSK 无法同时配置此前cafile/certfile等证书配置与psk_hint/psk_file等 PSK 配置同时存在时会出现冲突2.0.12 允许二者并存按 listener 分别配置使用 TLS-PSK 时禁用 TLS v1.3由于 TLS-PSK 在 TLS v1.3 下的配置路径存在不完整之处为避免错误配置导致的安全隐患Broker 与客户端库在使用 TLS-PSK 时均强制禁用 TLS v1.3。其他 Broker 修复password_file 指向目录时 Broker 无法退出#2241此前若password_file配置成了目录路径Broker 会出现启动/退出异常现已修复监听器 mount_point 未在出站消息上移除#2244mount_point用于给某监听器下的所有主题加前缀此前出站方向未正确剥离该前缀导致桥接/跨监听器转发时主题被双重前缀污染$share 共享订阅在持久客户端重连时未恢复共享订阅$share/group/topic此前对 durable 客户端重连后的恢复存在缺陷现已修复严格协议合规修复及测试套件本次同步补充了相应的回归测试更新插件配置文档#2286随动态安全等插件的发展官方同步更新了 插件配置文档。客户端库libmosquitto修复TLS-PSK 强制使用 PSK 密码套件发布说明强调客户端使用 TLS-PSK 时现在强制默认密码列表只使用 PSK 系列密码套件。这意味着连接到仅配置 x509 证书的 Broker 时PSK 客户端现在会明确失败此前该客户端会成功连接但不验证任何证书因为证书未配置这种静默的不安全行为已在 2.0.12 中消除。这是安全性显著提升的变更旧行为让用户误以为连接是安全的实际上既没有 PSK 也没有证书校验。升级后若你的客户端同时连接过 PSK 与证书型 Broker请检查是否显式配置了tls_opts_set/tls_set等选项。同时与 Broker 一致客户端库在使用 TLS-PSK 时也禁用 TLS v1.3。线程模式的重新启动#2242发布说明mosquitto_loop_start()启动的线程结束后线程模式状态会被取消配置deconfigured从而允许再次调用mosquitto_loop_start()。此前线程退出后内部状态残留重复启动循环线程会失败。MOSQ_OPT_SSL_CTX 与系统证书选项的修复MOSQ_OPT_SSL_CTX现在可以设置为 NULL#2289修复了将该选项显式置 NULL 时失败的问题MOSQ_OPT_TLS_USE_OS_CERTS下的重连失败#2288当使用系统证书选项、但未设置capath/cafile/psk/MOSQ_OPT_SSL_CTX且MOSQ_OPT_SSL_CTX_WITH_DEFAULTS保持默认值 true 时重连会失败——该组合场景已在 2.0.12 中修复。客户端库属性名支持在 property_mosq.c 与 property_mosq.c 中可以看到user-property作为标准属性名被mosquitto_property_identifier/mosquitto_property_string_to_name等 API 支持这也是安全修复中涉及 user-property 处理路径的库侧背景。Apps 与客户端命令行修复mosquitto_ctrl dynsec setDefaultACLAccessdynsec 默认 ACL 修复发布说明指出修复了mosquitto_ctrl dynsec setDefaultACLAccess命令不工作的问题。在 dynsec.c 中可以看到该命令的完整分发路径if(!strcasecmp(argv[0], setDefaultACLAccess)){ rc dynsec__set_default_acl_access(argc-1, argv[1], j_command); }else if(!strcasecmp(argv[0], getDefaultACLAccess)){ rc dynsec__get_default_acl_access(argc-1, argv[1], j_command); }命令用法dynsec.cmosquitto_ctrl dynsec setDefaultACLAccess acltype allow|deny其中acltype为pub发布或sub订阅allow|deny决定默认允许/拒绝。setDefaultACLAccess用于设置当客户端不属于任何角色时的默认 ACL 行为是动态安全插件plugins/dynamic-security配置默认拒绝一切策略的关键命令——修复前该命令生成的 JSON 请求无法被插件正确处理。mosquitto_sub / mosquitto_rr 的 Windows 二进制输出发布说明mosquitto_sub与mosquitto_rr现在在 Windows 上以二进制模式打开 stdout避免打印二进制 payload 时被换行符转换CRLF等机制修改。此前 Windows 默认文本模式会把\n转换成\r\n破坏二进制数据完整性。TLS 证书行为文档化-p 8883客户端工具同时更新了文档明确说明使用-p 8883TLS 端口时的证书行为帮助用户理解默认端口与证书校验的关系。构建修复WITH_TLSno安装失败#2281无 TLS 构建下的安装步骤此前存在缺失现已修复libressl 3.4.0 构建失败#2198修复了与 libressl 3.4.0 的兼容问题并清理了部分与 libressl 相关的冗余代码守卫MIPS 平台 printf 格式构建警告#2271修复了 MIPS 架构下的格式串编译警告。升级建议与验证针对本次发布建议按以下顺序完成升级验证安全项优先若你的 Broker 直接暴露于公网且允许匿名/大量 MQTT v5 连接优先验证 user-property 放大攻击与 keepalive 上限是否已生效可尝试用超过max_keepalive的 keepalive 连接 v3.1.1 客户端应被拒绝动态 ACL 环境使用 dynamic-security 插件的部署重点回归测试撤销角色后客户端订阅立即失效CVE-2021-34434 场景以及mosquitto_ctrl dynsec setDefaultACLAccess命令TLS-PSK 部署确认 Broker 与客户端版本同步升级检查 PSK 客户端是否会按预期拒绝纯证书型 Broker并按需显式配置密码套件回归测试仓库的 test 目录包含大量针对 broker 行为如 test/broker 下的协议合规、持久会话、ACL 用例的测试脚本可在本地构建后运行验证。完整的配置参数说明可参考 mosquitto.conf 与 mosquitto.conf.5 手册本次涉及的关键配置项max_keepalive、max_connections、global_max_connections、cafile、psk_file等的默认值与取值约束均已在上述源码位置给出依据。总结Mosquitto 2.0.12 是一次典型的小版本大安全维护发布五个安全修复中有两个直接对应 CVECVE-2020-13849 的缓解与 CVE-2021-34434 的修复一个堵住了默认监听器的匿名暴露陷阱另两个封堵了属性放大与 QoS 2 重连的 ACL 绕过路径。对于运维人员本版本尤其值得关注的是max_keepalive对 v3.1.1/v3.1 客户端行为的变化——它意味着老协议客户端将不再能绕开 Broker 的保活上限对于插件开发者ACL 撤销立即生效的修复则要求订阅恢复路径与权限模型保持一致。无论从安全基线还是协议合规角度2.0.12 都是 2.0 系列中值得尽快采纳的版本。赞分享物联网消息队列后端【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mosquit/mosquitto点击查看免费下载相关推荐Mosquitto 2.0.12 发布解析安全加固、Broker 与客户端库关键修复详解Mosquitto 2.0.12 发布解析安全加固、Broker 与客户端库关键修复详解 Eclipse Mosquitto 2.0.12 于 2021 年物联网消息队列后端网络/通信Eclipse Mosquitto 1.6.11 发布解读Broker 与客户端库的关键缺陷修复详解Eclipse Mosquitto 1.6.11 发布解读Broker 与客户端库的关键缺陷修复详解 导读 Eclipse Mosquitto 1.6.11后端消息队列消息路由Eclipse Mosquitto 2.0.22 发布详解Broker、客户端库与动态安全插件的关键修复Eclipse Mosquitto 2.0.22 发布详解Broker、客户端库与动态安全插件的关键修复 Eclipse Mosquitto 于 2025 年后端消息队列消息路由上一篇SLANeXt_wired社区贡献指南如何参与项目开发与改进下一篇CodeIgniter 3 教程构建新闻表单、表单验证与数据写入Create News Items 实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表