Mosquitto 1.1.3 发布解析:mosquitto_passwd 临时文件与备份机制的缺陷修复
后端消息队列消息路由【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mos/mosquitto点击查看免费下载导读本文基于 Eclipse Mosquitto 仓库中的 1.1.3 版本发布公告深入剖析这一 minor bugfix 版本的核心修复内容mosquitto_passwd工具改用tmpfile()生成临时数据文件并新增.backup备份文件用于错误恢复同时附带面向 Debian 打包的构建脚本修复。文章将结合仓库源码mosquitto_passwd.c还原修复前后的实现差异说明其可靠性提升的原理并给出当前版本下该工具的完整用法帮助你理解 MQTT broker 密码文件管理工具的设计演进与安全实践。1. 版本背景一次针对 Debian 打包问题的小版本修复Mosquitto 1.1.3 发布于 2013 年 2 月 11 日属于 minor bugfix 版本。根据官方发布说明见 ChangeLog.txt 中1.1.3 - 20130211条目本次发布旨在解决Debian 打包过程中暴露出来的一系列问题主要改动集中在两块Broker 侧mosquitto_passwd工具改用tmpfile()生成临时数据存储文件并创建可用于错误恢复的备份文件Other 侧构建脚本修复以改善 Debian 下的打包体验。与 1.1.2修复 TLS 证书校验默认值、1.1.1修复 ACL 模式下的崩溃问题不同1.1.3 没有引入新功能而是聚焦于密码文件写入过程的健壮性——这直接关系到使用密码认证的 broker 实例在升级或日常维护时的数据安全。2. 核心修复一mosquitto_passwd 改用 tmpfile() 生成临时文件2.1 修复前的问题背景在 1.1.3 之前mosquitto_passwd更新密码文件时如何安全地写入临时数据是一个隐患。在 Debian 等发行版打包流程如构建期自动化测试、脚本化密码初始化中以下两类问题尤其突出临时文件路径可预测如果临时文件使用固定或可猜测的路径如/tmp/下带固定文件名的文件在多用户环境中可能被恶意预创建或替换symlink 攻击导致数据被破坏或权限提升。写入中断无恢复手段一旦在写入过程中发生错误磁盘满、进程被杀、并发访问原密码文件可能处于半更新状态无法回退到修改前的有效内容。2.2 修复方案tmpfile() 匿名临时文件修复后源码中引入了mpw_tmpfile()封装函数mosquitto_passwd.c在不同平台上有两种实现Windows 平台直接调用标准 C 库的tmpfile()由系统负责在合适的临时目录中创建并管理文件非 Windows 平台POSIX实现更精细——先用 OpenSSL 的RAND_bytes()生成 32 字节随机数据映射为字母数字字符构造出形如/tmp/32位随机串-XXXXXX的模板路径随后调用mkstemp()以安全方式创建文件此时umask(077)确保仅属主可读写最后立即unlink()该路径但保留文件描述符继续使用。这一做法的关键收益在于特性说明路径不可预测随机命名 mkstemp()原子创建避免 symlink 竞态与预创建攻击匿名文件unlink()后文件不再存在于目录项中进程崩溃或异常退出也不会遗留敏感临时文件权限收紧umask(077)保证临时文件仅创建者可访问密码哈希不会暴露给其他用户自动清理进程结束或fclose()后系统自动回收磁盘空间从源码看这个临时文件被用作“新内容先写入临时文件再整体回写原文件”两段式提交的一部分详见第 3 节。2.3 修复后的写入流程结合源码以交互式更新单个用户密码为例主流程位于main()中mosquitto_passwd.c以rt模式打开现有密码文件fptr构造备份文件名原文件.backup.XXXXXX并调用create_backup()生成备份见下节通过mpw_tmpfile()创建匿名临时文件ftmp根据操作类型调用delete_pwuser()/update_file()/update_pwuser()等回调这些回调经由 pwfile_iterate() 逐行遍历原文件、将更新后的内容写入临时文件copy_contents(ftmp, fptr)将临时文件内容整体复制回原密码文件若全部成功unlink(backup_file)删除备份若复制失败则提示用户检查备份文件恢复数据。这种先写临时文件、后回写原文件的模式把部分更新的风险限制在最后一次复制操作内配合备份文件形成完整的容错闭环。3. 核心修复二备份文件机制错误时可恢复数据3.1 备份文件的创建create_backup()mosquitto_passwd.c负责在修改前保存原文件内容非 Windows 下同样使用mkstemp()生成原文件.backup.XXXXXX的安全临时文件并设置umask(077)通过copy_contents()将原密码文件全部内容复制进备份文件完成后rewind(fptr)将原文件指针复位供后续逐行处理。3.2 备份文件的生命周期从main()的控制流mosquitto_passwd.c可以清晰看到备份文件的三种结局处理失败rc ! 0立即unlink(backup_file)清理备份并退出避免残留旧密码哈希回写失败打印Password file may be corrupt, check the backup file: %s.错误信息保留备份文件供管理员手工恢复全部成功注释明确说明Everything was ok so backup no longer needed. May contain old passwords so shouldnt be kept around随即删除备份防止旧密码哈希长期滞留磁盘。这一机制保证了在任何步骤出错时管理员都能从.backup.*文件中找回修改前的密码数据库而正常成功后不会留下多余副本。3.3 与密码文件校验的配合需要说明的是这是工具层面的容错。broker 在启动加载密码文件时另有校验逻辑password_file选项解析与校验位于 src/password_file.c两者配合可以在写入前校验 写入时备份两个层面共同保障认证数据的可用性。4. 构建脚本修复面向 Debian 打包的改进发布说明中的第二项改动是Build script fixes to help packaging on Debian。结合仓库现状这属于打包流程层面的调整——确保make/configure生成的产物、安装路径与 Debian 的dpkg打包规范兼容。仓库根目录的 Makefile、config.mk 以及各子目录如 apps/mosquitto_passwd/Makefile共同构成了跨平台构建体系1.1.3 针对 Debian 的修复为该体系后续在各类发行版中稳定打包奠定了基础。从当前仓库的源码组织看这一方向最终演进为 README-compiling.md 中记载的完整编译指南以及CMakeLists.txt/Makefile双构建系统并存的结构。说明由于发布公告未给出具体 diff且 1.1.3 距今已远本节仅基于公告文本与仓库现状作事实性转述不再进一步推断细节。5. 延伸当前版本 mosquitto_passwd 的完整用法1.1.3 引入的tmpfile()与备份机制在后续版本中持续保留并演进当前源码中的mpw_tmpfile()/create_backup()即为其直接后代。为方便实战这里结合仓库中 man/mosquitto_passwd.1.xml 与源码print_usage()mosquitto_passwd.c给出当前版本的工具全貌5.1 命令语法mosquitto_passwd [-H argon2id | -H sha512-pbkdf2] [-c | -D] passwordfile username mosquitto_passwd [-H argon2id | -H sha512-pbkdf2] [-c] -b passwordfile username password mosquitto_passwd -U passwordfile5.2 主要选项选项含义-b批处理模式密码直接写在命令行注意会暴露在 shell 历史中-c创建新密码文件会覆盖已存在的文件-D从密码文件中删除指定用户名-H指定哈希算法argon2id当前默认、推荐或sha512-pbkdf2Mosquitto 2.0 及更早版本默认sha512-pbkdf21.6 及更早版本默认sha512-U将纯文本密码文件升级为哈希密码文件5.3 典型操作示例# 创建新密码文件并添加用户交互式输入密码 mosquitto_passwd -c /etc/mosquitto/passwd alice # 批处理模式添加/更新用户 mosquitto_passwd -b /etc/mosquitto/passwd alice s3cret! # 删除用户 mosquitto_passwd -D /etc/mosquitto/passwd bob # 将旧版纯文本密码文件升级为哈希格式 mosquitto_passwd -U /etc/mosquitto/passwd5.4 在 broker 中的接入生成的密码文件通过 broker 配置的password_file选项启用见 mosquitto.confallow_anonymous false password_file /etc/mosquitto/passwdallow_anonymous false关闭匿名访问password_file指向上述工具生成的哈希密码文件二者配合即可实现基于用户名/密码的 MQTT 客户端认证。哈希与校验的具体实现位于 libcommon/password_common.c含 argon2id、sha512-pbkdf2、sha512 三种算法的创建/校验/编码/解码broker 侧加载与解析则在 src/password_file.c 完成。6. 小结Mosquitto 1.1.3 虽然只是一个小版本但其两处修复都具有长远的可靠性价值tmpfile()临时文件机制从源头规避了临时文件路径预测与敏感数据残留问题备份文件机制让密码文件更新在任何失败场景下都可回滚、可恢复Debian 构建修复改善了生态打包体验为后续发行版分发铺平道路。这两项关于安全写文件的设计——随机命名、mkstemp()原子创建、umask(077)收紧权限、匿名文件即时unlink()、备份文件按结果保留或清理——至今仍完整保留在 apps/mosquitto_passwd/mosquitto_passwd.c 中是阅读 Mosquitto 工具链代码、理解安全文件更新模式的绝佳范例。延伸阅读仓库内版本发布说明原文www/posts/2013/02/version-1-1-3-released.md完整版本历史ChangeLog.txt工具实现源码apps/mosquitto_passwd/mosquitto_passwd.c密码哈希算法实现libcommon/password_common.cbroker 密码文件解析src/password_file.c官方手册man/mosquitto_passwd.1.xml编译指南README-compiling.md赞分享后端消息队列消息路由【免费下载链接】mosquittoEclipse Mosquitto - An open source MQTT broker项目地址https://gitcode.com/gh_mirrors/mos/mosquitto点击查看免费下载相关推荐Cilium CLIcilium命令参考基于 Helm 安装、升级与排障 Cilium 的完整指南Cilium CLIcilium命令参考基于 Helm 安装、升级与排障 Cilium 的完整指南 cilium 是 Cilium 项目自带的命令行工具后端消息队列消息路由Mosquitto 2.0.13 发布Broker 与客户端库关键缺陷修复全解析Mosquitto 2.0.13 发布Broker 与客户端库关键缺陷修复全解析 Mosquitto 2.0.13 是 Eclipse Mosquitto 在后端消息队列消息路由Eclipse Mosquitto 0.11.3 发布解析六个关键缺陷修复与持久化、会话接管机制详解Eclipse Mosquitto 0.11.3 发布解析六个关键缺陷修复与持久化、会话接管机制详解 本文以 Eclipse Mosquitto 0.11.3后端消息队列消息路由创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考