保护 Tower 安装程序密码
保护 Tower 安装程序密码
Red Hat Ansible Automation Platform 的关键组成部分之一是 Ansible Tower。Ansible Tower 有助于扩展 IT 自动化、管理复杂的部署并加快生产力。Ansible Tower 的优势在于其简单性,这也扩展到安装流程:当以非容器版本安装时,一个简单的脚本用于读取初始配置中的变量以部署 Ansible Tower。相同的脚本和初始配置甚至可以重复使用以扩展设置,例如添加更多集群节点。
但是,此初始配置的一部分是数据库、Ansible Tower 本身等的密码。在许多在线示例中,这些密码通常以明文形式存储。我作为 Red Hat 顾问经常遇到的一个问题是如何保护此信息。一个常见的解决方案是在完成 Ansible Tower 的安装后简单地删除该文件。但是,您可能希望保留该文件的原因有很多。在本文中,我将介绍另一种保护安装文件中的密码的方法。
Ansible Tower 的 setup.sh
简要说明一下背景,setup.sh
是用于安装 Ansible Tower 的脚本,在常规安装程序和捆绑安装程序中都提供。setup.sh
脚本只执行几个任务,例如验证 Ansible 是否安装在本地系统上以及设置安装程序日志;但最重要的是,它启动 Ansible 来处理 Ansible Tower 的安装。可以使用 -i
参数向安装程序指定清单文件,或者,如果未指定,则使用默认提供的清单文件(位于 setup.sh
旁边)。在清单文件的第一个部分,我们有组来指定将安装 Ansible Tower 和数据库的服务器
[tower] localhost ansible_connection=local [database]
并且,在这些组规范之后,有一些变量可用于设置连接和密码,并且您通常会在其中输入明文密码,例如
[all:vars] admin_password='T0w3r123!' pg_host='' pg_port='' pg_database='awx' pg_username='awx' pg_password='DB_Pa55w0rd!'
在上面的示例中,这些密码以明文形式显示。我合作过的许多客户出于安全原因,不希望在清单文件中保留其密码的明文。安装 Ansible Tower 后,可以安全地删除此文件,但如果您需要修改安装以向集群添加节点或添加/删除清单组,则需要重新生成此文件。同样,如果您想使用 setup.sh
的备份和恢复功能,您还需要包含所有密码的清单文件,就像最初安装时一样。
Vault 来救援
由于安装程序使用 Ansible 来安装 Ansible Tower,因此我们可以利用一些 Ansible 概念来保护我们的密码。具体来说,我们将使用 Ansible vault 来使用加密密码而不是明文密码。如果您不熟悉 Ansible vault,它是 Red Hat Ansible Automation Platform 自身附带的一个程序,是一种加密和解密数据的机制。它可以用于单个字符串,也可以加密整个文件。在我们的示例中,我们将加密作为密码的单个字符串。如果您最终将清单文件提交到源代码管理工具中,这将非常有用。SCM 将能够显示您在提交中更改的单个密码,而不是只能说加密文件已更改(但无法显示加密文件中更改了哪个密码)。
首先,我们将使用以下命令加密管理员密码(<>
中的字段表示 ansible-vault 的输入)
$ ansible-vault encrypt_string --stdin-name admin_password New Vault password: Confirm New Vault password: Reading plaintext input from stdin. (ctrl-d to end input) <t0w3r123!>admin_password: !vault | $ANSIBLE_VAULT;1.1;AES256 66663534356430343166356461373464336332343439393731363365303063353032373564623537 3466663861633936366463346135656130306538376637320a303738653264333737343463613366 31396336633730323639303436653330386536363838646161653562373631323766346431663461 6536646264633563660a343163303334336164376339363161373662613137633436393263376631 3539 Encryption successful </t0w3r123!>
在此示例中,我们正在运行 ansible-vault 并要求它加密一个字符串。我们已经告诉 ansible-vault 此变量将被称为 admin_password
,并且它的值将为 T0w3r123!(我们将输入到清单文件中的内容)。在示例中,我们使用了“password”作为密码来加密这些值。在生产环境中,应使用更强的密码来执行您的 vault 加密。在命令的输出中,在两次 ctrl-d 输入之后,我们的加密变量将显示在屏幕上。我们将获取此输出并将其放入名为 passwords.yml
的文件中,该文件位于我们的清单文件旁边。在加密第二个 pg_password
后,我们的 password.yml
文件如下所示
--- admin_password: !vault | $ANSIBLE_VAULT;1.1;AES256 66663534356430343166356461373464336332343439393731363365303063353032373564623537 3466663861633936366463346135656130306538376637320a303738653264333737343463613366 31396336633730323639303436653330386536363838646161653562373631323766346431663461 6536646264633563660a343163303334336164376339363161373662613137633436393263376631 3539 pg_password: !vault | $ANSIBLE_VAULT;1.1;AES256 65633239383761336539313437643733323235366337653164383934303563643464626562633865 3130313231666531613131633736386134343664373039620a336237393631333532373066343135 65316431626630633965623134623133353635376236306538653230363038333661623236376330 3664346237396139610a376536373132313237653239353832623433663230393464343331356561 3435
现在我们已经完成了 passwords.yml
文件,我们必须告诉安装程序从该文件中加载密码,并提示我们输入 vault 密码以解密该值。为此,我们将向 setup.sh
命令添加三个参数。第一个选项是 -e@passwords.yml
,这是告诉 Ansible 从指定的文件名(在本例中为 passwords.yml
)加载变量的标准语法。第二个选项将是 --
,它将告诉 setup.sh
脚本任何后续选项都应传递给 Ansible,而不是由 setup.sh
处理。最后一个选项将是 --ask-vault-pass
,它告诉 Ansible 提示我们输入密码才能解密 vault 机密。我们的设置命令将全部变为
$ ./setup.sh -e@passwords.yml -- --ask-vault-pass
如果您通常向 setup.sh
添加参数,则需要将它们合并到此命令结构中。setup.sh
的参数需要放在 --
之前,您传递给 Ansible 的任何参数都放在 --
之后。
使用这些选项运行 setup.sh
时,现在将提示您在 Ansible 安装程序开始之前输入 vault 密码
$ ./setup.sh -e@passwords.yml -- --ask-vault-pass Using /etc/ansible/ansible.cfg as config file Vault <password>: PLAY [tower:database:instance_group_*:isolated_group_*] ******************************************************************************************
在这里,我必须输入我的弱 vault 密码“password”才能使解密过程正常工作。
即使您在清单文件中保留空白密码变量,此技术也能正常工作,因为 Ansible 的变量优先级。任何变量可以获得的最高优先级来自 extra_vars(即我们添加到安装程序中的 -e
选项),因此我们 vault 文件中的值将覆盖清单文件中指定的任何值。
使用此方法,您可以将清单文件和密码文件保留在磁盘上或 SCM 中,并且其中不包含明文密码。
另一种解决方案
如果您只想使用单个清单文件,则可以采取的另一个选项是将现有的 ini 清单文件转换为基于 yaml 的清单。这将允许您直接将变量嵌入为 vault 加密值。虽然执行此操作的范围超出了本文的范围,但示例 inventory.yml
文件可能类似于以下内容
all: children: database: {} tower: hosts: localhost: vars: admin_password: !vault | $ANSIBLE_VAULT;1.1;AES256 66663534356430343166356461373464336332343439393731363365303063353032373564623537 3466663861633936366463346135656130306538376637320a303738653264333737343463613366 31396336633730323639303436653330386536363838646161653562373631323766346431663461 6536646264633563660a343163303334336164376339363161373662613137633436393263376631 3539 ansible_connection: local pg_database: awx pg_host: '' pg_password: !vault | $ANSIBLE_VAULT;1.1;AES256 65633239383761336539313437643733323235366337653164383934303563643464626562633865 3130313231666531613131633736386134343664373039620a336237393631333532373066343135 65316431626630633965623134623133353635376236306538653230363038333661623236376330 3664346237396139610a376536373132313237653239353832623433663230393464343331356561 3435 pg_port: '' pg_sslmode: prefer pg_username: awx rabbitmq_cookie: cookiemonster rabbitmq_password: '' rabbitmq_username: tower tower_package_name: ansible-tower tower_package_release: '1' tower_package_version: 3.6.3
使用此类文件,setup.sh
然后可以调用为
$ ./setup.sh -i inventory.yml -- --ask-vault-pass
使用此方法在升级 Ansible Tower 时需要更多工作,因为提供的清单文件中的任何字段更改都需要反映在您的 yaml 清单中,而之前的方法只需要将清单文件中添加的新密码字段添加到 password.yml
文件中。