Ansible-sign (CLI) 使用概览

对于 Ansible 自动化平台内容开发者(项目维护者),使用 **ansible-sign** 的主要和支持的方式是通过附带的命令行界面。

命令行界面旨在简化使用 GPG 等密码学技术来验证项目中指定文件是否被篡改的过程。

尽管将来可能会支持其他签署和验证方法,但目前仅支持 GPG 签署和验证。因此,本教程的其余部分假设使用 GPG。

为签署内容创建 GPG 公钥/私钥对的过程在网上有详细的文档,例如,在这篇 Red Hat“启用系统管理员”博文 中。因此,我们假设您已经拥有有效的 GPG 密钥对,并且它位于您的默认 GnuPG 密钥环中。

您可以使用以下命令验证密钥对是否存在。

验证是否存在用于签署内容的有效私钥
$ gpg --list-secret-keys

如果上述命令没有输出,或者只有一行输出,说明创建了“trustdb”,则您的默认密钥环中没有私钥。在这种情况下,请参考上述博文了解如何创建新的密钥对。

如果它产生了除上述以外的输出,则您拥有有效的私钥,可以继续进行 使用 ansible-sign

将 GPG 密钥添加到 AWX 或 Ansible Automation Controller

在命令行中,运行以下命令

$ gpg --list-keys
$ gpg --export --armour <key fingerprint> > my_public_key.asc
  1. 在 AWX/Automation Controller 中,单击“凭证”,然后单击“添加”按钮。

  2. 为新凭证指定一个有意义的名称(例如,“基础设施团队公钥”)。

  3. 对于“凭证类型”,选择“GPG 公钥”。

  4. 单击“浏览”以导航到并选择您之前创建的文件(my_public_key.asc)。

  5. 最后,单击“保存”按钮以完成操作。

现在,您可以在“项目”设置中选择此凭证。一旦选中,内容验证将在以后的项目同步中自动执行。

访问 GnuPG 文档 以获取有关 GPG 密钥的更多信息。有关生成 GPG 密钥对的更多信息,请访问 Red Hat“启用系统管理员”博文

如何访问 ansible-sign CLI 工具

运行以下命令以安装 ansible-sign

安装 ansible-sign
$ pip install ansible-sign

安装完成后,运行

验证 ansible-sign 是否已成功安装。
$ ansible-sign --version

您应该看到类似于以下内容的输出(版本号可能不同)。

ansible-sign --version 的输出
ansible-sign 0.1

恭喜!您已成功安装 ansible-sign

项目目录

我们将从一个简单的 Ansible 项目目录开始。Ansible 文档介绍了项目目录结构的更复杂示例

在我们的示例项目中,我们有一个非常简单的结构。一个 inventory 文件,以及一个 playbooks 目录下的两个小型剧本。

我们的示例项目
$ cd sample-project/
$ tree -a .
.
├── inventory
└── playbooks
    ├── get_uptime.yml
    └── hello.yml

1 directory, 3 files

注意

我们运行的未来命令将假定您的工作目录是项目根目录。 ansible-sign project 命令通常将项目根目录作为其最后一个参数,因此我们将简单地使用 . 来表示当前工作目录。

签署内容

ansible-sign 通过获取项目中所有受保护文件的校验和(sha256),将它们编译成一个校验和清单文件,最后签署该清单文件来防止内容被篡改。

因此,签署内容的第一步是创建一个文件,告诉 ansible-sign 哪些文件需要保护。此文件应名为 MANIFEST.in,并位于项目根目录中。

在内部,ansible-sign 使用 Python 的 distlib 库的 distlib.manifest 模块,因此 MANIFEST.in 必须遵循该库指定的语法。Python 包装用户指南对 MANIFEST.in 文件指令进行了说明

对于我们的示例项目,我们将包含两个指令。我们的 MANIFEST.in 将如下所示

MANIFEST.in
include inventory
recursive-include playbooks *.yml

有了此文件,我们就可以生成校验和清单文件并对其进行签署。这两个步骤都在一个 ansible-sign 命令中完成。

生成校验和清单文件并对其进行签署
$ ansible-sign project gpg-sign .
[OK   ] GPG signing successful!
[NOTE ] Checksum manifest: ./.ansible-sign/sha256sum.txt
[NOTE ] GPG summary: signature created

恭喜,您现在已经签署了第一个项目!

请注意,gpg-sign 子命令位于 project 子命令下。对于签署项目内容,每个命令都将以 ansible-sign project 开头。如上所述,通常情况下,每个 ansible-sign project 命令都将项目根目录作为其最后一个参数。

提示

如前所述,ansible-sign 默认使用您的默认密钥环,并查找第一个可用的私钥来签署项目。您可以使用 --fingerprint 选项指定要使用的特定私钥,甚至可以使用 --gnupg-home 选项指定完全独立的 GPG 主目录。

注意

如果您使用的是桌面环境,GnuPG 将自动弹出对话框,要求您输入私钥的密码。如果此功能不起作用,或者您在没有桌面环境的情况下工作(例如,通过 SSH),则可以在上述命令中,在 gpg-sign 之后使用 -p/--prompt-passphrase 标志,这将导致 ansible-sign 提示您输入密码。

如果我们现在查看项目目录的结构,我们会发现创建了一个新的 .ansible-sign 目录。此目录包含校验和清单文件及其分离的 GPG 签名。

签署后的示例项目
$ tree -a .
.
├── .ansible-sign
│   ├── sha256sum.txt
│   └── sha256sum.txt.sig
├── inventory
├── MANIFEST.in
└── playbooks
    ├── get_uptime.yml
    └── hello.yml

验证内容

如果您接触到一个已签署的 Ansible 项目,并且想要验证它是否被篡改,可以使用 ansible-sign 来检查签名是否有效以及文件的校验和是否与校验和清单中指示的一致。特别是,可以使用 ansible-sign project gpg-verify 命令自动验证这两个条件。

验证我们的示例项目
$ ansible-sign project gpg-verify .
[OK   ] GPG signature verification succeeded.
[OK   ] Checksum validation succeeded.

提示

同样,默认情况下,ansible-sign 使用您的默认 GPG 密钥环来查找匹配的公钥。您可以使用 --keyring 选项指定密钥环文件,或者使用 --gnugpg-home 选项指定不同的 GPG 主目录。

如果验证由于任何原因失败,将打印一些信息以帮助您调试原因。可以通过在您的命令中,在 ansible-sign 后面立即传递全局 --debug 标志来启用更多详细程度。

关于自动化的注意事项

在具有高度可信 CI 环境的环境中,可以自动执行签署过程。例如,可以将 GPG 私钥存储在 GitHub Actions 秘密中,并在 CI 环境中将其导入 GnuPG。然后,可以在正常的 CI 工作流/容器/环境中运行上述签署工作流。

使用 GPG 签署项目时,可以将环境变量 ANSIBLE_SIGN_GPG_PASSPHRASE 设置为签署密钥的密码。这可以在 CI 管道中注入(并屏蔽/保护)。

ansible-sign 将根据具体情况返回不同的退出代码,无论是在签署还是验证过程中。这在 CI 和自动化环境中也很有用,因为 CI 环境可以根据错误采取不同的行动(例如,针对某些错误发送警报,而针对其他错误则静默失败)。

这些代码在代码中使用得相当一致,可以认为是稳定的。

ansible-sign 可能退出的状态代码

退出代码

近似含义

示例场景

0

成功

  • 签名成功

  • 验证成功

1

通用错误

  • 在验证过程中,校验和清单文件包含语法错误

  • 在验证过程中,签名文件不存在

  • MANIFEST.in在签名时不存在

2

校验和验证失败

  • 在验证过程中计算的校验和哈希值与签名校验和清单中的哈希值不同。(也就是说,项目文件已更改,但签名过程未重新完成。)

3

签名验证失败

  • 签名者的公钥不在用户的 GPG 密钥环中

  • 指定了错误的 GnuPG 主目录或密钥环文件

  • 签名的校验和清单文件已被修改

4

签名过程失败

  • 在 GPG 密钥环中找不到签名者的私钥

  • 指定了错误的 GnuPG 主目录或密钥环文件