首页
/ 用 rclone 连接 iCloud:iCloud Drive 与 iCloud Photos 后端的配置、认证原理与实战指南

用 rclone 连接 iCloud:iCloud Drive 与 iCloud Photos 后端的配置、认证原理与实战指南

2026-09-07 14:25:13作者:殷蕙予

rclone 自 v1.69 起内置 iclouddrive 后端,可在一个 remote 中同时覆盖 iCloud Drive(默认服务)与 iCloud Photos(只读照片库)两大 Apple 云服务。本文以其官方文档 docs/content/iclouddrive.md 为骨架,结合仓库源码讲解完整的交互式配置流程、SRP-6a 免密上送认证机制、Photos 服务的层级结构与磁盘缓存、FUSE 挂载参数以及 Advanced Data Protection(ADP)下的故障排查方法,帮助你安全地备份、浏览与归档 iCloud 数据。

一、后端概览:一个 remote,两种服务

iclouddrive 后端在注册时即定义了两种服务类型(见 backend/iclouddrive/icloud.go 中的常量定义与 init 注册表):

服务值 含义 用途
drive(默认) iCloud Drive 访问 iCloud 云盘文件,支持读写
photos iCloud Photos 以只读层级树访问照片图库

选择在哪一层生效有三种方式:

  • rclone config 中新建 remote 时直接选定 service
  • 在配置文件中把已有 remote 的 service 改为 photos
  • 不改配置,仅在使用命令时追加 --iclouddrive-service photos 临时切换。

rclone config 之后路由到具体后端的逻辑位于 backend/iclouddrive/icloud.goNewServiceFs 解析 service 选项后,默认补为 drive,再分别分发到 Drive 的 NewFs 或 Photos 的 NewFsPhotos

需要留意的是平台支持范围:该后端本体带有 //go:build !plan9 && !solaris 构建标签,无法构建的平台上由 backend/iclouddrive/iclouddrive_unsupported.go 提供占位实现。

二、初次配置:交互式创建与 30 天信任令牌

创建 iCloud remote 的前提条件与注意事项:

  • 使用你常规的 Apple ID 密码,配合受信设备弹窗或短信的 2FA 验证码
  • ⚠️ 重要:不接受 App 专用密码(App-specific passwords),只能用普通密码 + 2FA。

以下示例创建一个专门用于照片的 remote icloudphotos。若只想用 iCloud Drive,让 service 保持默认值 drive 即可。首先执行:

rclone config

rclone 会引导你进入交互式配置流程(Storage 选项中的编号因版本而异,选择 iclouddrive 即可):

No remotes found, make a new one?
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
name> icloudphotos
Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
[snip]
XX / iCloud Drive
   \ (iclouddrive)
[snip]
Storage> iclouddrive
Option service.
iCloud service to use.
Choose a number from below, or type in your own value of type string.
Press Enter for the default (drive).
 1 / iCloud Drive
   \ (drive)
 2 / iCloud Photos
   \ (photos)
service> 2
Option apple_id.
Apple ID.
Enter a value.
apple_id> APPLEID
Option password.
Password.
Choose an alternative below.
y) Yes, type in my own password
g) Generate random password
y/g> y
Enter the password:
password:
Confirm the password:
password:
Edit advanced config?
y) Yes
n) No (default)
y/n> n
Option config_2fa.
Two-factor authentication: enter your 2FA code or type 'sms' for a text message
Enter a value.
config_2fa> 2FACODE
Remote config
--------------------
[icloudphotos]
- type: iclouddrive
- service: photos
- apple_id: APPLEID
- password: *** ENCRYPTED ***
- cookies: ****************************
- trust_token: ****************************
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y

最终写入配置的关键字段包括:typeserviceapple_idpassword(rclone obscure 加密存储)、cookiestrust_token(均以密文/掩码形式保存,由 rclone 自动维护,无需手工填写)。

信任令牌(trust token)有效期 30 天,到期后需重新认证。重新认证有两个途径:

# 交互式重建
rclone config
# 或仅刷新认证状态(对应 cmd/config/config.go 中 Use: "reconnect remote:" 的子命令)
rclone config reconnect icloudphotos:

在配置阶段的源码实现中,重新认证并不只是刷新令牌:当 config.State == "" 时,Config 函数主动丢弃旧的 trust token 与 cookies,强制走完整 SRP + 2FA 流程,确保每次 reconnect 都提示 2FA 而不是悄悄复用旧会话。

三、认证原理:SRP-6a 协议与 2FA 状态机

rclone 采用与 iCloud 网页端相同的 SRP(Secure Remote Password,安全远程密码)协议 与 Apple 身份服务通信。核心承诺是:你的密码永远不会被发送到 Apple 服务器——客户端用密码在本地派生密钥,与服务端交换密码学证明来验证“你知道密码”这一事实。

3.1 认证流程

  1. rclone 向 Apple 身份服务发起会话(源码中端点位于 api/client.goidmsa.apple.com/appleauth/auth 等);
  2. 完成 SRP 密钥交换——密码仅在本地用于派生密钥;
  3. Apple 向受信设备推送 2FA 提示,或允许你请求短信验证码;
  4. 输入 2FA 验证码后,rclone 获得可用于后续会话的 trust token 与 cookies。

3.2 SRP 参数与本地证明

SRP 客户端实现集中在 api/srp.go。它使用 RFC 5054 定义的 2048-bit 大素数群(g=2,SHA-256) 作为协商参数:客户端生成 32 字节随机私钥 a,计算公钥 A = g^a mod N 发送给服务端;收到服务端挑战后按 RFC 5054 校验 B 落在 1..N-1 区间,并拒绝计算得到 u = 0 的非法挑战,随后用 PBKDF2(SHA256) 派生的密码密钥、盐值与双方公钥计算会话密钥与证明值 M1/M2。服务器只能验证证明,拿不到明文密码。

3.3 2FA 交互状态机与短信通道

iCloud 的 2FA 存在多种形态,icloud.go 用显式的状态机覆盖了全部路径:

  • 若账号没有任何受信设备且配置了受信手机号,rclone 会跳过推送,直接自动触发短信流程(triggerSMSFlow);
  • 若存在受信设备,rclone 显式调用 RequestPushNotification 向设备推送验证码——这是针对 iOS 26.4+ 上 SRP 409 不再自动推送 的兼容处理,旧版本上可能产生一次无害的重复推送;
  • 用户在 config_2fa 处输入 6 位验证码,或输入 sms 改用短信;
  • 账号绑定多个手机号时,rclone 会先列出手机号供选择,再向所选号码发送短信;
  • 关键中间状态(SRP 会话等)被 base64 编码存入配置的 _auth_session 字段,以便在“获取验证码”与“校验验证码”两步之间复用会话,避免重复做一次 SRP 往返并触发第二次推送。

校验通过后调用 saveAuthCredentials:写入新的 trust_tokencookies,清空临时会话状态,并清除磁盘上旧的认证缓存。

3.4 会话保持与自动续期

日常使用时(非配置阶段),若配置中已存有 trust token,客户端通过 newICloudClienticloud.go)以最小开销恢复会话:优先复用已缓存的会话与服务端点,跳过昂贵的 /validate 往返。当请求遇到 401/421(会话过期)时会自动重认证并重放请求,详见 api/client.go;若此时仍被要求 2FA,则返回错误提示用户重新执行 rclone config reconnect

四、选择服务:--iclouddrive-service 命令行覆盖

如果不想为照片单独建一个 remote,也可以保留 service = drive 的通用 remote(如 iclouddrive:),在需要访问照片库时通过命令行开关临时切换:

# 列出照片图库(第一层即各个 Library)
rclone lsd iclouddrive: --iclouddrive-service photos

# 列出个人图库中的相册
rclone lsd iclouddrive:PrimarySync/ --iclouddrive-service photos

# 列出某相册中的全部照片/视频
rclone ls iclouddrive:PrimarySync/All\ Photos/ --iclouddrive-service photos

# 把一张 HEIC 照片下载到本地
rclone copy iclouddrive:PrimarySync/Favorites/IMG_0001.HEIC /tmp/ --iclouddrive-service photos

即两种用法等价,任选其一:

  • 配置时设 service = photos,得到专用于照片的 remote(如示例的 icloudphotos);
  • 配置保持 drive,按需在命令后追加 --iclouddrive-service photos

五、iCloud Photos 的层级结构与只读访问

service = photos 时,remote 呈现一棵只读的、根植于照片图库的层级树:

  • 第一层:照片图库(Library)——包括你的个人图库 PrimarySync,以及任何共享图库 SharedSync-XXXX
  • 第二层及以下:相册与文件夹——在 Apple Photos 中组织的嵌套结构原样呈现(相册可含子文件夹);
  • 叶节点:照片与视频文件——相册内的媒体资源,Live Photo 的 .MOV 伴随文件也会一并列出。

List 的层级分发逻辑见 icloudphotos.go:根 ID 下列出所有库(并附带各库相册数量),lib: 前缀的目录 ID 列出库内相册,album: 前缀的目录 ID 则列出相册内媒体或子文件夹。

5.1 需要注意的首次列举延迟

由于 Apple 照片 API 存在分页上限,超大相册(如含 75,000 个条目的 All Photos)首次冷列举可能需要数分钟。这个开销只在第一次发生——后续列举会命中磁盘缓存(详见下文缓存机制)。

5.2 只读限制

iCloud Photos 服务是只读的:上传、删除、重命名与移动均不受支持。从源码特性看,Photos 后端的能力集仅声明了 ReadMetadata 等只读特性(icloudphotos.go),没有暴露任何写接口。若把 Photos remote 当作普通可写目标使用,会收到明确的能力错误。

六、Photos 元数据:--metadata 下的五个只读键

启用 --metadata 后,iCloud Photos 的条目会暴露以下只读元数据(仅当 service = photos 时可用):

元数据键 含义 类型 示例值 只读
added-time 条目被加入 iCloud 图库的时间 RFC 3339 2006-01-02T15:04:05Z
favorite 是否标记为收藏 bool
height 图片高度(像素) int
hidden 是否被隐藏 bool
width 图片宽度(像素) int

这些键与 fs.RegInfo.MetadataInfo 中的注册完全一致(见 icloud.go),Photos 对象的 Metadata() 方法在读取时动态组装(icloudphotos.go)——added-time 内部以毫秒时间戳存储、对外格式化为 RFC 3339。rclone 元数据机制的整体用法可参考仓库文档 fs/operations/operations.md。

元数据的典型消费场景是备份后的筛选与检索,例如结合 rclone copy --metadata 保留收藏/隐藏标记,或配合 rclone lsjson 输出做相册级整理。注意 favoritehidden 等仅由元数据携带,不作为文件系统的真实“属性”持久化到目标。

七、磁盘缓存机制:首跑并行分页 + 轻量增量检查

iCloud Photos 会把相册清单缓存到本地磁盘,保证后续访问快速。这是反复列举大相册时体验差异巨大的关键机制。

7.1 首次冷列举:并行 startRank 分区

首次列举大相册时,Photos API 的 CloudKit 查询接口只支持按 startRank(记录偏移)遍历。rclone 将整个相册按 stride = photosQueryLimit/2(即每次 100 个照片)划分成多个分区,用多个 worker 并行拉取,见 api/photos.gofetchPhotosParallel

7.2 增量检查:约 200ms 的 changes/zone

此后再次访问,rclone 不再全量拉取:它会针对该 zone(图库)调用一次 changes/zone 接口,做一次约 200ms 的轻量变更检查batchCheckForChanges 甚至可把多个 zone 的检查合并进单个 API 调用,见 api/photos.go)。只有确认有变更时才失效并重建对应相册缓存;无变更则直接复用。变更结果按新增/删除/相册成员关系/元数据标记分类处理(parseDeltaRecords),并精确失效受影响的相册而非整库刷新。

7.3 缓存位置与清理

缓存目录按 remote 与图库 zone 隔离:

~/.cache/rclone/iclouddrive-photos/<remote>/<zone>/

其中 <remote> 是 remote 名称,<zone> 是图库 CloudKit zone(如 PrimarySync);目录由 Photos API 层的 cacheSubdir = "iclouddrive-photos" 常量拼接而来(api/photos.go),库元数据 libraries.json 与各 zone 的 albums.json 也存放在该命名空间下。缓存清理有两种方式:

  1. 直接删除该目录;
  2. 执行 rclone config reconnect <remote>:——它调用后端的 Disconnecticloudphotos.go),在清除认证状态的同时移除磁盘缓存。

八、FUSE 挂载 iCloud Photos 的推荐参数

将 iCloud Photos 以文件系统形式挂载浏览时,官方推荐如下组合:

rclone mount remote: /mnt/photos \
    --iclouddrive-service photos \
    --vfs-refresh \
    --dir-cache-time 1h \
    --vfs-cache-mode full \
    --attr-timeout 1m \
    --read-only

各参数作用与取舍:

  • --vfs-refresh:挂载启动时在后台预热目录缓存,浏览相册时即刻就绪;
  • --dir-cache-time 1h:把目录内存缓存寿命从默认的 5 分钟延长到 1 小时——由于后端增量变更检查很快,延长缓存是安全的;
  • --vfs-cache-mode full:把下载过的照片/视频落盘缓存到本地,重复访问走本地 IO;
  • --attr-timeout 1m:降低内核属性查找频率(后端只读,属性不会在挂载期内被外部改变,因此安全);
  • --read-only:避免对只读后端产生令人困惑的写错误。

再次强调:超大相册(如数万张照片的 All Photos)首次列出的等待不可避免,这是 API 分页限制所致;耐心等待一次后,后续浏览将由磁盘缓存接管。

九、Advanced Data Protection(ADP,高级数据保护)支持

iCloud Drive/Photos 后端支持开启 ADP 的账号,但有一个关键前提:

  • 在 iPhone 上进入 设置 > Apple 账户 > iCloud >,确保 “在网页上访问 iCloud 数据”(Access iCloud Data on the Web)为开启状态

若账号启用了 ADP,rclone 会在 2FA 之后额外请求 PCS cookies(一种端到端加密场景所需的授权 cookie)。Apple 可能在受信设备上弹出批准请求——必须手动批准,PCS cookie 才会签发。

从源码看,PCS cookie 的获取是按服务域(drivews/ckdatabasews)作用域的:api.NewpcsWSKey 参数决定了 cookie 归属哪个云服务,空值则完全跳过 PCS 流程(api/client.go),认证成功后统一由 ensurePCSCookies 保证存在(api/client.go)。

十、故障排查

10.1 PCS cookie 错误与 ADP 批准未完成

症状:出现 Missing PCS cookies from the request 或形如 requestPCS: 的错误。其含义是 ADP 账号所需的授权流程未成功完成——会话请求被服务端以 423(Locked) 判定为缺少 PCS cookie(见 api/client.go 对 423 的注释)。

解决步骤

  1. 确认 “在网页上访问 iCloud 数据” 已开启;
  2. 在受信设备上批准弹出的授权请求;
  3. 重新认证以获取新 cookie:
rclone config reconnect icloudphotos:
  1. 若 remote 仍残留过期认证状态,清空配置中的 cookiestrust_token 字段;仍不行则直接删除并重建该 remote。

十一、配置选项速查

以下为 iclouddrive 后端的全部选项(与文档自动生成部分一致)。

标准选项

选项 Config 键 环境变量 类型 默认值 说明
--iclouddrive-service service RCLONE_ICLOUDDRIVE_SERVICE string "drive" 取值 drive(iCloud Drive)或 photos(iCloud Photos)
--iclouddrive-apple-id apple_id RCLONE_ICLOUDDRIVE_APPLE_ID string 必填 Apple ID
--iclouddrive-password password RCLONE_ICLOUDDRIVE_PASSWORD string 必填 Apple ID 密码,输入必须用 rclone obscure 加密(见 rclone obscure 命令

密码之所以要求 obscure 存储,是因为后端在运行时会调用 obscure.Reveal 还原明文参与 SRP 推导(icloud.go),明文不能直接落盘。

高级选项

选项 Config 键 环境变量 类型 默认值 说明
--iclouddrive-client-id client_id RCLONE_ICLOUDDRIVE_CLIENT_ID string "d39ba9916b7251055b22c7f910e2ea796ee65e98b2ddecea8f5dde8d9d1a815d" 用于 iCloud API 访问的客户端 ID(一般无需修改)
--iclouddrive-encoding encoding RCLONE_ICLOUDDRIVE_ENCODING Encoding Slash,BackSlash,Del,Ctl,InvalidUtf8,Dot 后端编码配置,通用编码规则见 overview 的 encoding 一节
--iclouddrive-description description RCLONE_ICLOUDDRIVE_DESCRIPTION string remote 描述

运行时还有一组由 rclone 自动写入、用于保持认证状态的非交互键:trust_tokencookies 与临时 _auth_session。请勿手工改动,除非在执行故障排查里的“清空认证字段”步骤。

十二、实践要点总结

  • 认证安全:SRP-6a + 2FA 保证密码永不上传,30 天 trust token 到期后用 rclone config reconnect <remote>: 快速续期;
  • 照片访问两条路:专用 photos remote 或 --iclouddrive-service photos 临时切换,结构为 Library(如 PrimarySync) → 相册/文件夹 → 媒体文件
  • 性能关键在缓存:首次大相册列举较慢,之后 ~200ms 增量检查 + 磁盘缓存让重复访问近乎瞬时;需要释放空间时删 ~/.cache/rclone/iclouddrive-photos/ 或执行 reconnect;
  • 元数据是只读附加值--metadata 下仅 Photos 服务暴露 width/height/added-time/favorite/hidden
  • 挂载用只读姿态:配合 --vfs-refresh--vfs-cache-mode full--read-only 可获得流畅的浏览体验;
  • ADP 账号:先开“在网页上访问 iCloud 数据”,2FA 后在受信设备上批准 PCS cookie 请求,即可正常使用。

相关集成测试入口见 backend/iclouddrive/iclouddrive_test.go(基于 fstest/fstests 的标准后端一致性测试套件),版本演进记录可查阅 docs/content/changelog.md 中 iclouddrive 相关条目。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388