在没有图形界面的服务器上,或不想使用客户端软件时,如何方便地使用网盘是个问题。
Rclone 就是为此而生的,它可以方便在命令行下挂载网盘,目前已经支持包括 Google Drive、OneDrive 在内的几十个网盘,而且除了速度慢一点外,可以模拟本地磁盘,对于容量有限的 VPS 来说就是免费扩容,配合 aria2、Transmission 等工具,就可以打造离线下载服务器。
配合 aliyundrive-webdav 项目,可以以 WebDAV 方式挂载阿里云盘。阿里云盘国内速度很不错,但国外就不太理想了,适合用作本地服务器备份、在线播放电影等。支持上传文件,但受限于 WebDAV 协议不支持文件秒传。
安装
Debian 的官方源中 Rclone 版本过于陈旧,建议到官网下载:https://rclone.org/downloads/
或者脚本一键安装:
$ curl https://rclone.org/install.sh | sudo bash
阿里云盘(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&client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&redirect_uri=http%3A%2F%2Flocalhost%3A53682%2F&response_type=code&scope=Files.Read+Files.ReadWrite+Files.Read.All+Files.ReadWrite.All+offline_access&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 等分块下载软件。writes
或 full
则可以很好地模拟本地文件系统,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 后启动。