
物联网消息队列后端网络/通信【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mo/mosquitto点击查看免费下载导读本文以 Eclipse Mosquitto 官方安全公告security-advisory-cve-2017-9868.md为主体系统梳理 CVE-2017-9868 的漏洞成因、影响版本、官方修复方案与管理员缓解措施并结合当前仓库源码中的restrict_read文件权限防护机制与 ChangeLog.txt 中的修复记录深入剖析持久化文件为何可能泄露敏感信息、现代 Mosquitto 又是如何从根源上杜绝该问题的。读完本文你将掌握该漏洞的完整背景、可落地的加固命令以及从源码层面理解 Mosquitto 持久化文件的安全设计。一、漏洞概览CVE-2017-9868 是什么CVE-2017-9868 是 Eclipse Mosquitto 历史上的一个本地信息泄露漏洞影响Mosquitto 0.15 至 1.4.12含 1.4.12的所有版本。漏洞核心一句话可以概括为当 broker 启用持久化persistence功能时生成的持久化数据库文件会被创建为世界可读world readable权限从而可能将敏感信息暴露给本机上的任意用户。也就是说任何能够登录该主机的本地账户普通用户、低权限服务账户等只要知道持久化文件的位置都可以读取其中的内容而不需要 broker 运行账户的授权。该问题已于Mosquitto 1.4.13版本正式修复官方同时为类 Unix 操作系统不包含 Windows发布了独立补丁。需要强调其本质属性这是一个本地local权限类漏洞攻击面是同一台机器上的其他本地用户而非远程网络攻击。但正因为 Mosquitto 常被部署在共享主机或包含多租户用户的服务器上其实际风险不容忽视。二、漏洞根因持久化数据库为何裸奔要理解这个漏洞先要理解 Mosquitto 的持久化机制到底保存了什么。2.1 持久化功能保存的内容在 mosquitto.conf 中持久化相关的核心配置如下# 如果启用持久化每 autosave_interval 秒将内存中的数据库保存到磁盘。 # 若设为 0持久化数据库只在 mosquitto 退出时写入。参见 autosave_on_changes。 # 注意可通过向 mosquitto 发送 SIGUSR1 信号强制立即写入。 #autosave_interval 1800 #autosave_on_changes false # 将持久化消息数据保存到磁盘true/false。 # 这会保存所有消息的信息包括订阅、当前传输中的消息in-flight以及保留消息。 # retained_persistence 是此选项的同义词。 #persistence false # 持久化数据库使用的文件名不含路径。 #persistence_file mosquitto.db # 持久化数据库的位置。 # 默认是空字符串当前目录。 # 在 Linux 等系统上以正式服务方式运行时建议设置为 e.g. /var/lib/mosquitto。 # 也可以通过 MOSQUITTO_PERSISTENCE_LOCATION 环境变量在启动 broker 前定义。 # 若配置项与环境变量同时设置环境变量优先。 #persistence_location如注释所述持久化文件保存的内容包括客户端会话与订阅信息、当前 in-flight传输中的 QoS 1/2 消息、保留消息retained messages及其载荷、以及消息队列。这些数据对 broker 在重启后恢复运行状态至关重要。2.2 敏感信息为什么值得保护问题在于持久化数据库不是无足轻重的缓存文件它承载的是业务数据本身保留消息与排队消息的载荷payload可能是传感器读数、指令、告警等业务数据MQTT 场景下常涉及物联网设备控制指令或遥测信息订阅主题与客户端标识反映系统内部的主题命名空间、设备分布拓扑是攻击者侦察内网结构与设备类型的重要情报会话与队列状态可用于推断设备上线规律、通信模式。当持久化文件以世界可读权限落盘时任何本地用户只要执行一次cat /var/lib/mosquitto/mosquitto.db就能拿到上述信息——这正是 CVE-2017-9868 的核心危害。2.3 从源码看当时的缺陷背景从当前仓库源码中可以看到修复后的实现路径。持久化数据库的写入由 src/persist_write.c 中的逻辑完成if(db.config-persistence_filepath NULL) return MOSQ_ERR_INVAL; log__printf(NULL, MOSQ_LOG_INFO, Saving in-memory database to %s., db.config-persistence_filepath); return mosquitto_write_file(db.config-persistence_filepath, true, persist__write_data, shutdown, persist__log_write_error);注意这里的第二个参数true——它对应restrict_read限制读取标志即当前版本的 Mosquitto 在写持久化文件时明确要求收紧文件权限。而在 CVE-2017-9868 修复之前1.4.12 及更早版本持久化文件在类 Unix 系统上经由普通fopen/open创建权限受默认 umask 约束。若运行环境 umask 为 022 等宽松值新建文件的权限即为 0644-rw-r--r--任何本地用户都可读取从而触发本漏洞。同理持久化文件的读取入口 src/persist_read.c 也以restrict_readtrue的方式打开文件if(!db.config-persistence || db.config-persistence_filepath NULL){ return 0; } fptr mosquitto__fopen(db.config-persistence_filepath, rb, true);而持久化文件路径本身由 src/conf.c 在配置解析阶段拼接生成——将persistence_location与persistence_file组合为完整路径Unix 下为location/file形式默认位置是 broker 当前工作目录下的mosquitto.db。这也解释了为什么官方公告建议将权限控制重点放在持久化文件所在目录上。三、官方修复方案1.4.13 版本3.1 修复记录的证据在仓库根目录的 ChangeLog.txt 中可以找到该漏洞修复的官方记录1.4.13 - 20170627 Security: - Fix CVE-2017-9868. The persistence file was readable by all local users, potentially allowing sensitive information to be leaked. This can also be fixed administratively, by restricting access to the directory in which the persistence file is stored. Broker: ... - Set persistence file to only be readable by owner, except on Windows. Closes #468.这段变更记录与安全公告完全吻合并补充了两个关键信息修复版本1.4.13 于 2017-06-27 发布即公告发布2017-06-26的次日修复范围Set persistence file to only be readable by owner,except on Windows——即持久化文件权限收紧为仅所有者可读且明确排除 Windows 平台与公告中补丁适用于类 Unix 操作系统即不含 Windows的表述一一对应。原因在于 Windows 采用 ACL 而非 Unix 权限位模型权限语义不同因而单独处理。3.2 补丁的适用前提官方为类 Unix 系统发布了独立补丁供无法立即升级到 1.4.13 的用户先行修复。无论选择补丁还是升级其效果一致确保持久化文件在创建时不再被赋予其他用户可读的权限。对于 Windows 部署由于文件权限模型不同公告明确不适用该补丁此时应直接升级到 1.4.13 或更高版本并通过目录级访问控制ACL限制访问。3.3 修复后的验证方式升级或打补丁后可对正在运行的新版 Mosquitto 做如下验证待持久化文件被写出后检查其权限位应只包含所有者读写权限-rw-------即 0600ls -l /var/lib/mosquitto/mosquitto.db # 期望输出类似-rw------- 1 mosquitto mosquitto ... mosquitto.db若仍显示-rw-r--r--等包含他人可读位的权限则说明环境未正确应用修复应检查 broker 版本与启动目录并配合下一节的目录加固措施。四、管理员缓解措施目录权限加固对于无法立即升级或打补丁的运维场景官方公告给出了一个纯管理层面的缓解手段通过移除持久化文件所在目录的世界读权限来缓解问题。在许多系统中可通过如下命令实现chmod 700 /var/lib/mosquitto4.1 为什么锁目录能生效原理很简单即使持久化文件本身的权限位是 0644世界可读但如果它所在的目录权限被收紧为 0700仅属主可读/写/执行则其他本地用户连进入该目录、列出文件名、通过路径打开文件的能力都没有——Unix 文件系统的路径解析要求对沿途每个目录都拥有执行x权限。chmod 700 /var/lib/mosquitto将目录权限从默认的 755 收紧为 700即只有目录属主通常是mosquitto系统用户可以访问。4.2 加固后的权限自查执行加固后可通过以下命令确认目录与文件的最终状态ls -ld /var/lib/mosquitto # 期望输出drwx------ ... /var/lib/mosquitto ls -l /var/lib/mosquitto/mosquitto.db需要注意两点前提目录属主必须是 broker 运行账户chmod 700只对目录属主有效若目录属主不是运行 mosquitto 的用户broker 本身将无法读写持久化文件导致启动失败或持久化写入失败该方法属于缓解而非根治它依赖管理员正确维护目录权限若未来目录权限被重新放宽或持久化文件被迁移到其他未加固目录风险将回归。因此官方修复1.4.13才是最终方案。五、源码级纵深防御当前版本如何从根源杜绝此类问题虽然 CVE-2017-9868 已在 1.4.13 修复但深入当前仓库源码可以看到 Mosquitto 在文件权限安全上的完整防护设计这正是理解该漏洞修复后形态的最佳窗口。5.1restrict_read统一的受限文件打开机制核心实现在 common/misc_mosq.c 的mosquitto__fopen()函数中。当调用方传入restrict_readtrue时类 Unix 路径采用如下策略old_mask umask(0077); int open_flags O_NOFOLLOW; for(size_t i 0; istrlen(mode); i){ if(mode[i] r){ open_flags | O_RDONLY; }else if(mode[i] w){ open_flags | O_WRONLY; open_flags | (O_TRUNC | O_CREAT | O_EXCL); }else if(mode[i] a){ open_flags | O_WRONLY; open_flags | (O_APPEND | O_CREAT); }... } int fd open(path, open_flags, 0600); if(fd 0) return NULL; fptr fdopen(fd, mode); umask(old_mask);该实现体现了四层防护umask(0077)在创建文件期间将进程 umask 临时收紧为 0077屏蔽组/其他位的所有权限防止环境默认 umask如 022把权限放宽open(path, ..., 0600)显式指定新建文件权限为 0600仅属主读写与 umask 双重保证O_CREAT | O_EXCL以独占方式创建若文件已存在则创建失败避免覆盖他人文件或符号链接O_NOFOLLOW拒绝跟随符号链接防止攻击者用符号链接诱导 broker 在敏感位置写入。而在 Windows 路径common/misc_mosq.c下则通过SECURITY_ATTRIBUTES与BuildExplicitAccessWithNameA显式构造仅当前用户GetUserNameA获取拥有GENERIC_ALL权限的 DACL实现仅所有者可访问的等价语义——这正是 ChangeLog 中except on Windows背后的工程实现。5.2 对既有危险文件的启动警告除了新建文件时收紧权限当前版本在打开已有文件时也会执行安全检查common/misc_mosq.cif(statbuf.st_mode S_IRWXO){ log__printf(NULL, MOSQ_LOG_WARNING, Warning: File %s has world readable permissions. Future versions will refuse to load this file.\n To fix this, use chmod 0700 %s., path, path); }即若持久化文件或密码文件、ACL 文件等其他敏感文件已存在且带有其他人可读权限位broker 会在日志中打出 WARNING提示管理员执行chmod 0700 file修复并预告未来版本将直接拒绝加载此类文件。该警告同样出现在 src/net.c 对 TLS keylog 文件的处理中说明restrict_read是贯穿 broker 全部敏感文件操作的统一安全策略。5.3 写入链路的原子替换持久化数据库的实际落盘由 common/misc_mosq.c 的mosquitto_write_file()完成。从源码结构看其流程是先以restrict_readtrue方式打开一个临时文件写入数据再替换为目标文件。这种写临时文件 重命名的模式确保持久化文件在任意时刻都处于完整、一致的状态避免进程中断产生半截数据库新生成的目标文件继承了受限的 0600 权限不会出现旧文件权限被保留的权限继承问题。这一设计恰好回应了 CVE-2017-9868 的教训权限安全必须在文件创建的每一个路径上都显式保证而不是依赖运行环境默认值。5.4 持久化生命周期中的调用点最后把整个链路串起来看对应 src/database.c 与 src/mosquitto.cbroker 启动时调用db__open()在WITH_PERSISTENCE编译开关下执行persist__restore()src/persist_read.c以restrict_readtrue方式读取persistence_filepath定时保存或退出保存时src/persist_write.c 以restrict_readtrue方式经mosquitto_write_file()写回磁盘期间若检测到文件存在世界可读权限立即输出修复指引日志。读写两端均强制收紧权限配合启动时的存量文件检查构成了针对持久化文件泄露的完整纵深防御。六、受影响判断与加固自检清单如果你管理着 Mosquitto 部署可按以下清单快速判断自己是否处于 CVE-2017-9868 影响范围并完成加固# 1. 确认 broker 版本低于 1.4.13 则受影响1.4.12 及以下均需处理 mosquitto -h | head -n 1 # 2. 确认持久化是否启用mosquitto.conf 中 persistence 是否 true grep -E ^\s*persistence /etc/mosquitto/mosquitto.conf # 3. 定位持久化文件并检查其权限 # 默认路径为工作目录下的 mosquitto.db或由 persistence_location 指定 ls -l /var/lib/mosquitto/mosquitto.db # 4. 收紧持久化目录权限官方公告给出的管理缓解措施 chmod 700 /var/lib/mosquitto # 5. 若发现文件本身权限过宽同步收紧文件权限 chmod 600 /var/lib/mosquitto/mosquitto.db判断结论的三条路径场景处理方式版本 ≤ 1.4.12 且启用持久化升级到 1.4.13或应用官方补丁并执行目录加固版本 ≥ 1.4.13已内置权限收紧Unix 下持久化文件为 0600仍建议确认目录权限Windows 部署补丁不适用直接升级到 1.4.13并通过目录 ACL 限制访问七、总结CVE-2017-9868 是一个典型的文件权限默认值引发的本地信息泄露漏洞Mosquitto 0.15~1.4.12 在启用持久化时以受 umask 支配的默认权限创建持久化数据库导致订阅、保留消息、in-flight 消息等敏感数据可能被任何本地用户读取。官方在 1.4.13 中修复持久化文件仅属主可读Windows 除外并提供了类 Unix 系统补丁管理员亦可通过chmod 700 /var/lib/mosquitto收紧持久化目录权限作为缓解。从当前仓库源码common/misc_mosq.c、src/persist_write.c、src/persist_read.c可以看到现代 Mosquitto 已把敏感文件权限内置为统一的restrict_read机制umask(0077)open(..., 0600)O_NOFOLLOWO_EXCL四重保障新文件权限并对存量危险文件输出chmod 0700修复警告。这一演进路径也给所有以文件落盘的系统一个可复用的安全范式永远不要依赖运行环境的默认 umask敏感文件权限必须在每次创建时显式声明。赞分享物联网消息队列后端网络/通信【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mo/mosquitto点击查看免费下载相关推荐Eclipse Mosquitto 持久化文件权限漏洞 CVE-2017-9868 详解与防护指南Eclipse Mosquitto 持久化文件权限漏洞 CVE 2017 9868 详解与防护指南 漏洞概要 Mosquitto 0.15 至 1.4.12后端消息队列消息路由Eclipse Mosquitto CVE-2017-7650 安全公告解读pattern ACL 绕过漏洞的成因与修复方案Eclipse Mosquitto CVE 2017 7650 安全公告解读pattern ACL 绕过漏洞的成因与修复方案 导读 本文围绕 Mosquitt后端消息队列消息路由Eclipse Mosquitto 安全公告解读CVE-2017-7651 与 CVE-2017-7652 的漏洞原理、修复机制与 1.4.15 加固实践Eclipse Mosquitto 安全公告解读CVE 2017 7651 与 CVE 2017 7652 的漏洞原理、修复机制与 1.4.15 加固实践 本后端消息队列消息路由上一篇Tiger框架组件作用域管理Scope注解的实战技巧下一篇Unity翻译革新实战XUnity Auto Translator全流程解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考