如何将 Synology 或 QNAP NAS 备份到 VPS
使用 Borg 或 restic 将 Synology、QNAP NAS 发送到异地 VPS,配置受限备份用户和仅可访问单个仓库的 SSH 密钥,并按上行带宽计算首次复制时间,限制带宽后定期测试恢复。
NAS 备份到存储 VPS 的实际形式
将 NAS 备份到存储 VPS,服务器端需要准备 4 项内容:一个非特权用户、一个只能访问单个存储库的 SSH 密钥、一个保存多个版本而不是创建镜像的备份程序,以及一个重启后仍能正常执行的计划任务。完成配置通常只需一个下午。耗时一周的部分是首次完整复制,因为家庭或小型办公室网络线路的上传速度远低于下载速度。
本指南假设的环境是实际常见的配置:一台 Synology 或 QNAP,存储着几 TB 数据,通过非对称 VDSL 或有线网络接入互联网,位于家庭或小型办公室中;用户希望在建筑物外保存一份数据副本。存储 VPS 与家用 NAS 的比较可以帮助您判断是否需要 VPS。本指南假设您已经决定使用 VPS,并说明如何连接和配置。
先说明一个术语。存储库是 VPS 上由备份程序管理的目录。它保存的是去重并加密的数据块,而不是可浏览的文件副本。您不能用文件管理器打开它,这正是这样设计的原因:VPS 保存数据,但无法读取数据。
存储 VPS 还是托管存储盒
托管存储盒是许多读者已经熟悉的默认选择。它通常按 TB 销售,可通过 SFTP、rsync、SMB 或 WebDAV 访问。对于普通的 rsync 目标或 Hyper Backup 任务来说,这已经足够。但它不提供 shell,因此远端只能存储数据。
在存储 VPS 上拥有 root 权限后,远端可以执行更多操作:
- 备份程序的服务端部分在远端运行。
borg serve在 VPS 本地读取存储库索引,并回答“这个块是否已经存在”,因此只有新块需要通过网络传输。在普通 SFTP 挂载上,同样的问题会变成数千次小型往返请求。链路延迟达到 15 到 30 ms 时,即使数据变化很少,任务也会慢得几乎无法运行。 - 追加写入限制在服务器端执行。即使 NAS 已被入侵,也无法关闭该限制。
- 保留策略在 VPS 自有的磁盘和 CPU 上运行,时间表由您决定。
- 校验也在远端运行,因此每周执行一次存储库检查完全不占用带宽。
这些内容并不代表任何特定服务商允许或包含这些功能,因此请阅读您租用的服务条款。技术要点很明确:远端提供 shell 后,存储库逻辑也可以迁移到远端。
将 NAS 数据导出的两种方式
使用厂商自带的任务。 Synology Hyper Backup 和 QNAP Hybrid Backup Sync 都通过 SSH 将数据发送到兼容 rsync 的服务器。您无需在 VPS 上安装其他软件,只需准备一个 SSH 账户和 rsync 二进制文件。您可以在 Web 界面中设置计划任务;连接中断后,任务会自动继续。仓库格式由厂商定义,因此恢复数据时必须使用厂商提供的工具。对于只需要异地副本且不想使用命令行的家庭用户,这是合适的方案。
使用 Borg 或 restic 将数据写入 VPS 上的仓库。 这种方式可以对所有版本进行去重,支持客户端加密,并可在一条命令中设置保留策略。它需要一个运行位置:x86 Synology 上的 Container Manager、QNAP 上的 Container Station,或一台始终运行且已挂载共享目录的小型 Linux 机器。通过 SMB 从另一台机器运行也可以,但这样无法保留所有权和 ACL(访问控制列表)元数据,扫描速度也会慢得多,因为读取每个文件的大小和修改时间都需要发起一次网络请求。restic 与 Borg 的选择取决于您希望由哪一端处理仓库逻辑,以及希望如何清理旧版本;在这里两者都可以使用。
直接使用 rsync -a --delete 将数据复制到 VPS,只能得到一个镜像。您在星期一误删一个目录,镜像会在星期二将其删除。NAS 被勒索软件加密后,下一次运行会把加密后的数据复制到原有的正常数据上。为什么第二个副本不一定是备份详细说明了这些情况。简而言之,您需要版本和仅追加密钥;本指南的其余部分将配置这两项。
在 VPS 上设置备份用户
以下命令适用于 VPS 上的 Ubuntu 24.04。请使用普通 sudo 用户执行。
sudo apt update && sudo apt install -y borgbackup
sudo adduser --disabled-password --gecos "" nasbackup
sudo install -d -m 700 -o nasbackup -g nasbackup /home/nasbackup/.ssh
sudo install -d -m 755 -o root -g root /srv/borg
sudo install -d -m 700 -o nasbackup -g nasbackup /srv/borg/nas1
borg --version--disabled-password表示该账户没有可供猜测的密码,因此密钥是唯一的登录方式。请注意命令输出的版本。NAS 上的 Borg 必须与 VPS 上的 Borg 使用相同的主版本,因为 1.x 客户端无法与 2.x borg serve通信。这种版本不匹配会在首次连接时暴露,而不是在安装时暴露。
在 NAS 上以 root 身份生成一个专用密钥对:
ssh-keygen -t ed25519 -f /root/.ssh/nas_offsite -N "" -C "nas1 offsite backup"这里有意使用空口令短语,因为无人值守的夜间任务无法输入口令。这正是下一步很重要的原因:除指定仓库外,该密钥在任何地方都不应具备价值。将公钥作为单行内容写入 VPS 上的 /home/nasbackup/.ssh/authorized_keys。
command="borg serve --restrict-to-repository /srv/borg/nas1",restrict ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... nas1 offsite backup然后在该行上设置 sudo chown nasbackup:nasbackup /home/nasbackup/.ssh/authorized_keys 和 sudo chmod 600。command=会替换客户端请求执行的任何内容,因此该密钥无法获取 shell、无法运行 rsync,也无法访问服务器上的其他路径。restrict用一个选项同时关闭端口转发、代理转发、X11 转发和 pty 分配(OpenSSH 7.2 及更高版本)。--restrict-to-repository是 Borg 对同一限制的设置。
从 NAS 测试连接:
ssh -i /root/.ssh/nas_offsite nasbackup@vps.example.com你应看到 PTY allocation request failed on channel 0,这说明 restrict正在生效。随后会进入一个没有提示符的会话,因为 borg serve正在标准输入上等待 Borg 协议。按 Ctrl-C 退出。若出现密码提示,说明密钥尚未正确安装。Permission denied (publickey).通常表示 .ssh 或 authorized_keys 的权限过于宽松,sshd 拒绝使用组可写文件。
现在从 NAS 创建仓库:
export BORG_REPO=ssh://nasbackup@vps.example.com/srv/borg/nas1
export BORG_RSH="ssh -i /root/.ssh/nas_offsite -o ServerAliveInterval=30"
borg init --encryption=keyfile-blake2
borg key export :: /root/nas1-borg-key.txtkeyfile-blake2会将加密密钥保存在 NAS 上的 /root/.config/borg/keys/ 中,因此 VPS 只保存密文,完全不保存密钥材料。代价很明显:如果 NAS 和密钥同时丢失,该仓库将永久无法读取。创建仓库后立即导出密钥,并将导出文件存放在两台机器都无法访问的位置,同时将口令短语保存到密码管理器中。borg key export --paper会生成可打印的版本。另一个选项 repokey-blake2会将加密密钥存储在仓库内部,更易于恢复,但安全性完全取决于你的口令短语。不在租用的磁盘上保存明文介绍了主机能够看到哪些内容这一更广泛的问题。
确认 borg init和第一次备份均已成功后,返回 VPS,并将 --append-only添加到 authorized_keys中的强制命令。启用仅追加模式后,服务器永远不会删除数据:通过此密钥发送的 borg delete或 borg prune会向客户端报告成功,但相应数据段仍保留在磁盘上。因此,即使攻击者控制了 NAS,也无法擦除备份历史。代价是必须从其他位置执行实际清理。请使用不在 NAS 上的机器,通过不带该选项的第二个密钥运行 borg prune;或者每年手动删除几次旧归档。无论采用哪种方式,都必须在 VPS 的 shell 中运行 borg compact,才能实际释放磁盘空间。
对于 restic,应使用 sshd 配置块而不是强制命令,因为 restic 使用 SFTP:
Match User nasbackup
ChrootDirectory /srv/restic
ForceCommand internal-sftp
AllowTcpForwarding noChrootDirectory要求 /srv/restic归 root 所有,且其他用户均不可写;仓库则放在由 nasbackup所有的子目录中。在 chroot 内,路径是 /nas1,而不是 /srv/restic/nas1,因此仓库字符串应为 sftp:nasbackup@vps.example.com:/nas1。重新加载配置前先检查配置语法,因为错误的 Match块可能会导致所有用户无法登录:sudo sshd -t && sudo systemctl reload ssh。restic 的仅追加模式位于其 REST server(rest-server --append-only)中。因此,如果你主要担心 NAS 上的勒索软件,应运行该服务,而不是使用 SFTP。
首次备份,以及应排除的内容
borg create --stats --progress \\
--compression auto,zstd,3 \\
--exclude '/volume1/*/@eaDir' \\
--exclude '/volume1/*/#recycle' \\
--exclude-caches \\
::'nas1-{now:%Y-%m-%d}' /volume1/documents /volume1/photoauto,zstd,3 会让 Borg 检查每个数据块,并在压缩无益时跳过压缩;照片或视频库中的大多数内容都属于这种情况。@eaDir 存放 Synology 的缩略图和索引数据,#recycle 是网络回收站:二者都可以重建。对于大型照片库,仅 @eaDir 就可能产生数十 GB 的上传数据,而这些数据本来无需上传。--exclude-caches 会跳过带有 CACHEDIR.TAG 标记的目录。
先从丢失后最难以承受的数据开始,不要一开始就备份所有内容。优先备份文档和照片,之后再处理媒体库。Borg 会根据已经存储的数据执行去重,因此稍后扩大包含列表时,只会上传存储库中尚未出现的数据块。分阶段进行不会浪费任何数据。
首次完整复制需要多长时间?
开始前先完成这个计算,因为结果会影响方案。将上行速率(以兆比特/秒为单位)除以 8,得到兆字节/秒。再取其中约 90%,以计入 TCP、SSH 和协议开销。然后用数据大小除以这个速率,再将秒数除以 86,400,得到天数。
注意单位。线路速率使用十进制单位,因此这里的 2 TB 表示 2,000,000 MB。NAS 报告有 2 TiB 数据时,按这些单位计算约为 2.2 TB,比计划的上传量多 10%。
The data behind this chart
[
{
"label": "VDSL 50/10",
"mb_per_sec_up": 1.1,
"mb_per_sec_down": 5.6,
"full_copy_up": "21 days",
"full_restore_down": "4.1 days"
},
{
"label": "Cable 250/25",
"mb_per_sec_up": 2.8,
"mb_per_sec_down": 28.1,
"full_copy_up": "8.3 days",
"full_restore_down": "19.8 hours"
},
{
"label": "VDSL 250/40",
"mb_per_sec_up": 4.5,
"mb_per_sec_down": 28.1,
"full_copy_up": "5.1 days",
"full_restore_down": "19.8 hours"
},
{
"label": "Fibre 500/100",
"mb_per_sec_up": 11.2,
"mb_per_sec_down": 56.2,
"full_copy_up": "2.1 days",
"full_restore_down": "9.9 hours"
}
]这些行是将公式应用于 4 种典型公开套餐速率后的结果,不代表任何实际线路的测量值。在 VDSL 50/10(常见的入门线路)上,以满速全天候上传 2 TB 首次副本需要 21 days。在 Fibre 500/100 上,同一副本需要 2.1 days。Cable 线路处于中间位置,但限制也很明显:Cable 250/25 的上行速率为 2.8 MB/s,因此需要 8.3 days;而同一线路将整个仓库下载回来只需 19.8 hours。
由此可以得出两点。带宽限制会按比例直接增加耗时,因此速率减半时,最慢线路上的首次复制需要 6 周。对于非对称连接,恢复方向从来不是问题;真正耗时的是只需执行一次的上传方向。
如果首次复制无法在你能接受的时间窗口内完成,可以选择以下方案。
- 先备份少量但重要的数据集,然后在数周内逐步扩大包含范围。
- 使用更快的线路执行首次复制。将数据复制到 USB 磁盘,带到办公室或朋友的光纤连接处,然后在同一仓库上执行首次
borg create。Borg 从新机器访问仓库时会重建本地缓存;路径发生变化时,文件会再次读取,但仓库中已有的块不会重复上传。 - 以受限速率运行 1 个月。对于家庭用户,这是合理的选择。明确说明哪些数据尚未受到保护,因为运行完成前,异地副本并不存在。
- 考虑媒体库是否确实需要放在异地。可以重新获取的电影收藏,与 5 年发票的唯一副本不属于同一重要级别。排除电影收藏后,首次复制可能从 6 周缩短到 2 天。
在运行备份时保持家庭网络可用
备份占满上行带宽后,整个网络连接都会像中断一样,包括下载。原因是排队。调制解调器接收数据包的速度超过线路发送数据包的速度,缓冲区被备份数据填满。所有交互式数据包、DNS 查询和 TCP 确认都必须在缓冲区后面等待。Ping 延迟会从约 15 ms 增加到几百毫秒。这就是缓冲膨胀,也是视频通话会在一次上传期间中断的原因,即使该上传只使用了“闲置”带宽。
应限制任务速度,不要寄希望于网络自行恢复。下面的3个工具都接受以 kibibytes per second 为单位的限速参数:
borg create --upload-ratelimit 900 ...
restic --limit-upload 900 backup ...
rsync --bwlimit=900 ...900 KiB/s 约等于 7.4 Mbit/s。在 10 Mbit/s 的上行链路上,这会保留约 2.5 Mbit/s 的空闲带宽。不要只相信配置值,应实际测量结果。启动备份,然后在笔记本电脑上运行 ping -c 20 1.1.1.1。如果延迟接近空闲状态下的值,说明限速合适。如果延迟达到几百毫秒,说明缓冲区仍在被填满。将限速降低三分之一,然后再次测量。配备现代队列管理功能的路由器(fq_codel 或 cake;部分固件将其称为 SQM)可以更彻底地解决同一问题,因为它会在缓冲区填满前发出拥塞信号。
在 Linux 主机上使用 systemd timer 调度任务:
[Unit]
Description=Nightly offsite backup of the NAS
[Timer]
OnCalendar=*-*-* 01:30:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.targetPersistent=true 会在系统启动后运行错过的任务。这对于不是全天候开机的机器很重要。RandomizedDelaySec 会随机分散启动时间,避免两台机器在同一秒访问存储库并争用锁。使用 sudo systemctl enable --now nas-offsite.timer 启用它,然后检查 systemctl list-timers nas-offsite.timer。该命令会输出下一次运行时间和上一次运行的结果。DSM 和 QTS 没有 systemd,因此应使用厂商提供的任务调度器调用同一个脚本。将命令集中放在一个 shell 脚本中,确保两种方式执行完全相同的代码。
传输过程中连接中断时
连接会中断。持续数天的上传可能遇到路由器重启、ISP 维护和强制重新连接,因此支持断点续传是必要条件,而不是可有可无的功能。
Borg 默认每 30 分钟写入一个检查点归档(--checkpoint-interval 1800)。任务中断后,您会看到名称以 .checkpoint 结尾的归档。下一次运行 borg create 时,Borg 会重新读取源文件,但只上传存储库中尚不存在的块。因此中断只会损失最近半小时的传输进度,而不是最近 3 天的进度。对同一归档完成一次任务后,检查点会被替换。
Restic 会持续上传 pack 文件和索引文件,因此重复运行时会跳过已经上传的数据。如果崩溃后留下了没有索引引用的 pack 文件,restic repair index 会使这些文件重新可见,以便重用,而不是再次上传。对于 0.16 之前的版本,使用的命令是 restic rebuild-index。
被终止的客户端会留下锁,下一次运行会因 Failed to create/acquire the lock 停止。确认确实没有任务正在运行,然后使用 borg break-lock 或 restic unlock 清除锁。在 BORG_RSH 中保留 -o ServerAliveInterval=30,这样断开的 TCP 会话可在 1 分钟内被发现,而不必一直等待内核超时。
保留策略,避免仓库无限增长
borg prune --list --keep-daily=7 --keep-weekly=4 --keep-monthly=12 --keep-yearly=2
borg compactBorg 1.2 将这两个操作拆分开来。prune 会删除归档条目,compact 会通过重写分段来回收磁盘空间。如果跳过 compact,仓库就永远不会缩小,无论执行多少次 prune。如果仓库包含来自多个来源的归档,请添加 Borg 版本支持的归档匹配选项,因为不带过滤条件的 prune 会处理它能看到的所有归档。restic 中对应的操作只有一条命令:restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 2 --prune。
完成首次复制后,每晚运行时只会上传发生变化的块,因此仓库的增长完全取决于所保存的数据类型。文档和照片库每月可能只变化几 GB。虚拟机镜像目录或完整数据库转储每天可能几乎完全变化,此时相同的保留策略会占用源数据数倍的空间。运行两周后的 borg info,根据该结果为 VPS 选择容量,不要凭猜测决定;当仓库超出当前方案时,还要考虑 块存储与对象存储每 TB 的成本。还要注意,VPS 快照与备份是两种不同的工具:快照保护的是存放仓库的机器,而不是 NAS。
验证备份,然后从备份恢复
未经验证的备份只是一种假设。下面的检查耗用的带宽差异很大,因此安排在不同的周期执行。
- 每周在 VPS 上执行:
borg check --repository-only /srv/borg/nas1。该命令会验证分段校验和及存储库索引,但不会解密任何内容,因此不需要密钥,也不耗用带宽。将它加入 VPS 上 root 的 crontab。 - 每月从 NAS 执行:
borg check --archives-only。该命令会读取已加密的归档元数据,因此需要密钥,并会通过网络下载这些元数据。与数据本身相比,元数据很小。 - 偶尔执行:
borg check --verify-data会解密并计算每个块的哈希值,这意味着要下载整个存储库。网络线路较慢时,即使下载方向速度较快,也可能需要数天。
Restic 也采用相同的方式。restic check 会验证结构;restic check --read-data-subset=1/12 每月读取十二分之一的数据,因此无需进行一次超大规模下载,也能在一年内验证整个存储库。
验证可以证明存储库完整无损,但不能证明你能够恢复文件。这是另一项技能,也是压力下最容易失败的环节。每季度进行一次恢复演练,并记录所需时间。
borg list
borg extract --dry-run --list ::nas1-2026-09-05 volume1/documents/2026
mkdir -p /tmp/restoretest
cd /tmp/restoretest
borg extract ::nas1-2026-09-05 volume1/documents/2026
diff -r /volume1/documents/2026 /tmp/restoretest/volume1/documents/2026归档中的路径不包含开头的斜杠,borg extract 会将路径写入当前目录的相对位置,因此演练从 cd 开始。最后 diff -r 不输出任何内容,这正是预期结果。Restic 版本为 restic snapshots,后跟 restic restore latest --target /tmp/restoretest --include /volume1/documents/2026。如果你的 Borg 构建支持 FUSE,borg mount ::nas1-2026-09-05 /mnt/borg 会将归档作为只读文件系统提供,这是恢复单个文件最快的方法。
在一台不是 NAS 的计算机上进行一次演练,因为真正需要恢复时,NAS 可能正是故障设备。准备一台安装了 Borg 的笔记本电脑、导出的密钥和密码短语即可。这句话就是你的灾难恢复计划,因此必须确认它确实可行。
3-2-1 规则中的位置
3-2-1 表示保留 3 份数据副本,使用 2 种不同类型的介质,其中 1 份存放在异地。NAS 加上 VPS 仓库,就是位于两栋建筑中的 2 份副本;将 VPS 用作异地目标,总体上涵盖了这一环节的作用。如果某个文件只存在于 NAS 上,例如手机照片导入 NAS 后又从手机中删除,那么你实际上只有 2 份副本。未被及时发现的损坏或删除会在超出保留窗口后同时影响这 2 份副本。
RAID 不算其中一份副本。镜像磁盘组可以防止一块磁盘故障,但无法防止文件夹被删除或发生火灾。
成本较低的第三份副本可以使用家中的 USB 磁盘,并定期轮换,存放时保持未连接状态。它还能提供快速恢复,因为从本地磁盘读取数 TB 数据只需一个下午,而从 VPS 下载则受限于上文所述的下载速度。远端系统的运行状况同样重要;监控 SMART 数据以及值得触发告警的错误,只有在保存最后一份副本的机器上拥有 root 权限时才能执行。
FAQ
第一次将 NAS 备份到 VPS 需要多长时间?
将上行速率(以兆比特/秒为单位)除以 8,再取结果的约 90% 作为扣除开销后的有效速率,然后用数据大小(以兆字节为单位)除以该速率。对于 2 TB 数据,持续上传时间在 VDSL 50/10 上为 21 days,在 VDSL 250/40 上为 5.1 days。任何带宽限制都会按比例延长时间,因此限制为线路速率一半的任务需要 2 倍时间。
可以在 Synology NAS 上运行 Borg 或 restic 吗?
在支持 Container Manager 的 x86 型号上,可以在容器中运行其中任意一个,并访问共享文件夹。基于 ARM 的型号通常不支持此功能,在软件包系统之外安装二进制文件往往会在下次 DSM 更新时失效。有两种替代方案效果较好:将 Hyper Backup 指向 VPS 上的 rsync 目标,或者在一台始终运行的 Linux 小型设备上运行 Borg,并挂载 NAS 共享文件夹,但需要接受较慢的扫描速度以及所有权元数据丢失。
将 NAS 通过 rsync 备份到 VPS 是否足够?
这样可以获得异地副本,但不会保留历史版本。NAS 上删除或加密的文件会在下一次运行时从镜像中删除或被加密,而您可能要到数周后才发现。请使用版本化仓库,例如 Borg、restic 或厂商自带的版本化任务,并将服务器密钥限制为仅追加模式,防止 NAS 销毁已经存储的数据。
如果 NAS 和其加密密钥同时丢失,会发生什么?
使用 keyfile 加密时,没有导出的密钥文件和密码短语就无法读取仓库,因此应将该导出文件保存到两台设备都无法访问的位置,例如密码管理器,或使用 borg key export --paper 打印一份副本。使用 repokey 时,加密密钥存储在仓库内部,只需密码短语即可恢复。无论采用哪种方式,都应在真正需要恢复之前进行测试:将一个目录恢复到一台从未访问过该仓库的笔记本电脑上。