☰
Eclipse Mosquitto 1.4.13 版本解析:安全加固、Broker 修复与客户端改进
2026/9/27 21:40:54 网站建设 项目流程
  • 物联网
  • 消息队列
  • 后端

【免费下载链接】mosquitto

Eclipse Mosquitto - An open source MQTT broker

项目地址:https://gitcode.com/gh_mirrors/mosquit/mosquitto
点击查看免费下载

本篇技术指南以 Eclipse Mosquitto 1.4.13 版本发布说明(www/posts/2017/07/version-1-4-13-released.md)为主体,系统梳理该 bugfix/security 版本在安全漏洞修复、Broker 行为修正与客户端实现上的全部变更,并结合当前仓库源码(src、lib)验证每一项修复的底层实现,帮助读者掌握该版本的关键改动及背后的 MQTT 协议细节。

版本定位:一次聚焦 Bug 修复与安全加固的发布

Mosquitto 1.4.13 于 2017 年 7 月发布,官方定位为bugfix and security release(缺陷修复与安全发布)。与引入新特性的大版本不同,此类版本的重点是消除已知漏洞、修正 Broker 在特定场景下的异常行为,并同步改进客户端库的细节实现。它上承 1.4.x 系列的功能形态,下启 1.5 系列,是该分支上收尾性质的重要一版。

本版本改动可划分为三大板块:

  • Security:修复 CVE-2017-9868(持久化文件权限泄露)与 CVE-2017-7650(用户名/客户端 ID 特殊字符限制)的相关处理;
  • Broker:websockets 性能与大数据包问题、lazy bridge 的idle_timeout超时、CONNECT 保留位校验、停止时遗嘱消息发送、认证插件特殊字符检查开关等;
  • Clients:自动生成客户端 ID 时不再使用/字符。

下文逐一展开,并给出仓库源码层面的印证。

安全修复:CVE-2017-9868 与持久化文件权限

漏洞本质:持久化文件可被本地任意用户读取

1.4.13 修复的第一个安全问题是CVE-2017-9868:Broker 写出的持久化文件(persistence file)默认权限过宽,所有本地用户均可读取。由于持久化数据库中可能包含客户端的会话状态、遗嘱消息、retained 消息乃至认证相关信息,这种泄露存在敏感信息外泄的风险。

发布说明同时指出,该问题也可以在管理层面修复:通过限制持久化文件所在目录的访问权限来兜底,即仅允许运行 mosquitto 的用户(通常是专用服务账号)访问该目录。

修复方式:持久化文件仅属主可读(Windows 除外)

版本将持久化文件的权限收紧为仅属主(owner)可读,即典型的0600权限语义,并且该限制在 Windows 平台不适用(Windows 使用 ACL 机制管理文件权限,与 POSIX 权限位模型不同)。

从当前仓库结构看,持久化逻辑集中在 src/persist_write.c、src/persist_read.c 与 src/database.c 中。其中 src/database.c 的db__open()负责在 Broker 启动时打开持久化数据库,而 src/persist_read.c 在恢复阶段以"rb"只读方式打开持久化文件。运维人员在升级到 1.4.13 后,可以检查持久化文件的实际权限位,确认其已收紧为属主可读写。

实践建议:

  • 升级后检查持久化文件权限:ls -l应显示-rw-------(属主读写,其他用户无权限);
  • 无论版本如何,都应将persistence_file所在目录的权限限制为仅服务账号可访问(例如chmod 700目录),形成纵深防御;
  • 若持久化文件中包含不希望落盘的高敏感数据,可评估关闭持久化或使用受保护目录。

认证与 ACL:CVE-2017-7650 限制放宽与新配置项

CVE-2017-7650:允许/出现在用户名与客户端 ID 中

1.4.13 同时放宽了此前针对 CVE-2017-7650 施加的限制:/现在允许出现在用户名与客户端 ID 中。CVE-2017-7650 本身与用户名/客户端 ID 中特殊字符可能触发的模式匹配问题相关,早期版本采用了较为严格的字符过滤,1.4.13 在评估风险后决定仅对+与#保留硬性限制,放开/。

auth_plugin_deny_special_chars:可配置的特殊字符检查

与 CVE-2017-7650 配套,1.4.13 新增了针对认证插件的配置项auth_plugin_deny_special_chars,允许管理员显式配置是否对用户名/客户端 ID 中的+#进行检查,从而在兼容性与安全性之间取得平衡。

从配置解析源码看,该选项在 src/conf.c 中按插件粒度解析:

  • 未配置任何认证插件时,出现该选项会直接报错:Error: An auth_plugin_deny_special_chars option exists in the config file without a plugin.;
  • 每个认证插件的默认值为true(见 src/conf.c,plugin->config.deny_special_chars = true);
  • 布尔值解析失败时返回MOSQ_ERR_INVAL。

对应的检查实现在 src/plugin_acl_check.c 的acl__pre_check()中:

  • 当deny_special_chars == true时,若用户名或客户端 ID 包含+或#,立即以MOSQ_ERR_ACL_DENIED拒绝访问;
  • 注释明确说明该检查必须对每条消息无条件执行,以保护插件免受基于模式(pattern)的攻击;
  • 值得注意的是,当前源码中strpbrk(username, "+#")的检查集不再包含/,与 1.4.13 放宽/的决策一致;
  • 该检查属于 ACL 的“预检查”(pre-check),在真正调用插件 ACL 回调之前执行,并仅对用户名/客户端 ID 生效。

配置示例(位于认证插件声明块内):

auth_plugin /path/to/auth_plugin.so auth_plugin_deny_special_chars true

说明:该选项必须出现在某个auth_plugin之后,否则 mosquitto 启动时报错退出;设为false可关闭对+#的检查(需自行评估安全风险)。

对应测试可见 test/broker/16-config-huge.py(auth_plugin_deny_special_chars false的配置解析用例),以及 man/mosquitto.conf.5.xml 中的手册条目说明。

Broker 修复:websockets 性能、lazy bridge 与停止时遗嘱

websockets:性能与大型 retained 消息

本版本包含两项 websockets 相关修复:

  1. 修复 websockets 性能不佳的问题:1.4.13 之前 websockets 监听器在大量并发连接或高频消息场景下吞吐受限,本版针对数据读写路径进行了优化;
  2. 修复 websockets 上大型 retained 消息的问题(对应 issue #427):此前通过 websockets 分发较大的 retained 消息时可能出错,本版修正了该传输路径上的处理逻辑。

这两项修复对应仓库中的 src/websockets.c 及 lib/net_ws.c。若读者部署了 websockets 监听器(listener 8083配合protocol websockets),升级 1.4.13 后应关注大型 retained 消息的推送正确性。

lazy bridge:idle_timeout 超时修复

lazy bridge是 mosquitto 的一种按需连接型桥接模式:只有在本地有消息需要转发时才会建立到远端的连接,空闲后断开以节省资源。1.4.13 修复了 lazy bridge 在idle_timeout到期后不超时断开的问题(issue #417)。

从当前源码看,idle_timeout的默认值为 60 秒,且解析时被强制下界到 1 秒(src/conf.c):

idle_timeout 60

该配置项位于 bridge 配置块内,语义为:lazy bridge 在空闲超过该秒数后自动断开与远端的连接。相关字段int idle_timeout;定义于 src/mosquitto_broker_internal.h。修复前该超时逻辑存在缺陷,导致空闲连接无法按时释放;1.4.13 修正后,lazy bridge 能按预期在空闲idle_timeout秒后断开。

Broker 停止时:已连接客户端的遗嘱消息被“发送”

1.4.13 修复了 Broker 关闭流程中的遗嘱消息处理(issue #477):Broker 停止时,所有仍保持连接的客户端的遗嘱消息(will message)现在会被“发送”。此前 Broker 直接退出可能导致遗嘱消息未被处理,客户端无法感知对端异常下线。

对应实现位于 src/mosquitto.c:主事件循环退出后,Broker 遍历db.contexts_by_id中所有上下文,逐个调用context__send_will(ctxt),随后调用will_delay__send_all()冲刷所有带延迟的遗嘱。context__send_will()本身定义于 src/context.c,它会根据will_delay_interval决定立即发送还是进入延迟队列(will_delay__add())。

需要说明的是,该处代码留有 FIXME 注释:当前实现将全部遗嘱立即发送,而更理想的行为是仅发送will_delay_interval == 0的遗嘱、将带正延迟的遗嘱持久化并在客户端重连时限内恢复——这是后续版本演进的方向,1.4.13 的“发送”行为已覆盖了绝大多数实际场景。

CONNECT 保留位校验:严格遵守 MQTT-3.1.2-3

MQTT v3.1.1 规范要求 CONNECT 报文的固定头(Fixed Header)第 1 字节的低 4 位(即“保留标志位”)必须为 0,违反即为协议错误。1.4.13 修复了 Broker 对这一检查的落实,严格遵循规范中的MQTT-3.1.2-3。

从当前源码看,该检查位于 src/handle_connect.c:context->in_packet.command的低 4 位非 0 时直接以MOSQ_ERR_PROTOCOL拒绝连接。此外,对于 MQTT v3.1.1 与 v5 客户端,Connect Flags 字节的最低位(reserved 位,即0x01)也必须为 0,否则同样按协议错误处理(src/handle_connect.c)。这些校验保证了 Broker 对畸形 CONNECT 报文的一致性处理。

其余 Broker 修复

  • CVE-2017-7650 剩余部分的修复:除放开/外,1.4.13 还完成了该 CVE 相关的其余加固工作(发布说明中的 “Remainder of fix”),整体上形成了“保留+#硬限制、放开/、提供可配置开关”的最终策略;
  • 持久化文件属主权限:即前述 CVE-2017-9868 的修复(issue #468),持久化文件写入后仅属主可读(Windows 除外)。

客户端改进:自动生成 ID 不再包含/

客户端库(libmosquitto)在本版本中有一项针对性修复:自动生成的客户端 ID 不再使用/字符。当客户端程序未显式指定 Client ID 时,mosquitto 会基于进程信息等生成一个随机 ID;在 1.4.13 之前,该 ID 可能包含/,而结合 CVE-2017-7650 的讨论(用户名/客户端 ID 中的特殊字符),/在部分场景下不受欢迎,因此本版改为从自动生成 ID 的字符集中剔除/。

该改动与 Broker 侧“允许/出现在用户提供的 ID 中”并不矛盾:前者针对的是客户端库的自动生成行为(生成侧规避特殊字符,减少下游插件/桥接场景的兼容问题),后者针对的是用户显式提供的身份(Broker 侧评估后放宽限制)。两者共同体现了 1.4.13 在“协议兼容”与“安全防护”之间的细致平衡。

升级与验证建议

升级要点

  • 将 mosquitto 升级到 1.4.13(或包含上述修复的更新版本);
  • 检查持久化文件权限已收紧为属主可读写,并限制持久化目录的访问;
  • 若使用认证插件且依赖旧版对/的拦截行为,请评估是否需要通过auth_plugin_deny_special_chars或其他 ACL 规则补充控制;
  • websockets 监听器用户建议回归测试大型 retained 消息的推送。

回归验证

仓库自带的测试可辅助验证相关行为:

  • 配置解析:auth_plugin_deny_special_chars的解析用例见 test/broker/16-config-huge.py;
  • CONNECT 协议校验:相关 Python 测试位于 test/broker 目录(如 01 系列连接测试);
  • 桥接行为:lazy bridge 与idle_timeout相关测试见 test/broker/06-bridge-*.py;
  • 遗嘱消息:遗嘱相关测试见 test/broker/07-will-*.py 系列。

小结

Mosquitto 1.4.13 是典型的“小而关键”的维护版本:两个 CVE 的处理(CVE-2017-9868 的持久化文件权限、CVE-2017-7650 的字符限制策略)、websockets 性能与大数据包修复、lazy bridge 的idle_timeout超时、停止时遗嘱发送、CONNECT 保留位校验,以及客户端自动 ID 的字符调整,共同构成了该版本的完整变更面。对仍在 1.4.x 分支的部署而言,本版本是值得执行的安全与稳定性升级;其修复思路(如auth_plugin_deny_special_chars的可配置化、权限收紧与目录级兜底)也为后续版本的安全设计奠定了基础。

  • 物联网
  • 消息队列
  • 后端

【免费下载链接】mosquitto

Eclipse Mosquitto - An open source MQTT broker

项目地址:https://gitcode.com/gh_mirrors/mosquit/mosquitto
点击查看免费下载
上一篇:使用 Windows.UI.Core.AnimationMetrics 读取 Windows 动画库原始参数:AnimationMetrics 示例深度解析
下一篇:终极指南:5分钟让你的老旧游戏手柄兼容所有现代游戏!🎮

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询