Restic

来自 ArchWiki

本页面讨论了 restic 备份工具,提供了一个“快速入门”指南,并提出了在 Arch Linux 环境下的最佳实践。

Restic 的主要特性和优点是

  • 加密备份
  • 远程备份
  • 内置压缩支持
  • 高效存储(基于块的增量,数据不重复)
  • 可以灵活使用自定义调度器,例如 cron 或 systemd
  • 使用 Go 编写,提供独立的二进制文件

安装

安装 restic,然后在空目录中初始化仓库(用于本地备份),使用

$ restic init --repo /path/to/backup/directory/

请参阅官方教程

安全

Restic 规定了使用时的威胁模型假设

它对仓库使用对称加密。这给计划备份带来了一些问题[1][2],因为密钥通常必须以纯文本形式存储,以便自动化进程能够创建备份。理想情况下,应该有非对称加密,允许使用公钥(在 restic 的自动化脚本中使用)创建快照,但只能使用私钥解密快照,但这目前不支持。

作为 restic 对称加密的优势,它具有 restic-key(1) 命令来管理仓库的多个密钥。因此,可以添加主密钥和辅助密钥。此外,可以使用 --password-command 选项从密钥库中获取密钥。结合使用,可以保护主密钥并使用辅助密钥

上述方法可以为系统(root 用户)和普通用户配置,从而限制与备份仓库的纯文本密码凭据相关的风险。

此文章或章节需要扩充。

原因

提及 TLS 功能

(在 Talk:Restic 中讨论)
注意:Restic 仓库(备份)不需要使用 LUKS 加密。Restic 默认加密数据。

计划任务

Systemd 定时器

与其他工具如 timeshift[3] 不同,restic 不包含计划任务功能。您需要使用 cronsystemd 定时器

您可以使用现成的项目,例如 restic-automatic-backup-scheduler,或者遵循此示例,该示例创建本地(完整)系统备份,应以 root 用户身份运行。

此示例假设存在一个现有目录,其中已初始化了现有的 restic 仓库(请参阅 #安装)。

创建独立卷

此步骤是可选的,但最好在此处挂载一个单独的卷,以防止自动备份过程可能消耗操作系统可用的所有空间。

首次 restic 备份将需要克隆整个操作系统,因此所需的最小空间量等于操作系统占用的空间(受制于下面描述的路径排除)或您决定备份的任何其他目录。

当然,您需要空间来存储未来任何额外的增量更改,因此最好创建一个卷,其大小是被备份数据的 2 倍甚至 3 倍。例如,如果 / 占用 55G,那么您可以创建 /mnt/restic,大小为 110G

Systemd 服务

您将需要一个服务单元。创建一个

/etc/systemd/system/restic-backup.service
[Unit]
Description=Backup system

[Service]
ExecStart=systemd-inhibit /usr/local/bin/restic-backup
注意:此服务将由下面的定时器调用,但也可以根据需要启动,用于任何计划外的快照。systemd-inhibit(1) 是可选的,但建议使用,以防止在创建备份时意外关闭系统。
配置资源约束

使用 systemd 使您可以选择对备份过程施加资源约束。例如,您可以限制内存和/或 CPU 的量。这是您将在 systemd 服务单元中配置的内容。请参阅 systemd.resource-control(5)

限制 restic 使用的资源的另一种方法是使用 GOMAXPROCS 环境变量,如官方文档中所述。

Systemd 定时器

您还需要一个定时器单元(此定时器每 15 分钟运行一次)

/etc/systemd/system/restic-backup.timer
[Unit]
Description=Timer for full system backups

[Timer]
OnBootSec=5min
OnUnitActiveSec=15min
Unit=restic-backup.service

[Install]
WantedBy=timers.target

备份脚本

您还需要创建一个小的 shell 脚本来传入所有必需的选项,例如

/usr/local/bin/restic-backup
#!/bin/bash

if pgrep -f 'restic backup' > /dev/null; then
  echo 'restic is already running...' 1>&2
  exit 0
fi

set -e
set -v

export RESTIC_REPOSITORY='/mnt/restic'
export RESTIC_PASSWORD_COMMAND='/usr/local/bin/get-restic-password'
export RESTIC_COMPRESSION='off'
export RESTIC_CACHE_DIR=~/.cache/restic

mkdir -p "${RESTIC_CACHE_DIR}"

restic unlock 
restic backup / --exclude-file=/etc/restic/excludes.txt --tag scheduled 
restic check --with-cache --read-data-subset=5G
restic forget --prune --keep-hourly 24 --keep-daily 30 --keep-monthly 6 --keep-weekly 4 --keep-yearly 3
/usr/local/bin/get-restic-password
#!/bin/bash
echo VerySecurePassword123
# chmod 744 /usr/local/bin/restic-backup
# chmod 700 /usr/local/bin/get-restic-password
压缩

如果您要备份尚未压缩的数据(例如大型文本文件),您可能需要考虑在 restic 中启用压缩以节省空间。

快照保留

如果需要,调整上面脚本中的 restic forget --prune --keep-hourly 24 --keep-daily 30 --keep-monthly 6 --keep-weekly 4 --keep-yearly 3 值。

配置优先级

您可能还希望调整备份过程的优先级。如果您经常运行备份,您可能需要降低资源使用率,以防止其影响交互式使用。但是,您应该检查备份需要多长时间,并确保它们不重叠(即,在前一个备份尚未完成时启动新的备份)。

您可以使用 nice(1) 来做到这一点。您可能希望通过在资源密集型命令的开头添加 nice 来调整备份脚本,例如

# nice -n 19 restic backup ...
# nice -n 19 restic check ...

或者,如果您使用 ananicy-cpp,您可能需要确保在 /etc/ananicy.d/ 下的配置文件中配置了优先级。

/etc/ananicy.d/00-types.types
{"type":"file-sync","nice":19,"ionice":7}
/etc/ananicy.d/99-custom/file-sync/restic.rules
{"name": "restic", "type": "file-sync"}

有关更多信息,请参阅 restic FAQ

排除列表

/etc/restic 下添加排除文件,例如

/etc/restic/excludes.txt
/data/**
/dev/**
/home/*/**/*.pyc
/home/*/**/__pycache__/**
/home/*/**/node_modules/**
/home/*/.cache/**
/home/*/.local/lib/python*/site-packages/**
/home/*/.mozilla/firefox/*/Cache/**
/lost+found/**
/media/**
/mnt/**
/proc/**
/root/**
/run/**
/swapfile
/sys/**
/tmp/**
/var/cache/**
/var/cache/pacman/pkg/**
/var/lib/docker/**
/var/lib/libvirt/**
/var/lock/**
/var/log/**
/var/run/**
启用

不要忘记启用 restic-backup.timer

远程只追加备份仓库

与大多数备份解决方案一样,restic 备份通常可以由执行备份的用户修改。这使得备份数据容易受到操纵和勒索软件等威胁。虽然上面的示例以 root 用户身份运行备份,从而防止了本地非特权用户的简单修改,但系统遭到入侵将允许恶意软件也删除/覆盖备份数据,即使该数据位于远程仓库中(因为本地用户已通过身份验证连接到远程仓库)。为了设置无法修改的安全备份解决方案,restic 可以与 rclone 结合使用,以利用其只追加功能在受限的远程系统上运行。

提示:如果您控制远程系统,则该项目的 restic-rest-serverAUR 是另一种选择,它具有 只追加模式
注意:还要注意,只追加仓库也可能存在漏洞,例如,如果攻击者可以操纵备份计划或系统日期。Restic 建议结合备份保留策略,特殊使用其 --keep-within 选项

通过 ssh 设置受限的 'rclone serve'

以下设置会将用户限制为指定的命令,有效地仅允许向路径 /home/myuser/backup 添加新数据,同时防止修改现有文件。

/etc/ssh/sshd_config
/etc/ssh/sshd_config
Match user myuser
  ForceCommand rclone serve restic --stdio --append-only ./backup

通过 rclone 运行 restic

在远程 ssh 服务器上初始化备份仓库

restic -o rclone.program='ssh myuser@backup.tld' -r rclone: init

使用 rclone 作为传输执行 restic 备份

restic -o rclone.program='ssh myuser@backup.tld' -r rclone: backup /home/myuser/importantData

只追加脚本

请注意,不再可能使用 prune 选项来删除旧备份,因为现在无法修改远程仓库上的任何数据。用户只能写入追加新文件并读取现有备份数据以进行恢复。

/usr/local/bin/restic-backup
#!/bin/bash

if pgrep -f 'restic backup' > /dev/null; then
  echo 'restic is already running...' 1>&2
  exit 0
fi

set -e
set -v

export RESTIC_REPOSITORY="rclone:"
export RESTIC_PASSWORD_COMMAND='/usr/local/bin/get-restic-password'
export RESTIC_COMPRESSION='off'
export RESTIC_CACHE_DIR=~/.cache/restic

RCLONE_EXEC="rclone.program=ssh myuser@backup.tld forced-command"
DATA_PATH="/home/myuser/importantData"

mkdir -p "${RESTIC_CACHE_DIR}"

restic -o "${RCLONE_EXEC}" unlock
restic -o "${RCLONE_EXEC}" backup ${DATA_PATH} --exclude-file="$HOME/.local/scripts/excludes" --tag scheduled
restic -o "${RCLONE_EXEC}" check --with-cache --read-data-subset=5G

恢复备份数据

restic -o rclone.program='ssh myuser@backup.tld forced-command' -r rclone: restore latest --target /tmp/restoredData

技巧与诀窍

使用令牌作为第二因素的密码

以下示例使用 Universal 2nd Factor 令牌,在本例中为 YubiKey,来派生用于使用其 --password-command 选项解锁 restic 仓库的密码。先决条件是已设置的 challenge-response 插槽,因为它可用于多种目的。

首先,生成一个随机用户密钥,并将其馈送到令牌的 challenge-response 函数中,以获得其令牌唯一的哈希值

$ dd if=/dev/urandom of=/home/username/resticblob bs=512 count=1
$ chmod 400 /home/username/resticblob
$ ykchalresp -2 -i/home/username/resticblob
71832e30cf9d5adb8672154d7a83fa1684f544d3

其次,复制粘贴哈希值,将其作为用户访问密钥添加到 restic 仓库。

注意:您绝不能将静态哈希值保存在任何地方,其目的是在令牌可用时解锁仓库。要在没有令牌的情况下访问仓库,您可以依赖用于添加新密钥的仓库密码。
$ restic -r /home/username/restic/ key add
enter password for repository: 
repository 045a06ef opened (version 2, compression level auto)
enter new password: 
enter password again: 
saved new key with ID 1991e876106f203c245e45a401b59dedec4aae6656f89152b66eca180385c1b

现在,可以使用令牌透明地访问仓库

$ restic -r /home/username/restic unlock --password-command "ykchalresp -2 -i/home/username/resticblob"
repository 045a06ef opened (version 2, compression level auto)

注意,对于非交互式使用,此方法需要令牌配置,该配置对于 challenge-response 方法没有用户存在(触摸)验证,并且某些令牌不允许配置该功能。相同的限制适用于其他方法,除非使用 --password-command 选项来执行 shell 脚本以相应地准备其输出。也可以使用 --password-file 选项,例如,请参阅