我在一台主机上运行 Puppet Server (v8),并在另一台主机上配置 Puppet 代理 (v8),所有这些都在 Rocky 8 上运行。我已经安装了 Puppet Forge 的 MySQL 模块。
如何定义加密的用户密码而不覆盖MySQL模块目录中的hiera.yaml和common.yaml?
我在服务器上的 Puppet 文件夹结构是:
etc/
├─ puppetlabs/
│ ├─ code/
│ │ ├─ environments/
│ │ │ ├─ production/
│ │ │ │ ├─ data/
│ │ │ │ │ ├─ common.yaml
│ │ │ │ ├─ modules/
│ │ │ │ ├─ manifests/
│ │ │ │ │ ├─ site.pp
│ │ │ │ ├─ hiera.yaml
│ │ ├─ modules/
│ │ │ ├─ mysql/
│ │ │ │ ├─ data/
│ │ │ │ │ ├─ common.yaml
│ │ │ │ ├─ manifest/
│ │ │ │ │ ├─ server.pp
│ │ │ │ ├─ hiera.yaml
│ │ │ │ ├─ and more...
我希望使用 Puppet 服务器上安装的 eyaml 来加密 MySQL 的 root 密码。我已运行以下命令来生成密钥并加密密码:
eyaml createkeys
eyaml encrypt -l 'my_mysql_password' -s 'mypassword'
上面生成了格式为
ENC[PKCS7,...==]
的加密密钥。
我的生产环境hiera.yaml是: /etc/puppetlabs/code/environments/product/hiera.yaml
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Per-node data (yaml version)"
path: "nodes/%{::trusted.certname}.yaml"
- name: "Other YAML hierarchy levels"
paths:
- "common.yaml"
- name: 'common'
lookup_key: eyaml_lookup_key
paths:
- "common.yaml"
options:
pkcs7_private_key: /etc/puppetlabs/puppet/keys/private_key.pkcs7.pem
pkcs7_public_key: /etc/puppetlabs/puppet/keys/public_key.pkcs7.pem
我的生产环境common.yaml是: /etc/puppetlabs/code/environments/product/data/common.yaml
---
mysql::server::root_password: >
ENC[PKCS7,...==]
我的生产清单包含: /etc/puppetlabs/代码/环境/生产/清单/site.pp
class { 'mysql::server':
package_name => 'mariadb-server',
root_password => lookup('mysql::server::root_password'),
remove_default_accounts => true,
restart => true,
override_options => {
mysqld => {
'max_connections' => '500',
},
}
}
我的 Puppet 在服务器上的文件夹结构是:[...]
这有点不寻常。 当我使用
puppet module
命令安装模块时,它们通常会进入默认环境的模块空间,但你的 puppetlabs-mysql 会进入全局模块空间。 不过我想应该还是可以的。
如何定义加密的用户密码而不覆盖MySQL模块目录中的
和hiera.yaml
?common.yaml
避免修改模块本身内部的文件是正确的。它们属于模块。 相反,通过修改全局或环境 Hiera 层次结构中的数据文件来自定义模块的属性。 例如,
/etc/puppetlabs/code/environments/production/data/common.yaml
。
我发现您实际上已经这样做了,并且我认为您提出这个问题是因为它并不像您期望的那样对您有用。 我无法确认您是否正确安装和配置了 eyaml 本身,但能够按照您的描述使用
eyaml
命令似乎说明了这一点。
我看到的主要问题是在您的生产环境 Hiera 配置中:您基于相同的
common.yaml
数据文件配置了两个不同的层次结构级别。 这意味着使用默认的首次找到策略的查找将始终由这两个策略中最先列出的策略提供服务,该策略使用默认的 YAML 后端。 那么,在您的情况下,您将获得密码的密文,而不是相应的解密文本。
您有两个可行的选择:
将加密数据移动到单独的文件中,并相应地重新配置 Hiera。 也许是这样的:
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Per-node data (yaml version)"
path: "nodes/%{::trusted.certname}.yaml"
- name: "Common data"
paths:
- "common.yaml"
- name: 'Encrypted common data'
lookup_key: eyaml_lookup_key
paths:
- "secure.eyaml"
options:
pkcs7_private_key: /etc/puppetlabs/puppet/keys/private_key.pkcs7.pem
pkcs7_public_key: /etc/puppetlabs/puppet/keys/public_key.pkcs7.pem
假设 eyaml 数据将进入文件
/etc/puppetlabs/code/environments/production/data/secure.eyaml
,将 common.yaml
文件留给不太敏感的数据。
或
Eyaml 支持混合加密和非加密数据,因此您可以为公共数据设置单个 Eyaml 级别:
---
version: 5
defaults:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Per-node data (yaml version)"
path: "nodes/%{::trusted.certname}.yaml"
- name: 'Common data'
lookup_key: eyaml_lookup_key
paths:
- "common.yaml"
options:
pkcs7_private_key: /etc/puppetlabs/puppet/keys/private_key.pkcs7.pem
pkcs7_public_key: /etc/puppetlabs/puppet/keys/public_key.pkcs7.pem
补充说明:
您已正确命名 Hiera 键,以便自动将数据绑定到类
root_password
的 mysql_server
属性。 当您声明该类时,您不需要执行显式的 lookup()
。 只需从类声明中完全省略 root_password
属性,Puppet 就会用您的 Hiera 数据填充它。
我一直认为,在大多数情况下,类包含类声明(使用
include
、require
或 contain
关键字)比类资源声明(例如您在问题中提出的)更受青睐。 这涉及将所有您的属性自定义移动到您的 Hiera 数据中。
我实际上并没有看到 Eyaml Hiera 后端有什么意义,因为它仅对静态驻留在服务器上的数据进行加密。 如果对手可以读取它,那么即使在您考虑他们也可能获取您的密钥之前,您就已经遇到了大麻烦。 在任何情况下,安全数据的纯文本都会出现在服务器和客户端上的节点目录中,并且相同的纯文本也可能出现在 Puppet 日志和报告中。
对于您询问的特定参数,您可以通过 配置 Hiera 将解密的密码转换为数据类型
Sensitive
,至少减少报告和日志中的出现。 然而,明文密码仍然保留在目录中,至少在客户端上。
IMO,如果值得付出任何努力来保护特定数据,那么您应该直接进行编写并使用
deferred
函数在客户端上动态检索它或与秘密存储集成。