如何使用带有GPG的Duplicity将数据备份到DigitalOceanSpaces
介绍
Duplicity 是一个用 Python 编写的命令行实用程序,可生成加密的 tar 卷以存储在本地或远程存储库中。 它使用 GNU Privacy Guard (GPG) 对其档案进行加密和签名,并使用 rsync 算法来创建增量、节省空间的备份。 备份可以传输到各种存储库,包括本地文件存储、SFTP 或 FTP 服务器以及与 S3 兼容的对象存储。
在本教程中,我们将安装 Duplicity 并介绍如何将项目数据备份到 DigitalOcean Spaces,这是一种与 S3 兼容的对象存储服务。 为此,我们将创建一个 Spaces 存储库,并介绍如何手动将数据备份到其中。 最后,我们将通过创建一个脚本来自动执行此过程,该脚本将设置增量备份和每周完整备份计划。
先决条件
对于本教程,您将需要:
- 一台 Ubuntu 16.04 服务器,按照我们的 Initial Server Setup with Ubuntu 16.04 教程 进行设置。 完成本教程后,您应该拥有一个非 root 的 sudo 用户。
- DigitalOcean Space 和 API 密钥,按照 如何创建 DigitalOcean Space 和 API 密钥 创建。 请务必记下您的空间的以下凭据:
- 访问密钥
- 密钥
- 空间网址
- 存储桶名称
设置好 Space 并掌握这些信息后,您可以继续安装 Duplicity。
安装 Duplicity
要获得最新版本的 Duplicity,我们可以从 Duplicity 发布个人软件包存档 (PPA) 安装它:
sudo apt-add-repository ppa:duplicity-team/ppa
我们还将安装 python-boto
包以访问 Boto,这是一个提供 Amazon Web Services 接口的 Python 包。 这将帮助我们利用 Spaces 与 AWS S3 API 的互操作性。 我们将从官方 Ubuntu 存储库安装 python-boto
,因为此版本与我们的 Ubuntu 服务器映像附带的 Python 版本兼容。 如果您更喜欢使用 Boto3,您可以从源代码安装它,尽管与 Python 3.3+ 的功能兼容性仍在开发中。
除了 python-boto
,我们还将安装 Haveged,该工具将帮助我们生成创建 GPG 密钥所需的 entropy。 为了创建这些密钥,GPG 利用我们系统中的熵或不可预测性水平。 安装 haveged
将帮助我们加快密钥创建过程。
在安装这些软件包之前,请更新本地存储库索引:
sudo apt-get update
然后通过键入以下命令安装 duplicity
、python-boto
和 haveged
:
sudo apt-get install duplicity haveged python-boto
提示确认安装时按y
。 我们现在已经在我们的系统上安装了 Duplicity,并准备好创建我们的项目文件夹和配置文件。
创建备份目录
为了演示备份过程是如何工作的,我们将在非 root 用户的主目录中为我们的备份创建一个目录,以及一些示例数据。 我们将调用我们的目录 sammy_backups
:
mkdir ~/sammy_backups
接下来,创建一个名为 historical_sharks.txt
的示例项目文件:
echo "The ancient Megalodon shark reached lengths of up to 59 feet, and is widely regarded as one of history's most fearsome predators." >> ~/sammy_backups/historical_sharks.txt
有了我们的备份目录和测试数据,我们就可以为我们的非 root 用户生成 GPG 密钥了。
生成 GPG 密钥
接下来,我们将为我们的用户生成一个 GPG 密钥对。 为确保信息的安全传输,GPG 使用公钥加密。 这在我们的上下文中意味着数据将被加密为我们的公钥并发送到我们的存储库。 有关 GPG 密钥和加密的更多信息,请参阅我们关于 如何使用 GPG 对消息进行签名和加密 的教程。
我们的密钥环将存储在我们的用户帐户中名为 ~/.gnupg
的目录中,该目录将在我们生成密钥时创建。 当我们使用 duplicity
命令时,我们将指定一个指向我们的密钥对的公钥标识符。 使用此标识符可以启用数据加密和验证我们对私钥所有权的签名。 加密的数据将被传输到我们的存储库,在那里很难从文件本身推断出文件大小和上传时间。 这可以保护我们的数据,我们的用户可以随时使用私钥完全恢复这些数据。
GPG 应该默认安装在我们的服务器上。 要对此进行测试,请键入:
gpg --version
验证 GPG 已安装后,您可以生成密钥对,如下所示:
gpg --gen-key
您将被问到一系列问题来配置您的密钥:
- 键的类型。 选择 (1) RSA 和 RSA(默认)。
- 键的大小。 按
ENTER
将确认 2048 位的默认大小。 - 密钥到期日期。 通过输入 1y,我们将创建一个一年后过期的密钥。
- 确认您的选择。 您可以通过输入 y 来执行此操作。
- 用户 ID/真实姓名。 输入你的名字。
- 电子邮件地址。 输入您的电子邮件地址。
- 评论。 在这里,您可以输入一个 可选注释,该注释将与您的签名一起可见。
- 更改 (N)ame、©omment、(E)mail 或 (O)kay/(Q)uit? 如果您准备好继续,请键入 O。
- 输入密码。 您将被要求在此处输入 密码。 一定要记下这个密码。 我们将在本教程的其余部分将其称为
your-GPG-key-passphrase
。
创建这些设置后,gpg
将根据系统中的熵级别生成密钥。 由于我们安装了 haveged
,我们的密钥应该很快或立即生成。 您将看到包含以下内容的输出:
Output... gpg: /home/sammy/.gnupg/trustdb.gpg: trustdb created gpg: key your-GPG-public-key-id marked as ultimately trusted public and secret key created and signed. ...
注意 your-GPG-public-key-id
,因为我们将在下一节中使用它来配置我们的本地环境变量。
创建手动备份
我们现在将设置环境变量,这样我们在运行 duplicity
命令时就不需要在命令行中输入任何机密信息。 这些变量将在当前会话期间对我们的用户可用,我们会将它们存储在隐藏目录中,以便以后使用。 duplicity
需要的变量,我们将定义为环境变量,包括我们的空间访问密钥和秘密,以及我们的 GPG 公钥 ID 和密码。
首先,让我们在用户的主目录中创建一个隐藏目录来存储配置文件:
mkdir ~/.duplicity
接下来,让我们创建一个名为 .env_variables.conf
的文件来定义我们的变量,我们将使用 export
语句来完成。 这些语句将使变量可用于程序以供以后使用。 通过键入以下内容打开文件:
nano ~/.duplicity/.env_variables.conf
在该文件中,设置您的 Spaces 访问密钥和秘密,以及您的 GPG 公钥 ID 和密码:
~/.duplicity/.env_variables.conf
export AWS_ACCESS_KEY_ID="your-access-key" export AWS_SECRET_ACCESS_KEY="your-secret-key" export GPG_KEY="your-GPG-public-key-id" export PASSPHRASE="your-GPG-key-passphrase"
完成后保存并关闭文件。
我们现在可以对文件设置权限,以确保只有我们当前的非 root 用户具有读写权限:
chmod 0600 ~/.duplicity/.env_variables.conf
通过键入以下命令使这些变量可在当前 Bash 会话中使用:
source ~/.duplicity/.env_variables.conf
接下来,我们将运行 duplicity
来手动创建 ~/sammy_backups
目录的完整备份。 在没有 full
操作的情况下运行 duplicity
将创建初始完整备份,然后是增量备份。 我们将在第一次使用该命令时创建完整备份,但如果您希望为此目录创建另一个完整的手动备份,则需要指定 full
操作。
我们将在命令中定义的其他选项包括:
--verbosity
:这将指定我们希望输出的信息级别。 我们将指定info
,这将提供比默认notice
设置更多的细节。--encrypt-sign-key
:这将告诉duplicity
加密到我们在GPG_KEY
变量中用your-GPG-public-key-id
标识的对中的公钥。 它还将告诉duplicity
使用相同的标识符来启用签名功能。--log-file
:此选项将指定日志文件的位置,其他程序也可以使用该位置。 如果我们需要进行故障排除,这将为我们提供一个简单的查看位置。 我们将日志文件位置指定为/home/sammy/.duplicity/info.log
。
最后,我们将指定要备份的目录和存储库端点。 我们将备份用户主目录中的 ~/sammy_backups
目录。 我们的存储库将是我们的空间,我们将使用以下信息对其进行定义:s3://spaces_endpoint/bucket_name/
。 您可以按如下方式确定您的端点和存储桶名称:如果您的 Space 的 URL 是 https://sammys-bucket.nyc3.digitaloceanspaces.com
,则 sammys-bucket
是您的存储桶名称,而 nyc3.digitaloceanspaces.com
是您的端点。
我们的 duplicity
命令最终将如下所示:
duplicity --verbosity info --encrypt-sign-key=$GPG_KEY --log-file /home/sammy/.duplicity/info.log /home/sammy/sammy_backups \ s3://nyc3.digitaloceanspaces.com/sammys-bucket/
运行此命令后,我们将看到如下输出:
Output... --------------[ Backup Statistics ]-------------- StartTime 1522417021.39 (Fri Mar 30 13:37:01 2018) EndTime 1522417021.40 (Fri Mar 30 13:37:01 2018) ElapsedTime 0.01 (0.01 seconds) SourceFiles 2 SourceFileSize 4226 (4.13 KB) NewFiles 2 NewFileSize 4226 (4.13 KB) DeletedFiles 0 ChangedFiles 0 ChangedFileSize 0 (0 bytes) ChangedDeltaSize 0 (0 bytes) DeltaEntries 2 RawDeltaSize 130 (130 bytes) TotalDestinationSizeChange 955 (955 bytes) Errors 0 -------------------------------------------------
要检查文件是否按预期上传到您的空间,您可以导航到 DigitalOcean 控制面板 中的 Spaces 页面以检查它们是否存在。
恢复文件
为了测试我们是否可以恢复我们的数据,我们现在将删除我们的示例文件并从我们的存储库中恢复它。 要恢复具有 Duplicity 的文件,我们可以使用 --file-to-restore
选项。 还需要在我们的 duplicity
命令中反转项目的顺序:我们的存储库 URL 现在将作为源,我们的备份目录将是我们恢复文件的目标。
通过键入以下内容删除文件:
rm ~/sammy_backups/historical_sharks.txt
检查以确保文件已被删除:
cat ~/sammy_backups/historical_sharks.txt
您应该看到以下输出:
Outputcat: /home/sammy/sammy_backups/historical_sharks.txt: No such file or directory
接下来,让我们从我们的 Space 中恢复这个文件。 --file-to-restore
选项允许我们指定要恢复的文件的路径。 这个路径应该是相对于我们已经备份的目录的; 在我们的例子中,我们的相对路径将是 historical_sharks.txt
。 我们还将反转 Space URL 和备份目录的顺序,以表明我们正在从存储库中恢复文件:
duplicity --verbosity info --encrypt-sign-key=$GPG_KEY --log-file /home/sammy/.duplicity/info.log --file-to-restore historical_sharks.txt \ s3://nyc3.digitaloceanspaces.com/sammys-bucket /home/sammy/sammy_backups/historical_sharks.txt
您将看到如下输出:
Output... Processing local manifest /home/sammy/.cache/duplicity/d9911d387bb9ee345a171141106ab714/duplicity-full.20180402T170008Z.manifest (195) Found 1 volumes in manifest Deleting /tmp/duplicity-e66MEL-tempdir/mktemp-_A24DP-6 Processed volume 1 of 1
再次运行cat
会输出恢复的historical_sharks.txt
文件的内容:
cat ~/sammy_backups/historical_sharks.txt
OutputThe ancient Megalodon shark reached lengths of up to 59 feet, and is widely regarded as one of history's most fearsome predators.
现在我们已经创建了 ~/sammy_backups
目录的手动备份并从我们的存储库中恢复了数据,我们准备继续自动化备份过程。
自动备份
自动化备份过程有助于确保我们的 ~/sammy_backups
目录中的数据保持可恢复和最新状态。 我们可以使用 cron
作业调度程序来创建一个备份计划,其中包括每周的完整备份和增量备份。 要了解有关使用 cron
安排任务的更多信息,请查看我们关于 如何在 VPS 上使用 Cron 和 Anacron 安排日常任务的教程。
首先,让我们在我们的 ~/.duplicity
目录中创建一个备份脚本:
nano ~/.duplicity/.backup.sh
在此文件中,我们将首先指定此脚本将由 Bash shell 运行:
~/.duplicity/.backup.sh
#!/bin/bash
接下来,我们将创建一个 HOME
变量以用于我们的 source
和 duplicity
命令。 请务必将突出显示的用户名、备份目录和存储桶名称替换为您的信息:
~/.duplicity/.backup.sh
... HOME="/home/sammy" source "$HOME/.duplicity/.env_variables.conf" duplicity \ --verbosity info \ --encrypt-sign-key="$GPG_KEY" \ --full-if-older-than 7D \ --log-file "$HOME/.duplicity/info.log" \ /home/sammy/sammy_backups \ s3://nyc3.digitaloceanspaces.com/sammys-bucket/
source
和 duplicity
命令在这里所做的工作与我们创建手动备份时所做的相同:source
将我们的环境变量加载到当前上下文中,而 [ X186X] 创建加密的 tar 卷以发送到我们的存储库。 我们的选项都保持不变,除了添加了 --full-if-older-than
选项。 设置为 7D
,此选项指定每周进行一次完整备份,只要最后一次完整备份超过 7 天。
我们脚本中的最后一个元素将是 unset
命令,它将删除我们的环境变量作为安全措施:
~/.duplicity/.backup.sh
... unset AWS_ACCESS_KEY_ID unset AWS_SECRET_ACCESS_KEY unset GPG_KEY unset PASSPHRASE
完整的脚本将如下所示:
~/.duplicity/.backup.sh
#!/bin/bash HOME="/home/sammy" source "$HOME/.duplicity/.env_variables.conf" duplicity \ --verbosity info \ --encrypt-sign-key="$GPG_KEY" \ --full-if-older-than 7D \ --log-file "$HOME/.duplicity/info.log" \ /home/sammy/sammy_backups \ s3://nyc3.digitaloceanspaces.com/sammys-bucket/ unset AWS_ACCESS_KEY_ID unset AWS_SECRET_ACCESS_KEY unset GPG_KEY unset PASSPHRASE
当您对脚本感到满意时,您可以保存并关闭文件。 我们还将设置权限以确保只有我们当前的非 sudo 用户才能读取、写入和执行文件:
chmod 0700 ~/.duplicity/.backup.sh
最后,我们可以通过编辑用户的 crontab
文件来自动化我们的备份计划。 通过键入以下命令打开此文件进行编辑:
crontab -e
因为这是我们第一次编辑这个文件,我们会被要求选择一个编辑器:
crontab
no crontab for root - using an empty one Select an editor. To change later, run 'select-editor'. 1. /bin/ed 2. /bin/nano <---- easiest 3. /usr/bin/vim.basic 4. /usr/bin/vim.tiny Choose 1-4 [2]: ...
您可以为 nano 选择 2
,或输入您选择的编辑器对应的数字。
在文件的底部,我们将添加一行来指定我们的脚本应该多久运行一次。 为了测试它的功能,我们可以将时间间隔设置为两分钟,如下所示:
crontab
... */2 * * * * /home/sammy/.duplicity/.backup.sh
保存并关闭文件。 两分钟后,您可以导航到 DigitalOcean 控制面板 中的 Spaces 页面,您应该会在其中看到增量备份文件。 您现在可以修改 crontab
文件以指定您希望用于增量备份的时间间隔。
结论
在本教程中,我们介绍了如何将特定目录的内容备份到 Spaces 存储库。 使用配置文件存储我们的存储库信息,我们创建了数据的手动备份,我们通过恢复示例文件和自动备份计划对其进行了测试。
有关 Duplicity 的更多信息,您可以查看 项目网站 以及 duplicity 手册页 。 本文档涵盖 Duplicity 的许多功能,并提供有关创建完整系统备份的指南。