现在使用Ansible Vault对变量和文件进行加密,并使用脚本管理Vault密码,已经有点迟了
有很多信息关于Ansible Vault已经公开,但在这里,我们只将重点放在以下三个要点上,并简要概述了实现方法。
-
- 機密情報の変数(パスワードなど)を暗号化する
-
- ターゲットに配置するファイル(秘密鍵など)を暗号化する
- Vault パスワードをスクリプトで管理する
参考:Ansible Vault — Ansible 文档
-
- 確認環境:
Ansible 2.10.7
Ubuntu 20.04 / Debian 10 (buster)
准备:设定Vault密码
首先,以最简单的方法在文件中设置Vault密码。我们将把密码设置为my_vaultp@ssw0rd,密码文件命名为“~/.vault_pass”。
echo -n 'my_vaultp@ssw0rd' >~/.vault_pass
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass
第2行的ANSIBLE_VAULT_PASSWORD_FILE是Ansible参考的环境变量。
运行ansible-vault ansible-playbook等命令时,根据此环境变量所指示的文件中的密码,变量和文件将自动进行加密/解密。
参考:《Ansible 配置设置 —— Ansible 文档》
加密机密信息的变量(如密码等)
使用 Vault 前
以下是一个示例,变量文件名为 all.yml,其中定义了用户名和明文密码。
group_vars/
└── all.yml
---
my_user: "user_1"
my_password: "myp@ssw0rd" # パスワード文字列 → 暗号化したい
儲藏室使用結束
使用Vault对变量my_password的值进行加密。
首先,将变量文件更改为与原文件同名的目录+两个文件。
group_vars/
└── all/ # 元の変数ファイルと同名のディレクトリ
├── vars # all.yml を移動してリネームする
└── vault # 新規作成
-
- 変数ファイル all.yml を新しいディレクトリ「all」の下に移動し、ファイル名を vars に変更する
- 同じ階層に vault というファイルを新規作成する(YAML)
编辑vars,将my_password的值myp@ssw0rd更改为名为”vault_ +原始变量名”的新变量的引用。
my_user: "user_1"
- my_password: "myp@ssw0rd" # パスワード文字列 → 暗号化したい
+ my_password: "{{ vault_my_password }}" # 直値から「vault_ + 元の変数名」の参照に変更
在新创建的文件“vault”中,我们将新变量命名为“vault_+原始变量名称”并将其值设置为“myp@ssw0rd”。
---
vault_my_password: "myp@ssw0rd"
运行 ansible-vault encrypt 命令来加密 Vault。
ansible-vault encrypt group_vars/all/vault
保险库会被转换为以下这种加密文件。
$ANSIBLE_VAULT;1.1;AES256
65656533363866316462313831663032353031626239633333323862323132616239306130303162
3531363266336538376239646430656134363132633339320a636531653933636336306339636666
(略)
在同一个目录中,文件vars和vault应该成对使用,并遵循以下规则进行实施。
-
- vault 内では vault_ で始まる変数だけを定義し、ペアの vars からのみ参照する
- vars 内で参照する vault_ で始まる変数は、ペアの vault でのみ定義する
通过这样做,即使保险库仍然加密,内部定义也变得明显。
参考:
使用 Ansible Vault 充分利用,以避免在 Git 存储库中公开 AWS 访问密钥 — 株式会社 Nulab(Nulab inc.)Ansible 文档中的变量和 Vault 最佳实践。
对于要放置在目标位置的文件(如私钥等),进行加密处理。
中文原始句:Vault 使用前
中文排列:在使用 Vault 之前
以下是一个示例,将密钥文件”secret_key”部署到目标主机的角色。
roles/
└── ssh_client/
├── files/
| └── secret_key # 暗号化していない秘密鍵ファイル
└── tasks/
└── main.yml
在任务文件中,使用内置模块的”copy”来将secret_key放置到目标位置。
---
- name: Deploy secret key
ansible.builtin.copy:
dest: "/home/my_user/.ssh/secret_key"
mode: 0400
owner: "my_user"
src: "{{ role_path }}/files/secret_key"
- 参考: ansible.builtin.copy – Copy files to remote locations — Ansible Documentation
密钥文件secret_key尚未加密。
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
hwqGhTJo8kiZehDGI6+5ZgZmNS5mpYI7576DAzPwZ7lF1YQhSYRwNWmPpFIT6mQb/RY6Ys
(略)
Vault使用之後
使用”ansible-vault encrypt”命令对secret_key进行加密。
ansible-vault encrypt roles/ssh_client/files/secret_key
密钥会被转换成如下的加密文件。
$ANSIBLE_VAULT;1.1;AES256
65656533363866316462313831663032353031626239633333323862323132616239306130303162
3531363266336538376239646430656134363132633339320a636531653933636336306339636666
(略)
修改工作只需以下这些步骤。
Ansible的copy模块会自动解密文件并将其放置在目标位置,因此您无需修改任务文件。
以下内容引自《文件级加密 — Ansible Vault — Ansible 文档》。
Ansible Vault 可以加密任何文件,包括二进制文件。如果使用 vault 加密的文件作为 src 参数,并且在复制模块、模板模块、解压模块、脚本模块或汇编模块中指定,文件将被解密并放置在目标主机上(前提是在播放执行时提供了有效的 vault 密码)。
以脚本的方式管理Vault密码
您可以使用”将Vault密码输出到标准输出的脚本”来代替普通文本文件,从而能够自由设计Vault密码的管理方式。
之前未经脚本化
为了将密码文件排除在源代码管理之外并将其指定为.gitignore文件,需要向开发成员单独分发以下文件。
my_vaultp@ssw0rd
在环境文件中定义指定密码文件路径的环境变量,并与源代码一同共享。
如果开发环境是Docker,则可以通过设置类似以下的环境文件来在docker-compose中使用env_file:进行配置。
ANSIBLE_VAULT_PASSWORD_FILE="/workspace/.vault_pass"
如果开发环境不是Docker的话,可以在~/.bashrc等文件中导出上述环境变量,或者可以通过ansible.cfg进行以下配置。
vault_password_file = "/workspace/.vault_pass"
脚本化之后
使用“Vault密码输出到标准输出的脚本”代替密码文件。
将脚本的路径指定为相同的位置。
ANSIBLE_VAULT_PASSWORD_FILE="/workspace/.vault_pass.sh"
与其使用环境变量,也可以通过ansible.cfg文件进行指定,方式如下。
vault_password_file = "/workspace/.vault_pass.sh"
脚本本身作为源代码管理的对象进行共享,并单独管理脚本输出的值。
以下是一个简单的示例,展示如何从环境变量中获取Vault密码并输出的脚本。
#!/bin/bash
echo -n "${MY_VAULT_PASSWORD}"
当然,这样做需要将环境变量 MY_VAULT_PASSWORD 分发给开发成员,因此在脚本化之前没有任何改进。
通过脚本化,现在可以自由设计未来 Vault 密码的管理方式。
未来的任务。
为了解决现实项目中所需的安全和运维问题,我们添加了以下文章。
下一次:现在开始使用Ansible Vault(2):将开发、测试、生产环境的Vault密码分别解开 – Qiita
下下次:现在开始使用Ansible Vault(3):使用AWS账户的SSM参数存储为每个环境管理Vault密码 – Qiita