Ubuntu 22.04 安装 rdiff-backup 指南
Ubuntu 22.04 双路径安装 rdiff-backup(apt 2.0.5 与 pip 2.2.7)、依赖与双机 SSH 免密部署、systemd timer 定时托管及本地+远端首次备份冒烟测试闭环,全部命令实测。
Ubuntu 22.04 安装 rdiff-backup 指南
目标:在 Ubuntu 22.04 上从零安装 rdiff-backup,覆盖 apt 仓库版(2.0.5)与 pip 最新版(2.2.7)两条安装路径、依赖说明、双机(备份服务器 → 目标机)SSH 免密部署、systemd timer 定时托管与首次备份冒烟测试闭环。全部命令与回显均在 Ubuntu 22.04.5 LTS 实测照抄,最新版本号查询日期为 2026-10-22。选型背景见 《rdiff-backup 介绍与选型指南》。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64,glibc 2.35),备份服务器主机名
backup-server(10.89.67.2),备份目标机主机名remote-server(10.89.67.3); - rdiff-backup 版本:
- Ubuntu 22.04 官方仓库(jammy/universe):2.0.5-3build1;
- PyPI 最新稳定版:2.2.7(GitHub Release 同为 v2.2.7,经 shields.io 徽章接口核对,查询日期 2026-10-22);
- 运行时:Python 3.10.12(系统自带);
- 双机关系:
backup-server主动向remote-server推送备份(push 模式),两台机器都要安装 rdiff-backup。
二、前置条件
- 两台机器均为 Ubuntu 22.04(低版本发行版同理,包名略有差异),且网络互通;
- 具备 root 权限(本文示例统一用 root,示例密码
q1w2e3r4); backup-server能访问 archive.ubuntu.com(apt 源)与 pypi.org(pip 源);内网环境可配置代理:
export http_proxy=http://192.168.1.62:7897 https_proxy=http://192.168.1.62:7897 # 内网代理示例,按实际环境替换
- 目标机需安装并运行 OpenSSH Server(
apt install openssh-server,Ubuntu 22.04 默认已装)。
三、版本选型说明
| 来源 | 版本 | 说明 |
|---|---|---|
| Ubuntu 22.04 apt 仓库(jammy/universe) | 2.0.5-3build1 | 随发行版冻结,版本偏老;不支持 2.2.x 的动作式新语法 |
PyPI(pip3 install rdiff-backup) | 2.2.7 | 官方发布 cp310 manylinux 二进制 wheel,免编译,含 librsync 支持 |
| GitHub Release(rdiff-backup/rdiff-backup) | v2.2.7 | 与 PyPI 一致(shields.io 徽章接口核对,查询日期 2026-10-22) |
先看 apt 仓库的候选版本(实测回显):
apt-cache policy rdiff-backup
rdiff-backup:
Installed: (none)
Candidate: 2.0.5-3build1
Version table:
2.0.5-3build1 500
500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages
💡 关键结论:Ubuntu 22.04 官方仓库只到 2.0.5,与上游最新 2.2.7 相差一个次版本线(1.x→2.x 曾有仓库格式破坏性变更,2.0→2.2 兼容)。双机部署必须保证两端版本一致或兼容——推荐两台机器都用 pip 安装 2.2.7;apt 的 2.0.5 仅适合「单机自用、不与新版本远端互通」的场景。
四、安装方案 A:apt 仓库安装(2.0.5)
4.1 方案说明
用系统包管理器安装 jammy/universe 里的 rdiff-backup 2.0.5。优点是一条命令、依赖自动处理、随 apt 升级;缺点是版本老,且与 pip 版本混装时会出现模块冲突(见 4.3 实录)。
4.2 安装步骤
apt-get update
apt-get install -y rdiff-backup
实测回显(输出节选,实测尾段):
Unpacking librsync2:amd64 (2.3.2-1ubuntu1) ...
Selecting previously unselected package python3-pylibacl:amd64.
Preparing to unpack .../python3-pylibacl_0.6.0-2ubuntu2_amd64.deb ...
Unpacking python3-pylibacl:amd64 (0.6.0-2ubuntu2) ...
Selecting previously unselected package python3-pyxattr:amd64.
Preparing to unpack .../python3-pyxattr_0.7.2-2ubuntu2_amd64.deb ...
Unpacking python3-pyxattr:amd64 (0.7.2-2ubuntu2) ...
Unpacking rdiff-backup (2.0.5-3build1) ...
Setting up python3-pylibacl:amd64 (0.6.0-2ubuntu2) ...
Setting up librsync2:amd64 (2.3.2-1ubuntu1) ...
Setting up rdiff-backup (2.0.5-3build1) ...
Setting up python3-pyxattr (0.7.2-2ubuntu2) ...
💡 说明:apt 方式一次装齐三件套——
librsync2(差分算法动态库)、python3-pylibacl(POSIX ACL 支持)、python3-pyxattr(扩展属性支持)。后两者正是 rdiff-backup 保留 ACL/EA 元数据的依赖(官网 features 页说明),方案 B 也会用到它们。
4.3 验证与混装冲突实录
验证版本:
rdiff-backup --version
若系统此前用 pip 装过 2.2.x,此时会看到两类现象(均为实测照抄):
现象一:which -a 显示两个二进制共存:
$ which -a rdiff-backup
/usr/local/bin/rdiff-backup
/usr/bin/rdiff-backup
/bin/rdiff-backup
现象二:直接调 /usr/bin/rdiff-backup(apt 的 2.0.5 脚本)会报错:
$ /usr/bin/rdiff-backup --version
Traceback (most recent call last):
File "/usr/bin/rdiff-backup", line 32, in <module>
rdiff_backup.Main.error_check_Main(sys.argv[1:])
AttributeError: module 'rdiff_backup.Main' has no attribute 'error_check_Main'
原因:pip 装的 2.2.7 模块位于 /usr/local/lib/python3.10/dist-packages/,在 sys.path 中优先级高于 apt 的 /usr/lib/python3/dist-packages/,导致 2.0.5 的启动脚本导入到 2.2.7 的模块(error_check_Main 在 2.2.x 已改名)。结论:apt 与 pip 两条路径二选一,不要混装;排障方法见「十、常见问题」。
4.4 卸载 apt 版本(切换到方案 B)
apt-get remove --purge -y rdiff-backup
实测回显(输出节选):
Removing rdiff-backup (2.0.5-3build1) ...
⚠️ 注意:卸载 rdiff-backup 包不会删除备份仓库数据目录(
rdiff-backup-data/),历史备份不受影响。
五、安装方案 B:pip 安装最新版 2.2.7(推荐)
5.1 方案说明
rdiff-backup 2.2.7 在 PyPI 发布了 cp310 的 manylinux 二进制 wheel(内置 librsync 编译产物,无需 gcc 与 librsync-dev),pip 安装即用。Python 依赖基础项只有 PyYAML;ACL/EA/进程统计支持由可选 extra meta 提供(pylibacl、pyxattr、psutil),推荐带 extra 安装:rdiff-backup[meta]。
5.2 安装步骤
apt-get install -y python3-pip
pip3 install "rdiff-backup[meta]==2.2.7"
实测回显(pip 的 root 用户 WARNING 属环境提示,不影响安装):
Collecting rdiff-backup[meta]==2.2.7
Downloading rdiff_backup-2.2.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (480 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 480.4/480.4 KB 605.8 kB/s eta 0:00:00
Requirement already satisfied: PyYAML in /usr/local/lib/python3.10/dist-packages (from rdiff-backup[meta]==2.2.7) (6.0.3)
Requirement already satisfied: pyxattr in /usr/lib/python3/dist-packages (from rdiff-backup[meta]==2.2.7) (0.7.2)
Requirement already satisfied: pylibacl in /usr/lib/python3/dist-packages (from rdiff-backup[meta]==2.2.7) (0.6.0)
Collecting psutil
Downloading psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl (155 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 155.6/155.6 KB 4.4 MB/s eta 0:00:00
Installing collected packages: rdiff-backup, psutil
Successfully installed psutil-7.2.2 rdiff-backup-2.2.7
💡 说明:本机此前用 apt 装过
python3-pylibacl/python3-pyxattr(4.2 步装上的,卸载 rdiff-backup 包不会移除它们),所以 pip 显示Requirement already satisfied;全新机器上[meta]extra 会自动从 PyPI 下载这两个包,两种来源等价。下载慢时参考第二章的代理配置。
5.3 验证
rdiff-backup --version
python3 -c "import posix1e, xattr, psutil, yaml; print(posix1e.__file__); print(xattr.__file__)"
实测回显:
rdiff-backup 2.2.7
/usr/lib/python3/dist-packages/posix1e.cpython-310-x86_64-linux-gnu.so
/usr/lib/python3/dist-packages/xattr.cpython-310-x86_64-linux-gnu.so
再看运行时信息(rdiff-backup info 输出节选,实测首段):
exec:
api_version:
actual: 0
default: 200
max: 201
min: 200
argv:
- /usr/local/bin/rdiff-backup
- info
parsed: null
version: 2.2.7
python:
executable: /usr/bin/python3
name: cpython
version: 3.10.12
💡 说明:
api_version.default: 200是 2.2.x 的默认服务端调用方式(旧式 CLI 兼容模式),因此每次备份会打印一条 deprecation WARNING,属正常现象,加--api-version 201可消除(见配置篇)。
5.4 升级与降级
pip 路径下版本切换非常直接,实测从 2.2.7 降到 2.2.6 再升回:
pip3 install rdiff-backup==2.2.6
rdiff-backup --version
pip3 install rdiff-backup==2.2.7
rdiff-backup --version
实测回显:
rdiff-backup 2.2.6
rdiff-backup 2.2.7
⚠️ 注意:降级前先确认仓库格式兼容(2.x 线内兼容);升级到跨大版本(1.x→2.x)前阅读官方 migration 文档。查看当前版本也可用
pip3 show rdiff-backup。
六、方案对比与选择建议
| 维度 | 方案 A:apt 仓库 | 方案 B:pip(推荐) |
|---|---|---|
| 版本 | 2.0.5-3build1(jammy 冻结) | 2.2.7(跟随上游,2026-10-22 查询最新) |
| 安装方式 | apt-get install rdiff-backup | pip3 install "rdiff-backup[meta]==2.2.7" |
| 依赖处理 | apt 自动(librsync2/pylibacl/pyxattr) | wheel 自带 librsync;[meta] 自动装 ACL/EA 依赖 |
| 是否需编译 | 否 | 否(manylinux wheel) |
新动作语法(backup/restore/list 等子命令) | ❌ 2.0.5 报错(实测见 FAQ) | ✅ |
| 升级/降级/多版本 | 受制于仓库 | pip3 install rdiff-backup==<版本> 任意切换 |
| 适用场景 | 仅系统仓库存量运维、单机自用 | 双机部署、需要新特性与语法、长期维护 |
💡 选择建议:双机与生产场景一律选方案 B,且两台机器安装同一版本;方案 A 仅在受控内网且能接受 2.0.5 老语法时使用。无论哪种方案,都要避免 apt 与 pip 混装(见 FAQ 10.1)。
七、双机部署:SSH 免密打通
rdiff-backup 跨机备份走 SSH 管道,免密是定时任务的前提(交互输密码的方案无法放进 cron/timer)。本节以 backup-server 为发起端、remote-server 为目标机。
7.1 主机名与网络规划
两台机器通过 /etc/hosts 固定主机名解析(也可用内网 DNS)。在 backup-server 上确认:
cat /etc/hosts
getent hosts remote-server
实测回显:
127.0.0.1 localhost
10.89.67.2 backup-server
10.89.67.3 remote-server
10.89.67.3 remote-server
7.2 目标机允许 root 密码登录(ssh-copy-id 的前置)
ssh-copy-id 首次分发公钥需要一次密码登录。Ubuntu 22.04 的 sshd 默认 PermitRootLogin prohibit-password(禁 root 密码登录),直接 ssh-copy-id 会失败——这是实测踩到的坑,排障过程完整沉淀如下。
直接分发时在 backup-server 上实测报错:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Permission denied, please try again.
在目标机 remote-server 上检查生效配置:
sshd -T | grep -E "^(permitrootlogin|passwordauthentication)"
实测回显(修复前):
permitrootlogin without-password
passwordauthentication yes
修复:写入 sshd 配置片段并重载(生产环境更规范的做法是改用普通用户分发公钥,此处按实验环境用 root 演示):
printf "PermitRootLogin yes\nPasswordAuthentication yes\n" > /etc/ssh/sshd_config.d/99-root-pwd.conf
systemctl reload ssh
sshd -T | grep -E "^(permitrootlogin|passwordauthentication)"
实测回显(修复后):
permitrootlogin yes
passwordauthentication yes
7.3 备份服务器生成密钥并分发
在 backup-server 上生成 ed25519 密钥(已有旧密钥可先备份或删除):
rm -f /root/.ssh/id_ed25519 /root/.ssh/id_ed25519.pub
ssh-keygen -t ed25519 -N "" -C "root@backup-server" -f /root/.ssh/id_ed25519
实测回显:
Generating public/private ed25519 key pair.
Your identification has been saved in /root/.ssh/id_ed25519
Your public key has been saved in /root/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:9px1WyEI7Fk4FGYNExXoI4egY3l68E/f5BYNIwDu8H0 root@backup-server
The key's randomart image is:
+--[ED25519 256]--+
| .. oXOo. |
| .. .o=oo. |
| .o.. = +. . . |
| *+..o B o . .|
| . *o .SEo = . .|
| . o o.o = o o |
| . o . B . . |
| . . + |
+----[SHA256]-----+
分发公钥到目标机(提示输入密码时输入目标机 root 密码,示例环境为 q1w2e3r4):
ssh-copy-id root@remote-server
实测回显:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -o 'StrictHostKeyChecking=no' 'root@remote-server'"
and check to make sure that only the key(s) you wanted were added.
💡 说明:脚本化环境可用
sshpass -p q1w2e3r4 ssh-copy-id -o StrictHostKeyChecking=no root@remote-server免交互完成(实测等价输出);分发完成后建议把 7.2 打开的 root 密码登录改回prohibit-password,只留密钥通道。
7.4 免密验证
ssh root@remote-server hostname
ssh root@remote-server "rdiff-backup --version"
ssh -o BatchMode=yes root@remote-server "echo passwordless-ok"
实测回显:
remote-server
rdiff-backup 2.2.7
passwordless-ok
⚠️ 注意:
BatchMode=yes禁用一切交互,能回显passwordless-ok才算真正的免密——定时备份就运行在这个模式下。同时确认目标机的 rdiff-backup 版本(2.2.7),两端版本一致是跨机备份的基本要求。
八、首次备份冒烟测试(本地 + 远端闭环)
安装与免密就绪后,用一套最小数据走通本地与远端两条备份链路。
准备测试数据(backup-server 上):
mkdir -p /root/smoke-src/etc-demo
printf "Port 22\nPermitRootLogin prohibit-password\n" > /root/smoke-src/etc-demo/sshd.conf
echo "smoke test file" > /root/smoke-src/readme.txt
8.1 本地备份冒烟
rdiff-backup backup /root/smoke-src /root/smoke-bak
rdiff-backup list files /root/smoke-bak
rdiff-backup verify /root/smoke-bak
实测回显:
NOTE: Starting mirror from source path /root/smoke-src to destination path /root/smoke-bak
.
etc-demo
etc-demo/sshd.conf
readme.txt
NOTE: All files verified successfully
💡 说明:首轮输出中的
NOTE: Starting mirror...表示从零建镜像;list files能列出镜像内容(镜像可直接浏览);verify全库校验通过。完整会话还会打印统计与一条 deprecation WARNING(含Session statistics表,含义见 《rdiff-backup 介绍与选型指南》第五章)。
8.2 远端备份冒烟(user@host::/path 语法)
rdiff-backup backup /root/smoke-src root@remote-server::/root/smoke-bak
ssh root@remote-server "ls /root/smoke-bak"
rdiff-backup list files root@remote-server::/root/smoke-bak
实测回显:
NOTE: Starting mirror from source path /root/smoke-src to destination path /root/smoke-bak
etc-demo
rdiff-backup-data
readme.txt
.
etc-demo
etc-demo/sshd.conf
readme.txt
💡 说明:
root@remote-server::/root/smoke-bak即「用户@主机::路径」三段式远端语法;目标机侧多出的rdiff-backup-data/子目录就是镜像旁的增量与元数据区。list files同样支持直接对远端仓库操作。
8.3 从远端仓库恢复单个文件
rdiff-backup restore root@remote-server::/root/smoke-bak/readme.txt /root/smoke-restored-readme.txt
cat /root/smoke-restored-readme.txt
实测回显:
smoke test file
至此安装—双机—备份—恢复闭环全部打通。
九、定时备份:systemd timer 托管
rdiff-backup 是一次性 CLI 会话工具,无常驻进程;定时调度用 systemd timer(或 cron)。在 backup-server 上创建服务单元与定时器单元:
/etc/systemd/system/rdiff-backup-smoke.service:
[Unit]
Description=rdiff-backup daily backup of /root/smoke-src
[Service]
Type=oneshot
ExecStart=/usr/local/bin/rdiff-backup backup /root/smoke-src /root/smoke-bak
/etc/systemd/system/rdiff-backup-smoke.timer:
[Unit]
Description=Run rdiff-backup-smoke daily at 02:00
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
💡 配置说明:
Type=oneshot对应一次性备份会话;OnCalendar=*-*-* 02:00:00表示每天 02:00 触发;Persistent=true让错过的调度(如停机窗口)在开机后补跑一次;ExecStart 写 rdiff-backup 的绝对路径(which rdiff-backup查得/usr/local/bin/rdiff-backup),避免 systemd 环境 PATH 差异。
启用定时器并手动触发一次验证:
systemctl daemon-reload
systemctl enable --now rdiff-backup-smoke.timer
systemctl list-timers rdiff-backup-smoke.timer --no-pager
systemctl start rdiff-backup-smoke.service
systemctl status rdiff-backup-smoke.service --no-pager -n 5
实测回显:
Created symlink /etc/systemd/system/timers.target.wants/rdiff-backup-smoke.timer → /etc/systemd/system/rdiff-backup-smoke.timer.
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2026-10-23 02:00:00 UTC 20h left n/a n/a rdiff-backup-smoke.timer rdiff-backup-smoke.service
○ rdiff-backup-smoke.service - rdiff-backup daily backup of /root/smoke-src
Loaded: loaded (/etc/systemd/system/rdiff-backup-smoke.service; static)
Active: inactive (dead) since Thu 2026-10-22 05:47:55 UTC; 4ms ago
TriggeredBy: ● rdiff-backup-smoke.timer
Process: 5269 ExecStart=/usr/local/bin/rdiff-backup backup /root/smoke-src /root/smoke-bak (code=exited, status=0/SUCCESS)
Main PID: 5269 (code=exited, status=0/SUCCESS)
Oct 22 05:47:55 backup-server systemd[1]: Starting rdiff-backup daily backup of /root/smoke-src...
Oct 22 05:47:55 backup-server rdiff-backup[5269]: NOTE: Starting increment operation from source path /root/smoke-src to destination path /root/smoke-bak
Oct 22 05:47:55 backup-server systemd[1]: rdiff-backup-smoke.service: Deactivated successfully.
💡 说明:
status=0/SUCCESS与日志中的Starting increment operation说明第二次备份走的是增量路径(首轮已建镜像)。远端备份定时任务只需把 ExecStart 的目标换成root@remote-server::/root/smoke-bak即可。
十、常见问题(FAQ)
Q1:/usr/bin/rdiff-backup --version 报 AttributeError: module 'rdiff_backup.Main' has no attribute 'error_check_Main'?
这是 apt(2.0.5)与 pip(2.2.x)混装冲突:pip 的模块目录优先级更高,2.0.5 的启动脚本导入了 2.2.x 的模块。定位方法:
which -a rdiff-backup
python3 -c "import rdiff_backup; print(rdiff_backup.__file__)"
pip3 list | grep -i rdiff
dpkg -l | grep rdiff-backup
解决:二选一保留。留 pip 版本则 apt-get remove --purge -y rdiff-backup;留 apt 版本则 pip3 uninstall rdiff-backup。本文按推荐方案保留 pip 的 2.2.7。
Q2:用 2.0.5 执行 rdiff-backup backup src dst 报 Fatal Error: Switches missing or wrong number of arguments?
backup 子命令是 2.2 引入的动作式新语法,2.0.5 只认旧语法 rdiff-backup src dst(此报错为 2.0.5 实测回显)。混部环境务必核对两端版本:rdiff-backup --version。
Q3:ssh-copy-id 提示 Permission denied, please try again.?
Ubuntu 22.04 sshd 默认 PermitRootLogin prohibit-password,root 无法用密码登录,公钥分发不进去。处理:在目标机 sshd -T | grep permitrootlogin 确认后,按 7.2 节写配置片段 PermitRootLogin yes 并 systemctl reload ssh;分发成功后建议改回默认只留密钥登录,或改用普通用户完成分发。
Q4:pip 安装时提示 Requirement already satisfied: pyxattr/pylibacl ... 但路径是 /usr/lib/python3/dist-packages?
说明这两个包来自 apt(python3-pyxattr/python3-pylibacl),与 pip 的 [meta] extra 等价,能被 rdiff-backup 正常导入(验证命令见 5.3),无需处理。
十一、卸载与清理
pip3 uninstall -y rdiff-backup # 卸载 pip 版(或 apt-get remove --purge -y rdiff-backup 卸载 apt 版)
apt-get remove --purge -y python3-pylibacl python3-pyxattr # 可选:清理 ACL/EA 依赖
rm -rf /root/smoke-bak /root/smoke-src /root/smoke-restored-readme.txt # 清理冒烟测试数据
systemctl disable --now rdiff-backup-smoke.timer # 如配置过 timer,一并移除单元文件
rm -f /etc/systemd/system/rdiff-backup-smoke.{service,timer}
实测回显(pip 卸载):
Found existing installation: rdiff-backup 2.2.7
Uninstalling rdiff-backup-2.2.7:
Successfully uninstalled rdiff-backup-2.2.7
⚠️ 注意:卸载软件不会删除备份仓库(含
rdiff-backup-data/的目录);确认不再需要历史备份后再手动删除对应仓库目录。
十二、参考链接
- 官方安装说明:https://github.com/rdiff-backup/rdiff-backup#1-installation
- PyPI 项目页:https://pypi.org/project/rdiff-backup/(2.2.7 wheel 与
[meta]extra 依赖,查询日期 2026-10-22) - 官网特性页(ACL/EA 依赖说明):https://rdiff-backup.net/features.html
- 1.x → 2.x 迁移文档:https://rdiff-backup.net/migration.html
- 站内相关篇目:《rdiff-backup 介绍与选型指南》、《rsnapshot 介绍与选型指南》