为什么个人站长该有一套自己的文件同步方案
做个人站久了,文件散落是常态:本地电脑一份源码、服务器上一份、笔记本上改了一半、手机上又拍了几张配图。用 SFTP 手动上传、用 U 盘拷来拷去,早晚会出现「改了 A 忘了传 B」的事故。很多人第一反应是装网盘客户端,但网盘要么限速、要么同步冲突、要么隐私存疑。其实 Linux 服务器本身就自带了一套能力完备的文件同步与挂载协议,只要配好,就能把服务器变成一个「网盘」,手机、笔记本、PC 都能直接读写。
这篇文章从运维视角讲清楚三件事:怎么用 WebDAV 把服务器目录暴露成可以挂载的网络磁盘;怎么用 rclone 做多端双向同步并解决冲突;以及怎么用 SSHFS 在临时场景下三分钟挂上一台远程目录。全程不依赖商业网盘。
先搞懂:WebDAV 到底是什么,和 Samba/NFS 差在哪
WebDAV(Web Distributed Authoring and Versioning)本质上是 HTTP 的扩展协议,在普通 GET/PUT 之上增加了 PROPFIND、MKCOL、MOVE、COPY、LOCK 等方法,用来列举目录、创建文件夹、重命名和加锁。它最大的优势是走 80/443 端口、走标准 HTTPS,任何能上网的地方都能用,不需要额外开端口、不需要 VPN。Windows 资源管理器、macOS Finder、安卓的 Solid Explorer、iOS 的 Documents,几乎都原生支持 WebDAV。
对比一下常见的三种方案:Samba(SMB)适合纯局域网、性能好但穿透差,445 端口在公网上极易被运营商封禁;NFS 适合服务器之间挂载,对客户端权限映射要求严格,NAT 环境下几乎不可用;WebDAV 性能不如前两者,但穿透性和兼容性最强,而且天然带 HTTPS,非常适合个人站长这种「没有固定内网、随时在外网」的场景。
方案一:用 Nginx 搭一个 WebDAV 服务
从 Nginx 1.13.9 起,官方源码里就带了 ngx_http_dav_module,但默认不编译。这个模块有个硬伤:它只支持 PUT/DELETE/MKCOL/COPY/MOVE,不支持 PROPFIND,也就是说客户端能写但不能列目录,体验会很差。所以生产上更推荐两种做法:一是用 nginx-extras 或第三方 nginx-dav-ext-module 补上 PROPFIND;二是干脆用成熟的 Docker 镜像。
先看最小可用的 Nginx 配置骨架(假设已装 dav-ext 模块):
server {
listen 443 ssl http2;
server_name dav.example.com;
# WebDAV 根目录
root /srv/dav;
# 认证:用 htpasswd 生成
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/dav.htpasswd;
# 关键:开启 WebDAV 方法
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_ext_methods PROPFIND OPTIONS;
dav_access user:rw group:rw all:r;
# PUT 时自动创建上级目录
create_full_put_path on;
# 限制上传体积,默认 1M 会直接 413
client_max_body_size 0;
# 关闭目录列表,防止泄露
autoindex off;
location / {
# 防止写 .php 被解析执行 —— WebDAV 目录绝不能执行脚本
location ~ \.php$ { deny all; }
try_files $uri $uri/ =404;
}
}
几个极易踩的坑,逐个说明:
client_max_body_size默认只有 1M,上传稍大的文件立刻返回413 Request Entity Too Large,改成0(不限制)或实际需要的值。create_full_put_path on;不加的话,客户端 PUT 一个不存在的多级路径会 409,必须在 PUT 前逐级 MKCOL。- WebDAV 目录严禁包含可执行脚本。如果 root 指向网站根目录而 Nginx 里又配了
location ~ \.php$,攻击者可以直接 PUT 一个 webshell 上去再访问,等于白送。务必用独立的目录、并在该 server 块里显式deny all掉脚本后缀。 - 上传大文件时如果走 CDN 或反代,要同步调大上游的 body 限制,否则 413 出现在 CDN 层,Nginx 日志里什么都看不到。
生成认证文件与权限收口
用 htpasswd 生成密码文件:
# -c 只在第一次创建时使用,后续追加必须去掉,否则会清空已有用户
htpasswd -c /etc/nginx/dav.htpasswd alice
htpasswd /etc/nginx/dav.htpasswd bob
# 权限:Nginx worker 通常以 www-data 运行
chown -R www-data:www-data /srv/dav
chmod 750 /srv/dav
find /srv/dav -type d -exec chmod 750 {} \;
find /srv/dav -type f -exec chmod 640 {} \;
权限不对是「能登录但上传 403」的头号原因。Nginx worker 用户必须对目标目录有写权限,注意父目录也要有 x(执行/进入)权限,只有 w 是不够的。可以用 sudo -u www-data touch /srv/dav/.writetest 快速验证写权限。
方案二:Docker 一行起一个 WebDAV(推荐给新手)
不想折腾模块编译的话,用现成镜像更快:
docker run -d --name webdav --restart unless-stopped \
-v /srv/dav:/var/lib/dav/data \
-e AUTH_TYPE=Basic \
-e USERNAME=alice \
-e PASSWORD='your-strong-pass' \
-p 127.0.0.1:8080:80 \
-e UID=33 -e GID=33 \
bytemark/webdav
随后用 Nginx 反向代理到 127.0.0.1:8080 并挂上证书。注意两点:一是容器内 UID/GID 要与宿主机目录属主一致,否则挂载目录里写不进去;二是端口绑定写 127.0.0.1:8080 而不是 8080,避免直接把明文 HTTP 的 WebDAV 暴露到公网。
反代时 Nginx 需要放行 WebDAV 方法和请求头,否则 PROPFIND 会被吞掉:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 关掉请求缓冲,大文件上传更稳
proxy_request_buffering off;
# 传递 Destination 头,否则 MOVE/COPY 会失败
proxy_pass_request_headers on;
}
三端挂载:Windows、macOS、Linux
Windows:资源管理器 →「映射网络驱动器」→ 填入 https://dav.example.com。Win10/11 默认只信任可信证书,自签证书会连不上;另外系统默认禁止 HTTP 明文 WebDAV,需要改注册表 BasicAuthLevel=2,或者干脆用正规证书走 HTTPS。
macOS:Finder →「前往」→「连接服务器」→ https://dav.example.com。macOS 会在每个目录自动写一个 .DS_Store,如果服务器端设了只读或配额容易报错,可以在同步策略里排除它。
Linux:用 davfs2 挂载:
apt install davfs2
mkdir -p /mnt/dav
mount -t davfs https://dav.example.com /mnt/dav
# 免交互:把凭据写入 /etc/davfs2/secrets,权限 600
echo "https://dav.example.com alice your-pass" >> /etc/davfs2/secrets
chmod 600 /etc/davfs2/secrets
davfs2 挂载大文件时会先写本地缓存再上传,缓存目录默认是 /var/cache/davfs2,如果服务器磁盘紧张要记得调整 cache_size,否则上传大文件容易把根分区写满。
方案三:rclone——真正好用的多端双向同步
WebDAV 解决的是「有个能挂载的远端」,但要真正做到多端自动同步、断点续传、冲突可查,rclone 才是主力。rclone 支持 70 多种后端,本地目录、WebDAV、S3、SFTP 都能当远端。一条命令把本地目录与 WebDAV 双向同步:
rclone sync /home/alice/site webdav:/site \
--progress \
--exclude ".git/**" \
--exclude "node_modules/**" \
--transfers 8 \
--checkers 16
关于 sync 与 copy 的选择,这是最容易翻车的地方:rclone sync 会让目标目录与源目录完全一致,目标里多余的文件会被删除。用它同步「本地 → 云端」做单向备份没问题;但如果两个方向都跑 sync,极易造成互相删除。做双向场景请用 rclone bisync,它会记录两次同步之间的状态并检测冲突:
# 初始化双向同步基准(第一次必须显式指定)
rclone bisync /home/alice/site webdav:/site --resync
# 之后定时跑,冲突文件会保留两份并加后缀
rclone bisync /home/alice/site webdav:/site \
--conflict-resolve newer \
--conflict-loser num \
--max-delete 100
--max-delete 是一道保险丝:如果某次同步突然要删除超过 100 个文件,rclone 会直接中止,防止一次误操作把云端清空。个人站做自动化同步时,这个参数强烈建议加上。把命令写进 crontab 每 10 分钟跑一次:
*/10 * * * * /usr/bin/rclone bisync /home/alice/site webdav:/site --conflict-resolve newer --max-delete 100 >> /var/log/rclone.log 2>&1
同步冲突与删除,怎么不被坑
同步类工具最常见的三类事故:一是两端同时修改同一文件,产生 file.conflict1 之类的副本,需要人工合并;二是误删沿同步链传播,一端删了另一端跟着删;三是同步把服务器上的敏感配置(如 .env、数据库密码)也一并传到云端。对策很朴素:用 --exclude 精确排除敏感文件与缓存目录;用 --max-delete 设上限;定期用 rclone check 做一次完整性校验。
# 校验两端差异(只比对不修改)
rclone check /home/alice/site webdav:/site --size-only
# 定期生成一份快照清单,出问题时可对照
rclone lsjson webdav:/site --recursive > /var/log/dav-manifest-$(date +%F).json
SSHFS:临时挂载的最快方案
如果只是临时想操作另一台服务器的目录,不需要 WebDAV,SSHFS 三分钟搞定。它把 SFTP 子系统挂载成本地目录,走 22 端口、走 SSH 密钥,不需要在服务端装任何东西:
apt install sshfs
mkdir -p /mnt/remote
sshfs alice@server:/var/www/site /mnt/remote \
-o reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,\
idmap=user,uid=$(id -u),gid=$(id -g)
# 卸载
fusermount -u /mnt/remote
-o reconnect 与 ServerAliveInterval 必须加,否则网络抖动一下挂载点就进入 D 状态、ls 卡死、进程杀不掉。真要卡死时,只能从另一台机器 reboot 或者等内核超时,非常难受。SSHFS 只适合临时用,不适合长期挂载生产目录。
安全加固清单
把文件协议暴露到公网,安全是绕不开的。收尾给出这份清单,逐条对照检查:
- 强制 HTTPS,80 端口 301 跳转,证书用 acme.sh 自动续期。
- WebDAV 目录独立,绝不放网站根目录,且该 server 块禁止执行任何脚本。
- 强密码 + 失败封禁,配合 fail2ban 监控 Nginx 的 401 日志,连续失败直接封 IP。
- 限制访问来源,如果只有自己用,用 Nginx 的
allow/deny或 mTLS 只放行固定 IP。 - 关闭 autoindex,目录列表泄露文件名是信息收集的第一步。
- 定期审计,用
find /srv/dav -newermt "-7 days"看最近改动的文件,异常改动及时排查。 - 备份,同步不等于备份。同步会把删除和勒索加密内容一并传播,WebDAV 里的数据仍需要独立的、带历史版本的备份。
小结
WebDAV 负责「随时随地方便地读写服务器目录」,rclone 负责「可靠地多端同步与冲突可查」,SSHFS 负责「临时应急挂载」。三者定位不同、不冲突,个人站长按需组合即可:日常用 rclone 定时 bisync 保同步,外出用 WebDAV 手机直接读写,临时排障用 SSHFS 挂一下。真正要记住的只有一句话——同步工具会忠实执行你的删除操作,所以 --max-delete 和独立备份永远不能省。