Fleet 4.59.0 深度解析:Mac 开机安装应用、自动连接 Wi-Fi 与自定义 Apple MDM URL
【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet
本文基于 Fleet 开源仓库(Open device management)的 4.59.0 版本发布说明,聚焦三大核心能力:在 macOS 新机首次开机的 Setup Experience(设置体验)阶段阻塞屏幕并自动安装软件/运行脚本、通过 NDES SCEP 证书让终端用户自动连接 Wi-Fi,以及为 Apple MDM 流量配置独立的自定义 URL。读完本文,你将理解每个功能的配置路径、GitOps/YAML 写法、底层数据流,并掌握升级前需要执行的数据库迁移与回填 SQL。
版本概览:Fleet 4.59.0 带来了什么
Fleet 4.59.0 是 Fleet 设备管理平台的一个里程碑式版本,核心亮点集中在 macOS 自动部署(Setup Experience)与证书驱动的网络接入两大方向:
- Install apps during new Mac boot:在新 Mac 首次开机(macOS Setup Experience)阶段阻塞用户屏幕,先完成软件安装与脚本执行,再放行到桌面,确保工作站开箱即满足组织标准。
- Automatically connect end users to Wi-Fi:通过为所有 macOS 主机部署来自 NDES 的 SCEP 证书(作为 Wi-Fi/Ethernet 配置描述文件的一部分),实现终端用户的免手动安全网络接入。
- Custom URL for Apple MDM:设置独立的 Apple Server URL,将 MDM 流量与 Fleet 其他流量区分开,便于对 MDM 通信应用专门的网络规则。
此外,该版本还包含 OpenTelemetry 库升级、fleetd 向 Fleet 服务端上报致命错误(如 Fleet Desktop 无法启动)等 Endpoint operations 改进,以及大量 MDM、漏洞管理相关的修复。本文主体严格围绕上述三大亮点展开,并穿插源码级佐证。
亮点一:在新 Mac 开机阶段安装应用与运行脚本
功能定位:为什么要在用户看到桌面之前阻塞屏幕
在 4.59.0 之前,macOS 设备的软件安装、脚本执行大多发生在设备进入桌面之后,终端用户可能在使用过程中被安装窗口打扰,或在组织强制配置尚未生效前就访问了桌面资源。4.59.0 将 Setup Experience 能力进一步产品化:Fleet 可以在 macOS 首次开机的设置流程中阻塞用户屏幕,按序安装软件、运行脚本,直到所有要求的配置落地后再把控制权交给用户。
这一机制由 Fleet 服务端与设备上的 fleetd/orbit 协作完成:服务端把"待执行项"写入队列,设备端在 Setup Experience 对话框内轮询执行并回报状态。从源码结构看,其核心状态机位于 server/datastore/mysql/setup_experience.go,对应数据库表setup_experience_status_results(建表迁移见 server/datastore/mysql/migrations/tables/20241025112748_AddSetupExperienceResultsTable.go)。
队列入队逻辑:软件、VPP 应用与脚本如何被选中
EnqueueSetupExperienceItems(见 server/datastore/mysql/setup_experience.go#L23-L25)是入队入口,其内部enqueueSetupExperienceItems展示了 4.59.0 时期的关键行为:
- 平台判定:区分 host platform(如
darwin、ubuntu)、platform-like(如debian)与 Fleet 平台(如linux),用于精确匹配软件安装包;.deb只匹配 Debian 系、.rpm只匹配 RHEL 系、tar.gz/sh/py可安装于任意 Linux 发行版(见 server/datastore/mysql/setup_experience.go#L225-L246)。 - 24 小时防误入队守卫:已注册超过 24 小时的存量主机不会在 fleetd 升级后被重复入队(对应 issue #35717 的边界场景);对于 Windows 主机,还通过
mdm_windows_enrollments表的新鲜注册记录识别"重新入队"场景。 - 软件类型覆盖:支持软件安装器(
software_installers中install_during_setup = true的条目)、VPP 应用(Apple 商业应用)、iOS/iPadOS 的 in-house 应用;macOS 还允许把平台为linux的.sh/.py脚本包"跨界"选入 setup experience(见 server/datastore/mysql/setup_experience.go#L263-L297)。
从发布说明的变更列表看,4.59.0 为这套能力补齐了产品闭环:
- 新增Setup Experience 脚本的 UI(添加 setup experience script);
- 新增安装软件 Setup Experience 的 UI(install software setup experience);
- 新增Setup Experience 软件标题选择 API;
- 新增支持 Setup Experience 的数据库迁移;
- 新增Orbit 端点
POST /orbit/setup_experience/status,用于检查 macOS 主机 Setup Experience 各步骤状态; - 新增安装状态跟踪服务;
- 新增在自动注册(ADE/ABM)时排队安装 Setup Experience 软件的集成。
防止误删的校验规则
4.59.0 还增加了一条重要校验:如果某个软件包或 VPP 应用已被选中用于 Setup Experience 安装,则禁止把它从团队中移除。这避免了"注册流程引用了已被删除的软件"导致的部署中断,对应校验逻辑可在软件标题选择 API 的校验路径(server/datastore/mysql/setup_experience.go#L466-L742)中看到:SetSetupExperienceSoftwareTitles会校验所选标题必须真实存在、平台匹配,并返回at least one selected software title does not exist or is not available for setup experience这样的可读错误。
GitOps 配置:fleetctl gitops 如何指定开机脚本与软件
4.59.0 为fleetctl gitops增加了对 Setup Experience 的支持:可以为一个团队(或 no team)指定开机要运行的脚本与要安装的软件。对应 YAML 配置文档见 docs/Configuration/yaml-files.md#L565-L596,setup_experience段落的核心字段如下:
| 字段 | 含义 | 默认值/说明 |
|---|---|---|
bootstrap_package | bootstrap 包 URL,Fleet 会自行下载 | macOS only,默认"" |
macos_manual_agent_install | 是否在 Setup Experience 中安装 fleetd agent | macOS only,默认false |
enable_end_user_authentication | 首次设置主机时是否要求 IdP 认证 | macOS / Windows / Linux / iOS / iPadOS / Android |
require_all_software_macos | 任一软件安装失败时是否取消 macOS 设置流程 | macOS |
require_all_software_windows | 任一软件安装失败时是否取消 Windows 设置流程;为true时主机被阻塞在 Windows Enrollment Status Page,需重置设备重试;为false时列出失败项但允许继续进入桌面 | Windows |
lock_end_user_info | 是否允许用户在 macOS Setup Assistant 中编辑本地账户 Account Name / Full Name | 默认true |
apple_enable_release_device_manually | 启用后由你负责发送DeviceConfigured命令,否则用户会停留在 Setup Assistant | Apple(macOS/iOS/iPadOS)AB 自动注册 |
apple_setup_assistant | 自定义 ADE(自动注册)profile(.json)路径 | macOS / iOS / iPadOS |
macos_script | 首次设置后运行的 macOS 自定义脚本路径 | macOS only |
示例(fleets/fleet-name.yml或fleets/unassigned.yml):
setup_experience: bootstrap_package: "https://your-storage/package.pkg" macos_manual_agent_install: false enable_end_user_authentication: true lock_end_user_info: true apple_enable_release_device_manually: false apple_setup_assistant: "./setup_assistant.json" macos_script: "./post_setup.sh"软件层面的选择同样可以在 GitOps 中声明:对软件安装包条目设置setup_experience: true即可让该软件在主机注册时安装(默认false);对.sh脚本型软件包还可通过setup_experience_platform(可选值为darwin和linux,未指定且setup_experience: true时默认 Linux)指定目标平台(见 docs/Configuration/yaml-files.md#L683-L716)。此外,4.59.0 修复了fleetctl gitops对 VPP 应用的支持——现在可以同时在 GitOps 中指定 VPP 应用并将其设为 Setup Experience 安装项。
4.59.0 对 Setup Experience 的收尾调整
发布说明中有一项重要的架构调整:弃用了"自动释放 macOS 设备的 worker 型任务",改为由 fleetd 专属的/status端点(即上文提到的POST /orbit/setup_experience/status)在设置流程中被 Fleet 控制的 Setup Experience 对话框轮询。这意味着设备释放(release device)不再依赖服务端定时任务,而是由设备端主动回报步骤完成状态,减少了时序竞争与延迟。
亮点二:自动将终端用户连接到 Wi-Fi(NDES SCEP 证书)
机制:把 SCEP 证书塞进 Wi-Fi/Ethernet 描述文件
4.59.0 允许从 NDES(Network Device Enrollment Service)安装 SCEP 证书到所有 macOS 主机,证书作为 Wi-Fi/Ethernet 配置描述文件的一部分下发。当 Wi-Fi payload 中的PayloadCertificateAnchorUUID指向证书 payload 的 UUID 时,macOS 会自动用该证书完成 EAP 认证,终端用户无需手动输入证书或凭据即可接入受保护网络。
Fleet 在这里扮演的是"SCEP 代理"角色:设备不直接访问 NDES,而是通过 Fleet 的 SCEP 代理端点(profile 中的URL指向$FLEET_VAR_NDES_SCEP_PROXY_URL)请求证书,Fleet 代为与 NDES 交互,从而把挑战密码(challenge)等敏感信息安全地托管在服务端。完整的多 CA 部署指南见 articles/connect-end-user-to-wifi-with-certificate.md。
前置条件:连接 Fleet 与 NDES
在 [Fleet UI] 中进入Settings > Integrations > Certificate authorities,点击Add CA,选择Okta CA or Microsoft NDES(Okta 底层也走 NDES),填入:
- SCEP URL(默认形如
https://<NDES_SERVER>/certsrv/mscep/mscep.dll) - Admin URL(默认形如
https://<NDES_SERVER>/certsrv/mscep_admin/) - Username / Password
保存时 Fleet 会尝试连接 SCEP 服务器做连通性校验(包括获取一次性挑战密码),该校验同样发生在 API 与 GitOps(含 dry run)添加/更新 SCEP 配置时,因此请确保 NDES 密码缓存足够大——默认缓存仅 5 个一次性挑战密码,每次失败的注册尝试都会消耗一个,生产环境建议调大缓存。
添加 SCEP 配置描述文件
创建包含 SCEP payload 的配置描述文件,在Controls > OS settings > Configuration profiles中上传并下发。macOS 示例(源自 articles/connect-end-user-to-wifi-with-certificate.md#L244-L304):
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadContent</key> <array> <dict> <key>PayloadContent</key> <dict> <key>Challenge</key> <string>$FLEET_VAR_NDES_SCEP_CHALLENGE</string> <key>Key Type</key> <string>RSA</string> <key>Key Usage</key> <integer>5</integer> <key>Keysize</key> <integer>2048</integer> <key>Subject</key> <array> <array> <array> <string>CN</string> <string>%SerialNumber% WIFI</string> </array> </array> <array> <array> <string>OU</string> <string>$FLEET_VAR_CERTIFICATE_RENEWAL_ID</string> </array> </array> </array> <key>URL</key> <string>$FLEET_VAR_NDES_SCEP_PROXY_URL</string> </dict> <key>PayloadDisplayName</key> <string>WIFI SCEP</string> <key>PayloadIdentifier</key> <string>com.apple.security.scep.9DCC35A5-72F9-42B7-9A98-7AD9A9CCA3AC</string> <key>PayloadType</key> <string>com.apple.security.scep</string> <key>PayloadUUID</key> <string>9DCC35A5-72F9-42B7-9A98-7AD9A9CCA3AC</string> <key>PayloadVersion</key> <integer>1</integer> </dict> </array> <key>PayloadDisplayName</key> <string>SCEP proxy cert</string> <key>PayloadIdentifier</key> <string>Fleet.WiFi</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>4CD1BD65-1D2C-4E9E-9E18-9BCD400CDEDC</string> <key>PayloadVersion</key> <integer>1</integer> </dict> </plist>关键变量说明:
$FLEET_VAR_NDES_SCEP_CHALLENGE:Fleet 为每个主机生成的动态挑战密码;$FLEET_VAR_NDES_SCEP_PROXY_URL:指向 Fleet 的 SCEP 代理端点,设备经此与 NDES 通信;$FLEET_VAR_CERTIFICATE_RENEWAL_ID:必须放在证书的 OU(Organizational Unit)中,它是自动续期机制的锚点(见下文"续期"小节);- 若需证书按主机唯一,可修改
Subject,例如使用$FLEET_VAR_HOST_END_USER_EMAIL_IDP、$FLEET_VAR_HOST_HARDWARE_SERIAL等受支持变量。
下发后 Fleet 会替换变量再交给主机;任何失败都会显示在对应主机的Host details > OS settings页面。
Windows 主机的 NDES 证书(4.59.0 新增 SCEP 代理)
4.59.0 新增了面向 Windows NDES(AD CS 的 Network Device Enrollment Service)服务器的 SCEP 代理,允许 Windows 设备请求证书。对 Windows 部署还需额外准备:为非 AD 加入主机下发根 CA 证书(通过RootCATrustedCertificatesCSP)、确保 CRL 可通过 HTTP 访问(非 AD 主机无法访问 LDAP CRL)、确认 CA 服务器时钟准确(防止notBefore在未来导致证书被拒)。Windows 示例 profile 使用ClientCertificateInstallCSP 的 SCEP 节点,并通过$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID保证每台主机的唯一性,完整 XML 见 articles/connect-end-user-to-wifi-with-certificate.md#L314-L421。
证书自动续期规则
Fleet 会在证书过期前 30 天自动为 Apple(macOS/iOS/iPadOS)、Windows 和 Android 主机续期;若证书整个有效期 ≤ 30 天(如 20 天),则在其一半有效期(如 10 天)时续期。Linux 主机目前不支持自动续期,且自动续期仅在有效期 ≥ 2 天时可用。每次续期失败会重试(Apple 与 Android 每台主机最多 3 次,Windows 目前每台主机 1 次),每 30 秒检查一次待重发证书。注意:NDES/Smallstep/ACME/SCEP 类 CA 都要求$FLEET_VAR_CERTIFICATE_RENEWAL_ID出现在证书 OU 中;该变量是一个 36 字符 UUID,而 NDES 的 OU 最长 64 字符,因此与之组合的其他变量内容不要超过剩余 28 字符,否则会被截断导致续期失败。
亮点三:自定义 Apple MDM URL
为什么需要独立 MDM URL
默认情况下,Apple 设备与 Fleet 之间的 MDM 流量和 fleetd 的其他流量共用同一个 Fleet Server URL。对于需要区分流量、实施针对性网络规则(如对 MDM 端点做白名单或限流)的组织,4.59.0 允许配置mdm.apple_server_url:Apple 设备将使用该 URL 与 Fleet 实例进行 MDM 通信。该配置是可选的,未设置时 MDM 默认使用 Fleet Server URL。
在源码层面,该字段定义于 server/fleet/app.go#L229-L235:
// AppleServerURL is an alternate URL to be used in MDM configuration profiles to differentiate MDM // requests from fleetd requests on customer networks. AppleServerURL DNS should resolve to the // same IP as the Fleet Server URL. // If not set, the server will use Fleet server URL (recommended). AppleServerURL string `json:"apple_server_url"`注意注释中的两条硬约束:AppleServerURL 的 DNS 必须解析到与 Fleet Server URL 相同的 IP;未设置时使用 Fleet Server URL(推荐)。
配置步骤
准备 DNS:为 Apple MDM 流量创建一条 DNS 记录。示例:
- Fleet Server URL:
https://fleet.example.com 104.21.82.73 - Apple Server URL:
https://fleet-mdm.example.com 104.21.82.73 - 两个 URL 指向同一 IP,以确保 MDM 与非 MDM 流量都能被无缝处理。
- Fleet Server URL:
在 Fleet 中配置 Apple Server URL:
- UI 方式:Settings > Organization settings > Advanced options > Apple server URL,输入 MDM Apple Server URL。
- GitOps 方式:在 YAML 的
org_settings中声明:
org_settings: mdm: apple_server_url: "https://mdm.example.com"- 校验规则:服务端在配置变更时会对 URL 做校验,非法值会直接返回错误(见 server/service/appconfig.go#L1860-L1875 及其测试 server/service/appconfig_test.go#L1799-L1817):必须包含 URL scheme(如
https://),scheme 只能是http或https,且必须包含 host。
重要警告:改 URL 需要重新注册
在设备完成 MDM 注册之后再修改该 URL,将要求这些设备重新注册 MDM。因此最佳实践是在设备注册之前就完成配置。此外,4.59.0 在 UI 中新增了自定义 MDM URL 的配置字段,并修复了手动 Mac 注册配置下载时的字符集 header 问题。
变更与修复清单(4.59.0)
Endpoint operations
- OpenTelemetry 库升级到最新版本。启用 OpenTelemetry 后:HTTPS 事务之外的 MySQL span 现在会被记录;MySQL span 被重命名以包含查询内容,便于跟踪与调试。
- fleetd 现在可以把致命错误(如 Fleet Desktop 无法启动)上报给 Fleet 服务端。
Device management (MDM)
- 新增 Setup Experience 脚本 UI、安装软件 Setup Experience UI、软件标题选择 API、Setup Experience 相关数据库迁移。
fleetctl gitops支持为团队或无团队指定 Setup Experience 脚本与软件。- 新增 Orbit 端点
POST /orbit/setup_experience/status与安装状态跟踪服务。 - 新增连接 SCEP NDES 代理的能力;为 Windows NDES(AD CS 的 Network Device Enrollment Service)服务器新增 SCEP 代理,允许设备请求证书。
- My Device 页面在主机 MDM 关闭时新增错误提示;UI 新增自定义 MDM URL 配置字段。
- 新增在自动注册时排队 Setup Experience 软件安装的集成。
- 新增校验:若软件包或 VPP 应用被选中用于 Setup Experience 安装,则禁止将其从团队中移除。
- gitops 用户权限更新,允许运行 MDM 命令。
- 当设备从当前 ABM 中删除时,自动移除对应的 pending MDM 设备。
- 确保软件安装运行的详情在对应安装器被编辑或删除后仍然可用且准确。
安装详情回填 SQL(升级时可选执行)
4.59.0 的数据库迁移会基于当前已上传的安装器把安装器数据回填进安装详情。如果你希望从 activities(活动记录)回填——更全面、更准确,但会扫描整个 activities 表、可能较慢——请在运行数据库迁移之后执行以下查询:
UPDATE host_software_installs i JOIN activities a ON a.activity_type = 'installed_software' AND i.execution_id = a.details->>"$.install_uuid" SET i.software_title_name = COALESCE(a.details->>"$.software_title", i.software_title_name), i.installer_filename = COALESCE(a.details->>"$.software_package", i.installer_filename), i.updated_at = i.updated_at该查询是可选的:如果没有编辑过任何软件安装器,则无需执行。
Vulnerability management
- 软件 OS 视图新增平台过滤,可只显示某一平台(Windows、macOS、Linux 等)的 OS。
- 修复漏洞 cron 因计算主机问题数时创建超大临时表而无法完成的问题。
- 修复 Debian python 包误报漏洞:移除 dpkg 安装的 Debian python 包重复条目,并将剩余的 pip 安装包重命名以匹配 OVAL 定义。
Bug fixes 与改进精选
- 修复运行旧版 fleetd 主机上的 ADE 注册释放设备处理;修复 BYOD 注册页偶发 404。
- 修复 macOS/Linux 脚本在长时间运行命令时无法超时的问题;修复 ABM 续期流程中新 token 上传失败。
- 修复安装器包已更新或软件已从主机移除时,从活动记录获取安装详情出现空白状态的问题;修复 Edge 的 svg 图标;修复空白状态安装详情的前端报错。
- 修复 profile 状态聚合 UI 的加载状态;修复手动 Mac 注册配置下载的错误字符集 header。
- 修复
fleetctl gitops对 VPP 应用的支持(含将 VPP 应用设为 Setup Experience 安装项);修复PATCH /api/latest/fleet/config错误清空 VPP token 与团队关联的问题。 - 设备 token 过期时下载手动注册 profile 现在会显示错误提示。
- 修复 DDM 声明在发送到主机前从 Fleet 删除后永远保持 "pending" 的问题;修复主机被配置为不运行任何策略后,主机详情页策略失败未清除的问题。
- 修复 ADE 注册流程中 iOS/iPadOS 设备释放问题。
fleetctl gitops对非 Premium 许可用户忽略--delete-other-teams标志。- macOS pre-14 主机的 OS 升级 Nudge 截止时间从 04:00 UTC 改为 20:00 UTC。
- 安装/卸载详情不存在时新增更明确的错误信息。
FLEET_REDIS_ADDRESS现在允许带redis://前缀,合法格式为redis://host:port或host:port。- 文档说明:由于 MDM 注册流程的实现方式,Microsoft 注册在
mdm_enrolled活动中填写的字段较少。 - Disk encryption 表格整行可点击;策略自动化触发的软件安装活动以 "Fleet" 为作者,并在每条活动上存储策略 ID 与名称。
- 更新 bootstrap 包与 VPP 应用状态的 UI tooltip;用户创建端点新增 created_at/updated_at 时间戳。
- UI 通知交互改进:点击 flash 消息横向区域(消息之外)会隐藏消息,路由变化时也会隐藏。
- 非 MDM 注册设备上过滤掉 VPP 应用;"add profile" 消息显式设置行高以保持跨浏览器一致。
- 密码重置失败时改进 UI 反馈。
升级指引
升级到 Fleet 4.59.0 前,建议按顺序执行:
- 阅读 docs/Configuration/fleet-server-configuration.md 确认服务端配置项(含
FLEET_REDIS_ADDRESS格式变化); - 运行数据库迁移,然后视需要执行上文的活动回填 SQL(仅当迁移默认回填不足以覆盖你的安装详情时);
- 若计划使用三大新特性,提前准备:Setup Experience 所需软件包/脚本与 GitOps YAML、NDES 服务与 SCEP profile、自定义 MDM 域名的 DNS 记录(且务必在设备注册前配置
apple_server_url)。
仓库内的进一步参考:
- Setup Experience 数据层实现与测试:server/datastore/mysql/setup_experience.go、server/datastore/mysql/setup_experience_test.go
- 服务端 MDM 状态更新链路:server/service/apple_mdm.go#L5682、server/service/apple_mdm_cmd_results.go#L178
- 证书部署全平台指南:articles/connect-end-user-to-wifi-with-certificate.md
- 自定义 MDM URL 指南:articles/alternate-apple-mdm-url.md
- GitOps 配置参考:docs/Configuration/yaml-files.md
【免费下载链接】fleetOpen device management项目地址: https://gitcode.com/GitHub_Trending/fl/fleet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考