科技云盘 (CSTCloud) rclone WebDAV 连接配置文档

背景

科技云盘(CAS Cloud Box)提供了 WebDAV 协议接口,可用于第三方应用访问和管理文件。然而,科技云盘的 WebDAV 服务器仅支持 Digest 认证 ,而 rclone 的 WebDAV 后端仅支持 Basic 认证 ,两者不兼容会导致 401 Unauthorized 错误。

为解决此问题,本方案通过一个运行在本地的 Python 反向代理来桥接 rclone 和科技云盘,由代理负责处理 Digest 认证。

架构

复制代码
rclone (无认证) ──> 本地代理 (127.0.0.1:18080) ──Digest认证──> pan.cstcloud.cn/DAV/

文件清单

文件 用途
~/.config/rclone/rclone.conf rclone 配置文件,指向本地代理
~/.config/rclone/webdav_digest_proxy.py Python 反向代理脚本,处理 Digest 认证
~/Library/LaunchAgents/com.rclone.webdav-proxy.plist macOS launchd 服务配置,开机自动启动代理
/etc/systemd/system/webdav-proxy.service Linux systemd 服务配置,开机自动启动代理

配置详情

1. rclone 配置 (~/.config/rclone/rclone.conf)

ini 复制代码
[remote]
type = webdav
url = http://127.0.0.1:18080/个人文件/
vendor = other
  • url 指向本地代理地址,路径 /个人文件/ 对应科技云盘的个人文件目录
  • 无需配置 userpass,认证由代理处理

2. WebDAV Digest 代理 (~/.config/rclone/webdav_digest_proxy.py)

代理脚本的核心配置参数位于文件顶部:

python 复制代码
UPSTREAM = "https://pan.cstcloud.cn/DAV/"   # 科技云盘 WebDAV 地址
USER = "XXXX@XXXX"               # 科技云盘账号
PASS = "XXXXXXXX"                   # WebDAV 授权密码
PORT = 18080                                # 本地监听端口

代理的工作流程:

  1. 监听 127.0.0.1:18080,接收 rclone 发来的 HTTP 请求
  2. 将请求转发到 pan.cstcloud.cn,自动附加 Digest 认证头
  3. 将响应中的绝对路径 (https://pan.cstcloud.cn/DAV/...) 改写为相对路径 (/...),使 rclone 能正确解析目录结构
  4. 返回处理后的响应给 rclone

依赖:Python 3 + requests 库(系统已安装)。

3. 服务管理(开机自启)

macOS --- launchd

服务配置文件:~/Library/LaunchAgents/com.rclone.webdav-proxy.plist

  • RunAtLoad: 登录时自动启动
  • KeepAlive: 进程退出后自动重启
  • 日志路径 : /tmp/webdav-proxy.log
Linux --- systemd

服务配置文件:/etc/systemd/system/webdav-proxy.service(系统级)或 ~/.config/systemd/user/webdav-proxy.service(用户级)

推荐使用用户级服务,无需 root 权限。创建步骤:

bash 复制代码
mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/webdav-proxy.service << 'EOF'
[Unit]
Description=CSTCloud WebDAV Digest Auth Proxy
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 %h/.config/rclone/webdav_digest_proxy.py
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

# 安全加固
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=default.target
EOF

%h 是 systemd 变量,会自动替换为当前用户的 home 目录。

启用并启动服务:

bash 复制代码
systemctl --user daemon-reload
systemctl --user enable webdav-proxy.service   # 开机自启
systemctl --user start webdav-proxy.service    # 立即启动

如果希望在用户未登录时也保持服务运行(适用于服务器环境):

bash 复制代码
sudo loginctl enable-linger $USER
Linux(无 systemd 用户会话)--- nohup + crontab

在共享实验室服务器、HPC 集群等环境中,普通用户通常没有 systemd 用户会话(systemctl --userFailed to get D-Bus connection: Connection refused)。此时使用 nohup + crontab 方案:

启动代理:

bash 复制代码
nohup python3 ~/.config/rclone/webdav_digest_proxy.py > /tmp/webdav-proxy.log 2>&1 &

设置开机/重启后自动启动(crontab):

bash 复制代码
(crontab -l 2>/dev/null; echo '@reboot nohup python3 $HOME/.config/rclone/webdav_digest_proxy.py > /tmp/webdav-proxy.log 2>&1 &') | crontab -

验证 crontab 是否写入成功:

bash 复制代码
crontab -l | grep webdav

管理代理进程:

bash 复制代码
# 查看代理是否运行
ps aux | grep webdav_digest_proxy | grep -v grep

# 停止代理
kill $(pgrep -f webdav_digest_proxy)

# 重启代理
kill $(pgrep -f webdav_digest_proxy) 2>/dev/null
nohup python3 ~/.config/rclone/webdav_digest_proxy.py > /tmp/webdav-proxy.log 2>&1 &

# 查看日志
tail -f /tmp/webdav-proxy.log

如何判断用哪种方案? 运行 systemctl --user status ,如果报 Failed to get D-Bus connection 就用 nohup + crontab 方案,否则用 systemd 方案。

常用操作

使用 rclone 访问云盘

由于本机配置了 HTTP 代理(http://127.0.0.1:7890),访问本地代理时需设置 no_proxy 环境变量以避免请求被转发到外部代理。

bash 复制代码
# 列出目录
no_proxy='*' rclone lsd remote:

# 列出所有文件
no_proxy='*' rclone ls remote:

# 列出指定目录的文件
no_proxy='*' rclone ls remote:科研/

# 上传文件到云盘
no_proxy='*' rclone copy /path/to/local/file remote:目标目录/

# 从云盘下载文件
no_proxy='*' rclone copy remote:科研/paper.pdf /path/to/local/

# 双向同步
no_proxy='*' rclone sync /path/to/local/ remote:目标目录/

# 挂载为本地磁盘(前台运行,Ctrl+C 卸载)
no_proxy='*' rclone mount remote: /tmp/cstcloud --vfs-cache-mode full

可在 ~/.zshrc 中添加别名简化操作:

bash 复制代码
alias rpan='no_proxy="*" rclone'

之后即可直接使用 rpan ls remote: 等命令。

管理代理服务

macOS
bash 复制代码
# 查看代理运行状态
launchctl list | grep webdav-proxy

# 查看代理日志
cat /tmp/webdav-proxy.log

# 停止代理服务
launchctl unload ~/Library/LaunchAgents/com.rclone.webdav-proxy.plist

# 启动代理服务
launchctl load ~/Library/LaunchAgents/com.rclone.webdav-proxy.plist

# 重启代理服务(停止 + 启动)
launchctl unload ~/Library/LaunchAgents/com.rclone.webdav-proxy.plist && \
launchctl load ~/Library/LaunchAgents/com.rclone.webdav-proxy.plist

# 确认代理正在监听
lsof -i :18080
Linux
bash 复制代码
# 查看代理运行状态
systemctl --user status webdav-proxy

# 查看代理日志
journalctl --user -u webdav-proxy -f

# 停止代理服务
systemctl --user stop webdav-proxy

# 启动代理服务
systemctl --user start webdav-proxy

# 重启代理服务
systemctl --user restart webdav-proxy

# 确认代理正在监听
ss -tlnp | grep 18080

更新 WebDAV 授权密码

科技云盘的 WebDAV 授权密码可能会过期,需要重新生成:

  1. 打开 科技云盘应用管理页面

  2. 点击顶部的「应用管理」标签

  3. 如果已有密码,点击「删除密码」,确认删除

  4. 点击「设置密码」→「生成密码」→「保存并复制」

  5. 编辑代理脚本,更新密码:

    bash 复制代码
    vim ~/.config/rclone/webdav_digest_proxy.py
    # 修改 PASS = "新密码"
  6. 重启代理服务:

    bash 复制代码
    # macOS
    launchctl unload ~/Library/LaunchAgents/com.rclone.webdav-proxy.plist
    launchctl load ~/Library/LaunchAgents/com.rclone.webdav-proxy.plist
    
    # Linux
    systemctl --user restart webdav-proxy
  7. 验证连接:

    bash 复制代码
    no_proxy='*' rclone lsd remote:

访问群组文件

默认配置访问的是「个人文件」目录。如需访问「群组文件」,修改 rclone.conf

ini 复制代码
[remote-group]
type = webdav
url = http://127.0.0.1:18080/群组文件/
vendor = other

然后使用 no_proxy='*' rclone ls remote-group: 访问。

Linux 完整部署指南

以下是在一台全新 Linux 机器(Ubuntu/Debian/CentOS 等)上从零部署的完整步骤。

第一步:安装依赖

bash 复制代码
# Ubuntu / Debian
sudo apt update && sudo apt install -y python3 python3-pip rclone
pip3 install requests

# CentOS / RHEL / Fedora
sudo dnf install -y python3 python3-pip rclone
pip3 install requests

# Arch Linux
sudo pacman -S python python-requests rclone

如果系统源中的 rclone 版本过旧,可使用官方安装脚本:

bash 复制代码
curl https://rclone.org/install.sh | sudo bash

第二步:部署代理脚本

bash 复制代码
mkdir -p ~/.config/rclone

cat > ~/.config/rclone/webdav_digest_proxy.py << 'PYEOF'
#!/usr/bin/env python3
"""Local reverse proxy: rclone (no auth) -> CSTCloud WebDAV (Digest auth)."""

import re
import sys
from http.server import HTTPServer, BaseHTTPRequestHandler
import requests
from requests.auth import HTTPDigestAuth

UPSTREAM = "https://pan.cstcloud.cn/DAV/"
USER = "XXXX@XXXX"       # <-- 替换为你的账号
PASS = "XXXXXXXX"           # <-- 替换为你的 WebDAV 授权密码
PORT = 18080

session = requests.Session()
session.auth = HTTPDigestAuth(USER, PASS)


class ProxyHandler(BaseHTTPRequestHandler):
    def _proxy(self):
        path = self.path.lstrip("/")
        url = UPSTREAM + path

        content_length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(content_length) if content_length else None

        headers = {}
        for key in ("Depth", "Destination", "Overwrite", "Content-Type",
                     "If-Match", "If-None-Match", "Range"):
            val = self.headers.get(key)
            if val:
                headers[key] = val

        if "Destination" in headers:
            dest = headers["Destination"]
            dest = dest.replace(f"http://127.0.0.1:{PORT}/", UPSTREAM)
            dest = dest.replace(f"http://localhost:{PORT}/", UPSTREAM)
            headers["Destination"] = dest

        try:
            resp = session.request(
                method=self.command,
                url=url,
                headers=headers,
                data=body,
                allow_redirects=False,
                stream=False,
                timeout=300,
            )
        except Exception as e:
            self.send_error(502, str(e))
            return

        content = resp.content

        if resp.headers.get("Content-Type", "").startswith("application/xml"):
            text = content.decode("utf-8", errors="replace")
            text = text.replace("https://pan.cstcloud.cn/DAV/", "/")
            text = text.replace("http://pan.cstcloud.cn/DAV/", "/")
            content = text.encode("utf-8")

        self.send_response(resp.status_code)
        for k, v in resp.headers.items():
            low = k.lower()
            if low in ("transfer-encoding", "connection",
                       "content-encoding", "content-length"):
                continue
            self.send_header(k, v)
        self.send_header("Content-Length", str(len(content)))
        self.end_headers()
        self.wfile.write(content)

    do_GET = _proxy
    do_PUT = _proxy
    do_POST = _proxy
    do_DELETE = _proxy
    do_HEAD = _proxy
    do_OPTIONS = _proxy
    do_PROPFIND = _proxy
    do_PROPPATCH = _proxy
    do_MKCOL = _proxy
    do_COPY = _proxy
    do_MOVE = _proxy
    do_LOCK = _proxy
    do_UNLOCK = _proxy

    def log_message(self, format, *args):
        pass


if __name__ == "__main__":
    port = int(sys.argv[1]) if len(sys.argv) > 1 else PORT
    server = HTTPServer(("127.0.0.1", port), ProxyHandler)
    print(f"WebDAV Digest proxy listening on http://127.0.0.1:{port} -> {UPSTREAM}",
          flush=True)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass
    server.server_close()
PYEOF

chmod +x ~/.config/rclone/webdav_digest_proxy.py

第三步:配置 rclone

bash 复制代码
cat > ~/.config/rclone/rclone.conf << 'EOF'
[remote]
type = webdav
url = http://127.0.0.1:18080/个人文件/
vendor = other
EOF

第四步:启动代理并设置自启

先测试 systemd 用户会话是否可用:

bash 复制代码
systemctl --user status

如果可用(正常输出状态信息),使用 systemd 方案:

bash 复制代码
mkdir -p ~/.config/systemd/user

cat > ~/.config/systemd/user/webdav-proxy.service << 'EOF'
[Unit]
Description=CSTCloud WebDAV Digest Auth Proxy
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 %h/.config/rclone/webdav_digest_proxy.py
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=default.target
EOF

systemctl --user daemon-reload
systemctl --user enable --now webdav-proxy.service

如果报 Failed to get D-Bus connection: Connection refused(常见于共享实验室服务器、HPC 集群),使用 nohup + crontab 方案:

bash 复制代码
# 立即启动
nohup python3 ~/.config/rclone/webdav_digest_proxy.py > /tmp/webdav-proxy.log 2>&1 &

# 设置开机自启
(crontab -l 2>/dev/null; echo '@reboot nohup python3 $HOME/.config/rclone/webdav_digest_proxy.py > /tmp/webdav-proxy.log 2>&1 &') | crontab -

第五步:验证连接

bash 复制代码
# 检查代理是否在运行
systemctl --user status webdav-proxy

# 测试 rclone 连接
no_proxy='*' rclone lsd remote:

# 预期输出示例:
#           -1 2026-02-06 19:06:01        -1 models
#           -1 2026-01-06 15:43:28        -1 zotero
#           -1 2026-01-05 10:32:32        -1 个人信息

第六步(可选):服务器环境保活

如果在无图形界面的服务器上使用,需要启用 linger 使用户服务在未登录时也能运行:

bash 复制代码
sudo loginctl enable-linger $USER

第七步(可选):设置 shell 别名

bash 复制代码
# 添加到 ~/.bashrc 或 ~/.zshrc
echo 'alias rpan='\''no_proxy="*" rclone'\''' >> ~/.bashrc
source ~/.bashrc

# 之后可以直接使用
rpan ls remote:
rpan copy localfile.pdf remote:科研/

跨平台配置差异总结

项目 macOS Linux (systemd) Linux (无 systemd 用户会话)
Python 路径 /usr/bin/python3 /usr/bin/python3 /usr/bin/python3
rclone 安装 brew install rclone 包管理器或官方脚本 同左
requests 安装 pip3 install requests pip3 install requests 同左
服务管理 launchd (launchctl) systemd (systemctl --user) nohup + crontab
服务配置位置 ~/Library/LaunchAgents/*.plist ~/.config/systemd/user/*.service crontab -e
开机自启 plist RunAtLoad=true systemctl --user enable @reboot crontab
进程保活 plist KeepAlive=true service Restart=on-failure 需手动重启
未登录时运行 不适用 loginctl enable-linger crontab @reboot 自动覆盖
查看日志 cat /tmp/webdav-proxy.log journalctl --user -u webdav-proxy tail -f /tmp/webdav-proxy.log
检查端口 lsof -i :18080 `ss -tlnp grep 18080`
停止服务 launchctl unload ... systemctl --user stop ... kill $(pgrep -f webdav_digest_proxy)

故障排查

症状 可能原因 解决方法
401 Unauthorized 授权密码过期 按上述步骤重新生成密码
connection refused (端口 18080) 代理未运行 macOS: launchctl load ...;Linux: systemctl --user start webdav-proxy
502 Bad Gateway 代理无法连接科技云盘 检查网络连接和 DNS 解析
目录列表为空但无报错 rclone 请求走了系统代理 确保设置了 no_proxy='*'
Item with unknown path 代理未正确改写路径 检查代理脚本中的 URL 替换逻辑
ModuleNotFoundError: requests 缺少 Python 依赖 pip3 install requests
systemd 报 Failed to connect to bus 缺少 D-Bus 用户会话 export XDG_RUNTIME_DIR=/run/user/$(id -u)
服务器重启后代理未运行 未启用 linger sudo loginctl enable-linger $USER

科技云盘 WebDAV 服务信息

项目
WebDAV 地址 https://pan.cstcloud.cn/DAV/个人文件/
账户名 XXXX@XXXX
认证方式 HTTP Digest (realm="pan", algorithm=MD5)
WebDAV 引擎 IT Hit WebDAV Server v4.4.3821
DAV 支持级别 1, 2
相关推荐
SENKS_DIGITAL3 小时前
踏入非遗展馆,邂逅古老文化的诗意栖居-森克思科技
科技·设计·艺术·展厅设计·展馆设计·博物馆设计·展览
鸿栢男子焊胡工3 小时前
鸿栢科技 D9拉弧储能螺柱焊机-解决传统储能焊的痛点,实现智能化升级
科技
一次旅行3 小时前
新闻科技简报 (2026-04-03)
人工智能·科技
科技每日热闻3 小时前
旗舰力作,焕新登场!EVNIA弈威天王星系列QD-OLED电竞显示器32M2N8900X新品重磅来袭
科技·游戏·计算机外设·生活
juyou51183 小时前
AI文旅爆发元年!巨有科技AI伴游+智慧景区方案,破解“体验同质化、运营低效”痛点
人工智能·科技·安全
ZGIS智博创享14 小时前
地质调查数据采集系统专栏① | ZGIS以科技赋能,促进地质调查迈入数智新时代
人工智能·科技·地质调查数据采集系统
JoyCong199816 小时前
纳睿雷达×ToDesk:突破时空限制,远程运维让“中国智造”雷达更高效
运维·科技·电脑·远程操作
星幻元宇VR18 小时前
VR动感科普单车:让交通安全教育更真实、更有效
科技·学习·安全·生活·vr
Kingfar_118 小时前
智能座舱HMI/HUD人机交互测评体系:基于多模态仿真与数据驱动的全流程解决方案
科技·人机交互·可用性测试·用户体验