Ubuntu 22.04 安装 rdiff-backup 指南

Ubuntu 22.04 双路径安装 rdiff-backup(apt 2.0.5 与 pip 2.2.7)、依赖与双机 SSH 免密部署、systemd timer 定时托管及本地+远端首次备份冒烟测试闭环,全部命令实测。

rdiff-backup数据备份rdiff-backup2026/10/22

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。

二、前置条件

  1. 两台机器均为 Ubuntu 22.04(低版本发行版同理,包名略有差异),且网络互通;
  2. 具备 root 权限(本文示例统一用 root,示例密码 q1w2e3r4);
  3. 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   # 内网代理示例,按实际环境替换
  1. 目标机需安装并运行 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-backuppip3 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/ 的目录);确认不再需要历史备份后再手动删除对应仓库目录。

十二、参考链接

  1. 官方安装说明:https://github.com/rdiff-backup/rdiff-backup#1-installation
  2. PyPI 项目页:https://pypi.org/project/rdiff-backup/(2.2.7 wheel 与 [meta] extra 依赖,查询日期 2026-10-22)
  3. 官网特性页(ACL/EA 依赖说明):https://rdiff-backup.net/features.html
  4. 1.x → 2.x 迁移文档:https://rdiff-backup.net/migration.html
  5. 站内相关篇目:《rdiff-backup 介绍与选型指南》、《rsnapshot 介绍与选型指南》