尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Fleet 管理 Apple Silicon Mac 恢复锁密码(Recovery Lock Password):启用、查看、轮换与底层实现全解析

Fleet 管理 Apple Silicon Mac 恢复锁密码(Recovery Lock Password):启用、查看、轮换与底层实现全解析 Fleet 管理 Apple Silicon Mac 恢复锁密码Recovery Lock Password启用、查看、轮换与底层实现全解析【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleetFleet 的 Recovery Lock Password 功能允许 IT 管理员在纳入 Fleet MDM 管理的 Apple SiliconARMMac 上自动设置恢复锁密码当终端用户忘记本地登录密码或设备需要恢复时IT 团队可在 recoveryOS 界面输入该密码解锁设备。本文将围绕 articles/recovery-lock-password.md 的完整操作路径展开如何通过 UI、fleetctl 与 REST API 三种方式启用/禁用该功能如何查看与轮换密码并结合仓库源码深入讲解密码生成规则、AES-256 加密存储、MDM 命令占位符注入机制与状态机实现。读完本文你将掌握这套「服务端生成—加密存储—下发注入—审计追踪」完整链路以及在其之上排障和二次集成的关键依据。一、功能概述与前置条件Recovery Lock Password恢复锁密码是 Fleet Premium 专属功能Fleet 可以自动为已纳入 Fleet MDM 的 Apple Silicon Mac 生成恢复锁密码并在服务端完成加密与存储管理员可从 Fleet UI 或 API 查看、轮换该密码。当用户忘记本地账号密码或设备需要进入 recoveryOS 进行系统恢复时IT 管理员即可用该密码解锁设备从而避免设备因无法解锁而需要返厂或强制抹除。该功能解决的核心场景是在没有恢复锁的情况下丢失本地凭据的 Apple Silicon Mac 可能被完全锁死且 MDM 服务器也无法远程解锁。预先托管一个服务端可控的恢复锁密码等于为 IT 团队保留了一把「备用钥匙」。启用该功能需要满足以下前置条件macOS 主机必须为 Apple SiliconARM架构——恢复锁只支持 Apple Silicon Mac主机已纳入 Fleet MDM 管理enrolledFleet Premium 授权——该功能属于付费版能力从源码看轮换接口在非 EE 构建中直接返回ErrMissingLicense见 server/service/hosts.go。二、工作原理密码生成、加密存储与命令注入在介绍操作步骤之前先梳理该功能的三条核心实现原理这也是后续各操作的基础1. 密码格式与字符集Fleet 自动生成的密码由6 组、每组 4 个字母数字字符组成组间以短横线-分隔形如A3B7-C9D2-E5F8-G4H6-J2K9-L7M3。生成器定义在 server/mdm/apple/apple_mdm.go// RecoveryLockPasswordCharset excludes confusing characters (0/O, 1/I/l) const RecoveryLockPasswordCharset 23456789ABCDEFGHJKLMNPQRSTUVWXYZ字符集刻意排除了容易混淆的字符数字 0 与字母 O、数字 1 与字母 I/l提升人工抄写与口述时的可读性随机字节来自 Go 标准库的crypto/rand确保密码的不可预测性。2. AES-256 加密存储密码在落库前由服务端私钥加密。在 server/datastore/mysql/recovery_lock_password.go 的SetHostsRecoveryLockPasswords中encrypted, err : encrypt([]byte(p.Password), ds.serverPrivateKey)加密后的密文以blob形式写入host_recovery_key_passwords表encrypted_password/pending_encrypted_password字段数据库中从不保存明文密码。读取时通过 GetHostRecoveryLockPassword 使用同一把服务端私钥解密后返回。表结构定义在 server/datastore/mysql/schema.sql。3. MDM 命令占位符注入明文不落命令队列Fleet 下发的 MDM 命令中并不直接携带明文密码而是写入占位符在命令真正投递给设备时才展开。命令构造逻辑见 server/mdm/apple/commander.gocmdPayload : commandPayload{ CommandUUID: cmdUUID, Command: map[string]any{ RequestType: fleet.SetRecoveryLockCmdName, NewPassword: $ fleet.HostSecretPrefix fleet.HostSecretRecoveryLockPendingPassword, }, }其中占位符前缀与键名定义在 server/fleet/secrets.goHostSecretPrefix FLEET_HOST_SECRET_配对的RECOVERY_LOCK_PASSWORD与RECOVERY_LOCK_PENDING_PASSWORD分别对应「当前生效密码」与「待生效密码」。命令入队时是$FLEET_HOST_SECRET_RECOVERY_LOCK_PENDING_PASSWORD这类占位符投递瞬间由ExpandHostSecrets从host_recovery_key_passwords表中查出真实密码注入。这样明文密码永远不会出现在命令队列或数据库的日志行中降低了凭据泄露面。从源码结构看VerifyRecoveryLock使用待生效密码占位符commander.goVerifyRecoveryLockLastKnownPassword则使用当前生效密码占位符commander.go用于设备侧确认新旧密码是否已切换成功。三、启用 Recovery Lock Password启用后Fleet 会自动对当前选定 Fleet团队或全局无团队中所有符合条件的 Apple Silicon 主机下发设置命令。条件由 GetHostsForRecoveryLockAction 的 SQL 界定darwin平台 CPU 含arm MDM 已启用 排除 BYOD 个人注册设备 所在团队/全局配置开启该开关 尚无密码记录或密码处于待下发状态。为什么排除 BYOD源码注释说明个人注册personally-owned设备被 Apple 剥夺了DeviceLock/DeviceErase访问权限设备会直接拒绝SetRecoveryLock命令因此 Fleet 跳过而非强制执行见 recovery_lock_password.go。方式一Fleet UI进入Controls OS settings Passwords从下拉框中选择目标 Fleet团队勾选Turn on Recovery Lock password点击Save保存。保存后Fleet 开始自动为当前 Fleet 内符合条件的主机设置密码进度会显示在各主机的OS settings状态中。方式二fleetctlGitOps 配置即代码在团队fleet或无团队unassigned / global的 YAML 配置中在mdm键下添加开关mdm: enable_recovery_lock_password: true然后应用配置fleetctl apply -f config.yml对应的配置模型字段为mdm.enable_recovery_lock_password见 server/fleet/app.go未显式设置时默认值为falseserver/fleet/app.go。方式三REST API为无团队主机全局配置启用PATCH /api/latest/fleet/config请求体{ mdm: { enable_recovery_lock_password: true } }为指定 Fleet 启用PATCH /api/latest/fleet/fleets/{fleet_id}请求体{ config: { mdm: { enable_recovery_lock_password: true } } }四、查看密码UI 操作打开某台 macOS 主机的Host details主机详情页面点击Actions Show recovery lock password密码在弹窗modal中展示。查看行为会记录为一条活动activity同时出现在该主机的活动时间线与全局活动源中。从服务层实现看server/service/hosts.go查看流程还会做三件事校验权限先授权Host列表访问再按主机授权读权限校验平台非darwin或 CPU 不含arm的主机会直接返回错误recovery lock is only available on Apple Silicon macOS hosts状态门禁只有状态为verified的密码才会返回明文否则返回空密码并清空auto_rotate_at。值得注意的联动行为源码显示成功查看密码后会调用MarkRecoveryLockPasswordViewed把auto_rotate_at设为「当前时间 1 小时」即Fleet 会在你查看密码约 1 小时后自动轮换一次该密码从而降低密码被查看后的长期泄露风险见 server/datastore/mysql/recovery_lock_password.go 与 GetHostsForAutoRotation。APIGET /api/latest/fleet/hosts/{id}/recovery_lock_password该路由注册于 server/service/handler.go响应体包含recovery_lock_password字段见 server/service/hosts.go。五、轮换密码轮换会生成一个全新密码并通过 MDM 命令推送到设备。轮换要求maintainer 或更高角色。UI 操作两种入口入口一Actions 菜单打开主机Host details页面点击Actions Show recovery lock password在弹窗中点击Rotate password。入口二OS settings 状态指示器打开主机Host details页面点击主机摘要卡片中的OS settings指示器悬停hoverRecovery Lock password 行点击Rotate。APIPOST /api/latest/fleet/hosts/{id}/recovery_lock_password/rotate路由注册于 server/service/handler.go。需要注意的是RotateRecoveryLockPassword在服务层当前实现中直接返回fleet.ErrMissingLicense见 server/service/hosts.go即该能力实际由 Fleet Premium / EE 版本承载。轮换的底层约束轮换并不是无条件的数据层的 InitiateRecoveryLockRotation 通过一条 UPDATE 语句的 WHERE 条件限定了可轮换状态主机必须已有生效密码encrypted_password IS NOT NULL操作类型必须是install即当前不是正在移除密码当前状态必须是verified 或 failed不能是 pending/NULL不能已有挂起的轮换pending_encrypted_password IS NULL。若已有轮换在途返回ErrRecoveryLockRotationPending若其他条件不满足返回ErrRecoveryLockNotEligible并在错误信息中附带当前status与operation_type便于排障。六、状态跟踪Recovery Lock 密码状态与主机详情页的其他 OS settings 一并展示可能的状态如下状态含义VerifiedFleet 已成功为该主机设置恢复锁密码。Enforcing (pending)Fleet 正在为该主机设置恢复锁密码。Removing enforcement (pending)Fleet 正在为该主机移除恢复锁密码。FailedFleet 未能为该主机设置恢复锁密码。从数据库层看状态值存储在host_recovery_key_passwords.status字段并与mdm_delivery_status表外键关联。该字典表内包含failed、pending、verified、verifying四个状态见 server/datastore/mysql/schema.sql操作类型字典mdm_operation_types则包含install、remove两种schema.sql。查询状态的服务端实现见 GetHostRecoveryLockPasswordStatus——其中将 NULL 状态统一视作 pending命令入队失败后待重试并在主机摘要卡片的 OS settings 中展示server/service/hosts.go。七、禁用 Recovery Lock Password关闭方式与启用相同在 UI 中取消勾选或用 fleetctl 将enable_recovery_lock_password改为false后fleetctl apply或通过 API 提交{mdm: {enable_recovery_lock_password: false}}。关闭后Fleet 会向已纳入管理的主机下发清除clear命令移除恢复锁。清除流程由 ClaimHostsForRecoveryLockClear 驱动覆盖两类主机当前处于 install/verified即已有密码的主机以及上一次清除失败待重试operation_type 为 remove、status 为 NULL的主机。设备侧清除通过SetRecoveryLock命令实现其中CurrentPassword使用占位符注入、NewPassword为空字符串见 commander.go。边界情况处理若功能在「清除命令已入队但设备尚未确认」的窗口内被重新启用Fleet 会把该主机从 remove/pending 状态恢复为 verified而不是重新下发新密码——因为设备此时仍持有旧密码直接设置新密码会因缺少当前密码而失败。相关逻辑见 RestoreRecoveryLockForReenabledHosts。八、审计与活动记录Fleet 对恢复锁密码的每一次关键操作都会记录活动activity出现在主机活动时间线及全局活动源中。从 server/fleet/activities.go 可确认的活动类型包括set_host_recovery_lock_password——设置密码activities.goviewed_host_recovery_lock_password——查看密码activities.gorotated_host_recovery_lock_password——轮换密码区分用户手动触发与 Fleet 自动轮换FleetInitiated字段见 activities.goenabled_recovery_lock_passwords/disabled_recovery_lock_passwords——为某个 Fleet 启用/禁用该功能activities.go。启用/禁用活动的记录时机在 server/service/appconfig.go仅当全局配置中该开关值发生变化时才写入对应活动。九、与其他 MDM 功能的协作与冲突从 server/service/mdm.go 可以看到一个重要的协作规则当某主机所属团队或全局配置已启用 Recovery Lock 密码托管时Fleet 会阻止管理员手动向该主机下发SetRecoveryLock/VerifyRecoveryLock命令返回 HTTP 409 Conflict错误信息提示如需自定义密码请先关闭这些主机的 Recovery Lock 密码开关如需轮换应使用 Fleet 的轮换能力。这避免了「Fleet 托管的密码」与「管理员手写密码」互相覆盖导致的失管状态。十、数据安全与生命周期细节最后补充几个数据层细节便于理解该功能在极端情况下的行为归档与剪枝每条待下发密码在命令入队前会先写入归档表host_recovery_key_password_archivehost_uuid、加密密码、命令 UUID每台主机归档上限为 25 条maxArchivedRecoveryLockPasswordsPerHost 25。原因在于设备可能应用了密码但 Fleet 因结果丢失、中途 CheckOut 等原因未能感知重试会产生多份候选密码见 recovery_lock_password.go。验证即剪枝当设备确认持有某份密码SetRecoveryLockVerified后早于该份密码的归档记录会被删除因为设备状态的确认证明更早的密码必然已失效recovery_lock_password.go。生命周期联动主机重新注册或显式退管Apple 会随 MDM 描述文件移除而清空设备端恢复锁时Fleet 会软删除deleted1本地密码记录cron 也会兜底清理「MDM 已关闭但 Fleet 未收到 CheckOut/Authenticate 信号」的主机记录见 softDeleteHostRecoveryLockPassword。失败与重试命令入队失败会将状态复位为 NULL 以便下次 cron 重新拾取ClearRecoveryLockPendingStatusrecovery_lock_password.go设备侧失败则进入failed状态并记录error_message供排障SetRecoveryLockFailedrecovery_lock_password.go。结语Recovery Lock Password 是 Fleet MDM 在 Apple Silicon 设备上提供的一道重要「最后防线」通过服务端生成高可读性随机密码、AES-256 加密落库、MDM 命令占位符注入下发配合 UI / fleetctl / API 三通道的启用、查看、轮换、禁用操作与完整活动审计IT 团队得以在不暴露明文凭据的前提下始终握有解锁 recoveryOS 的能力。上述所有行为均可对照 server/datastore/mysql/recovery_lock_password.go、server/mdm/apple/commander.go 与 server/service/hosts.go 等仓库源码逐行验证这也是在生产环境排障与二次集成时最可靠的依据。【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表