CI 节点能打开网页,但依赖解析、签名上传或公证仍然失败,通常不是“网络不通”,而是白名单没有覆盖正确的流量阶段。
最快解法:不要放行全部 Apple 域名;本周先把 Xcode 27 CI 网络白名单按源码、依赖、Xcode 组件、签名发布、通知与管理服务拆分,并让每条规则绑定一次真实流水线验证。
这篇文章适合三类人:
企业网络与安全负责人:需要为 Mac CI 设计最小出站权限和变更审核依据。
平台工程负责人:正在交付 Xcode 27、Apple Silicon 与 CI Runner 环境。
采购与基础设施负责人:需要判断远程 Mac 构建机是否具备可验证的网络交付能力。
最后更新于 2026 年 9 月 21 日。 Apple 服务主机与端口、Xcode 27 运行条件、公证接口和 Runner 路由说明,已按本文引用的官方资料核对;企业内部域名、代理行为和远程节点交付能力仍必须以你的企业记录或实际验收为准。
SECTION 01 先建立故障时间线
Xcode 27 的 CI 流水线不应被看成一次“访问 Apple”的动作,而应拆成六个连续阶段:
- 源码拉取:访问 Git 仓库、Git LFS 或企业代码托管服务。
- 依赖解析:访问 Swift Package、CocoaPods、私有制品库和依赖缓存。
- 工具链获取:下载 Xcode 组件、Simulator Runtime、平台支持包或 Metal Toolchain。
- 构建与签名:访问开发者账号相关服务,读取证书、Provisioning Profile 或密钥服务。
- 上传与发布:向 App Store Connect、TestFlight 或企业发布系统提交构建产物。
- 公证与结果回传:提交公证请求、查询状态、获取日志、装订票据,并把结果回传到 CI 平台。
Xcode 27 官方发布说明确认,它只能安装和运行在 Apple Silicon Mac 上,并且相关版本对 macOS 条件有明确要求。这个信息只能用于确认节点系统与芯片是否合格,不能替代网络连通性验证。Apple Xcode 27 发布说明
你需要先记录四项证据:失败发生在哪个阶段、请求目标是什么、执行账号是谁、返回了什么错误。管理员终端可以成功,不代表 CI 服务账号也具备相同的代理变量、证书权限、DNS 解析和密钥访问权限。
构建节点的网络目标应该怎样整理?
不能先给一个永久不变的域名清单。应按节点承担的任务建立目标集合,例如源码托管地址、私有包源地址、Apple 服务地址、企业代理地址和内部制品库地址,再为每个目标记录端口、用途、代理要求、负责人和复核日期。
Apple 官方企业网络文档明确指出,设备会主动连接相关主机;如果 HTTPS 流量经过代理,部分 Apple 服务不支持 HTTPS Interception,也就是 TLS 解密检查。你的企业防火墙因此不能只看“TCP 443 是否放行”,还要确认代理是否对目标连接执行了证书替换。Apple 企业网络主机与端口要求
SECTION 02 源码与依赖出口
源码和依赖流量是最容易被误归入 Apple 白名单的部分。即使最终构建的是 iOS 应用,Git 仓库、Git LFS、Swift Package、CocoaPods 和私有制品库也可能分别使用不同的域名、认证方式和代理路径。
建议为每类节点单独定义访问范围:
- 普通 PR 构建节点:允许读取源码和公共依赖,不允许访问生产签名密钥。
- 依赖构建节点:允许连接私有包源、制品仓库和缓存回源地址,但应限制写入权限。
- 生产签名节点:只接收已经完成依赖锁定和安全检查的构建输入,不承担任意分支的依赖下载。
- 灾备节点:复制生产节点的规则版本,但必须单独验证 DNS、代理、凭证和恢复路径。
当 CI 服务账号无法访问 Apple 资源时,应该怎样定位?
先判断失败是否真的发生在 Apple 服务。若错误出现在 Package.resolved、私有 SSH 仓库、依赖压缩包或企业制品库,继续增加 Apple 域名不会解决问题。你应在 CI 服务账号下分别执行依赖解析、锁文件校验和缓存失效后的冷启动构建。
推荐把一次冷启动验收拆成以下动作:
whoami
env | grep -i proxy
scutil --proxy
xcode-select -p
xcodebuild -version
随后让流水线执行以下顺序:
git clone <源码地址>
git lfs pull
xcodebuild -resolvePackageDependencies
xcodebuild -showBuildSettings
xcodebuild archive <项目参数>
其中 <源码地址>、项目参数和内部包源必须替换为企业实际值。不要把管理员终端中的 SSH Agent、钥匙串解锁状态或代理配置直接视为 CI 服务账号的有效条件。
如果使用自托管 Runner,还要把标签、Runner Group 和网络区域绑定起来,避免任务被调度到没有私网出口或没有正确代理变量的节点。官方 Runner 文档说明,任务会依据标签和组匹配可用节点;当节点不满足条件时,任务可能持续排队,而不是自动获得另一条网络路径。GitHub Actions 自托管 Runner 说明 Runner 标签配置说明
SECTION 03 Apple 服务与工具链出口
Xcode 组件流量不应与普通构建流量混在一条“Apple 全部放行”规则里。Xcode 支持单独下载平台支持包、Simulator Runtime、硬件支持更新和 Metal Toolchain;这些动作可能只在节点初始化、版本升级或缓存失效时发生。Xcode 组件下载与安装说明
你可以把工具链出口分成三个时间点:
- 节点初始化:下载 Xcode 版本所需的组件,并记录安装包校验值、安装时间和执行账号。
- 版本升级:在变更窗口内下载新的 Simulator Runtime 或平台支持包,不允许生产流水线临时自行安装。
- 缓存失效:故意清理组件缓存,验证节点在受控代理下是否能够重新获取依赖。
Apple 的通用端口资料列出了 DNS、NTP、HTTP、HTTPS 和 SSH 等常见服务用途,但也明确说明,不同产品可能使用文档未列出的端口或服务。因此,端口清单只能作为初始审查依据,不能替代对真实请求的观测。Apple 软件产品 TCP 与 UDP 端口说明
Mac CI 的代理与防火墙规则应如何组合?
推荐采用“受控出站代理 + 目标服务白名单”的组合,而不是让 Mac 构建机直接访问任意互联网地址。规则至少要区分:
- 目标主机或企业内部服务;
- TCP 或 UDP 端口;
- 是否允许显式代理;
- 是否禁止 TLS 解密;
- 是否允许重定向;
- 规则的业务用途;
- 失败时需要采集的日志位置。
不要用 ping、浏览器打开主页或单次 curl 作为最终成功标准。Apple 服务可能要求完整的认证流程、特定请求路径或后续状态查询;浏览器成功只说明某个用户上下文能够访问某个页面。
SECTION 04 签名、上传与公证隔离
普通构建、归档、签名、上传和公证不应共用完全相同的出站权限。生产签名节点尤其不适合同时承担不可信分支的依赖下载、通用调试和任意脚本执行,因为这会把代码、凭证和网络访问集中到同一信任域。
App Store Connect API 使用 JWT 授权,令牌由私钥签名,密钥泄露后需要立即撤销。Apple 文档还说明,令牌的角色与权限范围取决于 API Key 类型和配置,因此网络白名单收紧并不能替代凭证最小化。App Store Connect API 密钥说明
企业签名发布节点可以按以下边界设计:
- 归档节点:允许源码、已批准依赖和构建缓存访问,不持有生产发布私钥。
- 签名节点:只接受经过审核的归档产物,访问签名服务、凭证存储和必要的 Apple 服务。
- 上传节点:只开放上传和结果查询路径,不允许任意源码下载。
- 公证节点:只处理需要公证的 macOS 产物,不与不可信构建任务混用。
生产签名节点的出站权限应怎样收敛?
最小范围通常包括:认证所需的 Apple 服务、上传目标、状态查询接口、日志获取接口、企业凭证服务和时间同步服务。具体主机必须根据你的发布流程生成,不能把开发者网站、App Store Connect、TestFlight 和公证服务简单合并成一个通配域名。
Apple 的 Notary API 支持提交软件、查询提交状态、获取日志和查看历史提交;因此公证验收不能只测“上传成功”,还要验证状态轮询、日志下载和票据装订。Apple Notary API 文档
一个完整的公证测试应至少包含:
xcrun notarytool submit <文件> --wait
xcrun notarytool log <submission-id>
xcrun stapler staple <应用或安装包>
xcrun stapler validate <应用或安装包>
命令中的文件路径和提交编号只使用测试产物。验收记录要保存提交结果、状态响应、日志文件和装订后的验证结果,不能只截取 CI 页面中的绿色状态。
SECTION 05 代理与 TLS 审计
很多“主机能联网、CI 失败”的问题,最终落在六层差异上:
- DNS 解析:管理员账号和 CI 服务账号是否得到相同地址。
- TCP 建连:防火墙是否允许目标端口,代理是否要求显式连接。
- TLS 握手:内部 CA 是否被服务账号信任,是否发生证书替换。
- 认证授权:API Key、证书、SSH 凭证或钥匙串是否可用。
- 业务请求:上传、状态查询、日志获取等路径是否都被放行。
- 流水线结果:构建产物是否被正确回传,失败日志是否完整保留。
注意: Apple 企业网络文档明确提示,相关 Apple 服务可能不接受 HTTPS Interception。若企业必须保留 TLS 检查,应先在隔离节点验证完整的下载、认证、上传和状态查询,而不是直接推到生产签名节点。
你还需要分别测试显式代理、透明代理、DNS 重写和内部 CA。相同 URL 在管理员终端与 CI 服务账号下的表现可能不同,尤其是在 HTTP_PROXY、HTTPS_PROXY、NO_PROXY、钥匙串访问和系统网络服务配置不一致时。
每条规则都应记录以下字段:
- 规则编号;
- 目标服务;
- 目标主机或变量;
- 端口与协议;
- 业务用途;
- 执行账号;
- 是否经过代理;
- 是否允许 TLS 解密;
- 验证命令或流水线;
- 失败日志位置;
- 变更负责人;
- 审批人;
- 下次复核日期;
- 回滚规则。
当 Apple 端点、企业代理策略或私有制品库发生变化时,不能只重新执行一次成功构建。应先在隔离节点更新规则,再执行完整流水线,最后决定是否推广到生产节点。
SECTION 06 上线验收清单
下面这份清单可以直接交给网络、安全和平台团队。每一项都要勾选,并附上请求日志或流水线编号。
普通构建节点
- [ ] CI 服务账号能够拉取指定源码分支。
- [ ] Git LFS 或等效大文件依赖能够完成冷启动下载。
- [ ]
xcodebuild -resolvePackageDependencies能在无缓存条件下完成。 - [ ] 依赖锁文件校验结果被保存。
- [ ] 节点不能读取生产签名私钥。
- [ ] 代理变量、DNS 配置和管理员终端差异已记录。
- [ ] 失败时能够关联到具体目标主机、端口和请求阶段。
依赖构建节点
- [ ] 私有 Swift Package、CocoaPods 或制品库地址已单独登记。
- [ ] 私有依赖访问使用服务账号,而不是个人凭证。
- [ ] 缓存命中和缓存失效两种路径都已验证。
- [ ] 依赖下载权限与制品上传权限已经分离。
- [ ] Runner 标签或节点组不会把任务路由到错误网络区域。
生产签名与发布节点
- [ ] 生产签名节点与普通构建节点使用不同网络策略。
- [ ] 归档、签名、上传和公证分别记录了请求目标。
- [ ] App Store Connect API Key 权限已按发布任务收敛。
- [ ] 公证提交、状态查询、日志获取和票据装订均已完成。
- [ ] 节点不执行未审核分支的任意依赖脚本。
- [ ] 私钥、证书和 Provisioning Profile 的访问日志可审计。
灾备与远程节点
- [ ] 灾备节点能够复现 DNS、TCP、TLS、认证和业务请求六层验证。
- [ ] 节点失联后,平台可以识别离线状态而不是继续分配任务。
- [ ] 网络策略、代理配置和规则版本有可回滚副本。
- [ ] 远程重连后能够重新执行一次冷启动构建。
- [ ] 远程 Mac 的私网依赖、企业代理和签名发布能力都有书面证据。
远程 Mac 节点的白名单交付应怎样验收?
不要只让供应方发送“443 已放行”的截图。你应要求节点执行一份固定验收包:DNS 解析记录、TCP 连接结果、TLS 证书链、CI 服务账号身份、依赖解析日志、Xcode 组件下载日志、签名上传结果和公证状态查询结果。若节点承担生产任务,还要安排一次失联、恢复和规则回滚演练。
最终结论可以分成四类:
- ✅ 放行:六层验证全部通过,日志完整,权限符合设计。
- ⚠️ 限期整改:功能可用,但代理、审计或权限记录不完整。
- 🧪 隔离试点:只能完成普通构建,不能承担生产签名或发布。
- ❌ 禁止上线:依赖来源不明、TLS 行为不可控、凭证无法隔离或失败证据不足。
如果你准备把远程 Mac 纳入企业 CI,建议先阅读 VPSNIX 帮助中心,把代理、私网依赖、签名发布和失联恢复列为交付前置条件;不要先按套餐周期采购,再反过来验证网络是否满足生产要求。
对比自购 Mac mini,本地设备的优势是网络路径完全由你控制,但你也要自行承担机房出口、硬件故障、远程电源、系统维护和备用节点建设;普通公有云主机则无法直接替代 Apple Silicon Mac 的 Xcode 构建环境。VPSNIX 的远程 Mac 方案更适合需要临时扩容、PoC 验证、跨地区 CI 节点或按周期交付真实 Mac 环境的团队,但是否适合生产签名,仍应以这份网络白名单和恢复验收结果为准。完成试点后,再根据节点数量与使用周期查看 VPSNIX 方案与价格,或通过 VPSNIX 订单页面提交具体的企业网络交付需求。