使用 Rclone 管理云存储

2020-02-01 • 更新于 2025-01-28

在没有图形界面的服务器上,或不想使用客户端软件时,如何方便地管理云存储是个问题。

Rclone 就是为此而生的,它可以方便在命令行下挂载网盘,例如 Google Drive、Dropbox、OneDrive 等,还支持 Amazon S3 对象存储服务。

除了速度慢一点外,还可以模拟本地磁盘,对于容量有限的 VPS 来说就是免费扩容,配合 aria2、Transmission 等工具,就可以打造离线下载服务器。

配合 aliyundrive-webdav 项目,可以以 WebDAV 方式挂载阿里云盘。

阿里云盘国内速度很不错,但国外就不太理想了垃圾,适合用作本地服务器备份 、在线播放电影等。支持上传文件,但受限于 WebDAV 协议不支持文件秒传。

安装

Debian 的官方源中 Rclone 版本过于陈旧,建议到官网下载:https://rclone.org/downloads/

或者脚本一键安装:

$ curl https://rclone.org/install.sh | sudo bash

Amazon S3 对象存储(2025 更新)

创建桶

赛博大善人 Cloudflare R2 兼容 S3,并且 10G 以内存储免费、出口流量免费,简直是个人和小型工作室的福报。

首先登录控制台,进入 R2 对象存储,绑定支付方式(例如 Visa),并创建一个桶。

创建完成后,如果只是私人使用(相当于网盘),不想暴露在公网,就不要设置自定义域和 R2.dev 子域,但用 Rclone 创建临时链接也是可行的。

如果设置了域,则可以当作图床等使用。

然后创建 API 令牌,按照喜好选择是管理所有桶还是指定桶。令牌页面只会显示一次,要妥善保管,配置 Rclone 时要用到。

Rclone 配置

运行 rclone config 进行配置,按提示来就可以了。

配置完成后,最好再编辑配置文件(通常为 ~/.config/rclone/rclone.conf),在对应配置下增加一行 no_check_bucket = true 以减少查询。

最终配置类似于:

[cf-r2]
type = s3
provider = Cloudflare
access_key_id = <key_id>
secret_access_key = <key>
endpoint = https://<user_id>.r2.cloudflarestorage.com
no_check_bucket = true

可以运行 rclone mount cf-r2:<桶名> <挂载路径> --vfs-cache-mode full --vfs-cache-max-age 24h 来挂载。

如果使用 Linux,后文有 Linux 下使用 /etc/fstab 自动挂载阿里云盘,依葫芦画瓢即可,这里不赘述了。

这里演示在 macOS 下如何自动挂载。创建 ~/Library/LaunchAgents/rclone-cf-r2.plist

<?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>KeepAlive</key>
	<true/>
	<key>Label</key>
	<string>rclone-cf-r2</string>
	<key>ProgramArguments</key>
	<array>
		<string>/usr/local/bin/rclone</string>
		<string>mount</string>
		<string>cf-r2:<桶名></string>
		<string><挂载路径></string>
		<string>--vfs-cache-mode</string>
		<string>full</string>
		<string>--vfs-cache-max-age</string>
		<string>24h</string>
	</array>
	<key>StandardErrorPath</key>
	<string>/usr/local/var/log/rclone-cf-r2.log</string>
	<key>StandardOutPath</key>
	<string>/usr/local/var/log/rclone-cf-r2.log</string>
	<key>RunAtLoad</key>
	<true/>
</dict>
</plist>

把 <桶名> 和 <挂载路径> 替换为自己的,接着加载:

$ launchctl load ~/Library/LaunchAgents/rclone-cf-r2.plist

即可自动挂载了,开机会自行启动。

下载速率实测北美可以跑到 30 MiB/s,国内电信晚高峰只有 4 MiB/s 左右,也不是不能用,比现在的阿里云盘快多了。

阿里云盘(2023 更新)

以下以 Debian 为例,运行阿里云盘 WebDAV 服务并使用 Rclone 自动挂载。

aliyundrive-webdav

首先安装 aliyundrive-webdav:

# pip install aliyundrive-webdav

我讨厌虚拟环境,因为它总是把东西封装得面目全非,所以这里用特权用户安装,而且方便之后编写 systemd 脚本。根据个人喜好即可。

获取 token:

# aliyundrive-webdav qr login

手机打开阿里云盘 APP 扫码得到 token。

为 WebDAV 服务专门建立一个目录,用于存放 token:

# mkdir /var/lib/private/aliyundrive-webdav
# vim /var/lib/private/aliyundrive-webdav/refresh_token

将 token 复制到 refresh_token 文件中。

新建 systemd 脚本:

# cat /etc/systemd/system/aliyundrive-webdav.service
[Unit]
Description=Aliyun Drive WebDAV Service
After=network-online.target

[Service]
DynamicUser=yes
StateDirectory=aliyundrive-webdav
ExecStart=/usr/local/bin/aliyundrive-webdav --host localhost --workdir "$STATE_DIRECTORY" --cache-ttl 10

[Install]
WantedBy=multi-user.target

/var/lib/private 是个特殊的目录。

systemd 脚本如果指定了 StateDirectory,就会从 /var/lib 寻找目标文件夹,通过 $STATE_DIRECTORY 来访问它。但如果同时指定了 DynamicUser=yes,就会在 /var/lib 建立一个软链接指向 /var/lib/private 中的同名目标文件夹:

# ll /var/lib/aliyundrive-webdav
lrwxrwxrwx 1 root root 26 Mar 21 16:48 /var/lib/aliyundrive-webdav -> private/aliyundrive-webdav

由于只有特权用户能访问 /var/lib/private,以此保证了安全性,这就是上面建立 /var/lib/private/aliyundrive-webdav 目录的原因。

aliyundrive-webdav 通过 --workdir 参数指定工作目录,就可以读取和更新 token 了。

# systemctl daemon-reload
# systemctl start aliyundrive-webdav.service
# systemctl enable aliyundrive-webdav.service
# systemctl status aliyundrive-webdav.service

/etc/fstab 自动挂载

Rclone 可以作为 Unix mount helper 实现 mount 命令的挂载:

# ln -s /usr/bin/rclone /sbin/mount.rclone

还可以添加到 /etc/fstab 中,这就很方便了,不需要写什么蛋疼的 systemd 脚本。

不过这一方法需要 fuse3(rclone mount 似乎 fuse2 就行 新版 rclone mount 也需要 fuse3 了):

# apt install fuse3
# vim /etc/fuse.conf

取消注释 user_allow_other,以允许其他用户访问挂载目录。

添加挂载项:

# mkdir /mnt/aliyun
# cat <<-END >>/etc/fstab
# https://rclone.org/commands/rclone_mount/#rclone-as-unix-mount-helper
:webdav: /mnt/aliyun rclone nofail,_netdev,args2env,webdav_url=http://localhost:8080,allow_other,vfs_cache_mode=full,vfs_cache_max_age=24h,cache_dir=/var/cache/rclone,config=/dev/null 0 0
END

第四列是关注的重点,各选项以 , 分隔,例如,需要以指定用户挂载,可以添加 uid=xxx,gid=xxx 选项。

注:

Debian 从最近(2023 年 9 月前后)某次更新后,原本第四列的 x-systemd.automount 将会导致 Fatal error: mount not ready,如果此时访问目录则会报错 Transport endpoint is not connected,原因不明,因此删去这个选项。

这个选项的作用是让目录在实际访问时挂载(延迟挂载),而不是开机就立即启动。

如果有其它需要的 rclone 参数也可以添加,但 GNU 风格的参数要手动翻译一下,前缀 -- 去掉,- 改为 _,例如 --vfs-cache-mode=full 要改为 vfs_cache_mode=full

看看成功了没有:

# mount -av

需要 debug 的话,在第四列添加 vv 以查看更详细的 log。

这一配置会自动挂载,而且只有在访问挂载目录时真正挂载。

OneDrive(写于 2020 年,可能已过时,仅供参考)

Rclone 提供了简单的交互式配置方式,运行 rclone config 即可,一般就是打开浏览器获取一个 token,网上有很多教程,在此就不赘述了。

以 OneDrive for Business 为例,主要说明一下如何在没有图形界面的情况下获取 token。

一种是先用其他带图形界面的系统配置一次,直接把 token 复制过去。

另一种就是在命令行下执行到这一步时:

Use auto config?
 * Say Y if not sure
 * Say N if you are working on a remote or headless machine
y) Yes
n) No
y/n> y
If your browser doesn't open automatically go to the following link: http://127.0.0.1:53682/auth?state=xxxxxxxxxxxxxxxxxxxxxx
Log in and authorize rclone for access
Waiting for code...

选择 y 的话理论上会打开浏览器访问那个地址,当然由于是服务器,不可能打开浏览器,这时我们重开一个 SSH 连接,并用 curl 访问:

$ curl http://127.0.0.1:53682/auth?state=xxxxxxxxxxxxxxxxxxxxxx
<a href="https://login.microsoftonline.com/common/oauth2/v2.0/authorize?access_type=offline&amp;client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&amp;redirect_uri=http%3A%2F%2Flocalhost%3A53682%2F&amp;response_type=code&amp;scope=Files.Read+Files.ReadWrite+Files.Read.All+Files.ReadWrite.All+offline_access&amp;state=xxxxxxxxxxxxxxxxxxxxxx">Temporary Redirect</a>.

复制 href 中的链接,对其 URL 解码,可以使用 Python 或其它工具,如:https://tool.chinaz.com/tools/urlencode.aspx

接着(客户端)使用浏览器访问解码后的 URL 并登陆账号,然后会重定向到一个本地 URL,在服务器上用 curl 访问此 URL。

这时 Rclone 的配置应该会自动进行到下一步,其它照常配置即可。如果不行就多试几次。

挂载

安装 FUSE:

$ sudo apt install fuse

将名为 onedrive 的配置挂载到 /mnt/onedrive 下:

$ rclone mount onedrive:/ /mnt/onedrive --vfs-cache-mode full --vfs-cache-max-age 24h --vfs-cache-max-size 12G

其中 vfs-cache-mode 可选参数为 off|minimal|writes|full,默认为 off,写入文件时无法随机寻址,因此无法用于 aria2、Transmission 等分块下载软件。writesfull 则可以很好地模拟本地文件系统,writes 模式下只读打开的文件无缓存,full 模式下读写均有缓存。

vfs-cache-max-age 设置缓存保存时间,vfs-cache-max-size 设置缓存大小。

有一个很重要的参数 --allow-other,表示允许其他用户访问挂载的目录,否则默认其他用户无法访问,不注意的话根本无从排查。而这个参数要求配置 fuse,将 /etc/fuse.conf 中的 user_allow_other 取消注释。--allow-root 参数允许 root 用户访问,同样需要设置 user_allow_other

参数 -vv 可查看 log 以排查错误,--daemon 以守护进程运行等。更多可参考:https://rclone.org/commands/rclone_mount/

查看一下是否已经挂载:

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
onedrive:       5.0T   18G  5.0T   1% /mnt/onedrive

开机自启

systemd 脚本:

$ cat /etc/systemd/system/rclone.service
[Unit]
Description=Rclone Service
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=username
ExecStart=/usr/bin/rclone mount onedrive:/ /mnt/onedrive --vfs-cache-mode full --vfs-cache-max-age 24h --vfs-cache-max-size 12G
ExecStopPost=/bin/fusermount -qzu /mnt/onedrive

[Install]
WantedBy=multi-user.target

其中 User 设置为所运行的用户。

我实际使用时,停止进程后无法自动取消挂载,文件夹异常,因此用 fusermount -qzu /mnt/onedrive 取消挂载。

另外,开机时 Transmission 可能会在 Rclone 之前运行,此时目录未挂载,Transmission 就会出错,于是修改其 systemd 脚本:

$ vim /lib/systemd/system/transmission-daemon.service

After=network.target 修改为 After=network.target rclone.service,这样 Transmission 就在 Rclone 后启动。

Linux

本作品根据 署名-非商业性使用-相同方式共享 4.0 国际许可 进行授权。

适配器模式 Adapter Pattern

生成器模式 Builder Pattern