使用 Chef 存储密码和 API 密钥的最佳做法是什么?将数据库密码、AWS api 密钥和其他敏感凭证存储为 Chef 服务器属性以在配方中使用真的很诱人——但是安全考虑呢?这方面的最佳做法是什么?
9 回答
从#chef IRC 频道,许多人将此类数据存储在厨师服务器上的数据包中。
例如,一个数据包可能是“aws”,其中有一个项目“main”,指的是主 AWS 账户。项目中的单独键将用于每个特定值。例如:
{
"id": "main",
"aws_secret_key": "The secret access key",
"aws_access_key": "The access key"
}
您可能还对加密数据包感兴趣。我为管理postfix SASL 身份验证更详细地介绍了它们。
更新:我在我的博客和sysadvent上写了关于Chef Vault的博客文章。
这个问题很老,没有公认的答案,但是,这个问题的正确答案是 Chef 允许使用Encrypted Data Bags将敏感数据存储在Data Bags中。
我认为 Hashicorp 的 Vault 作为一种动态检索加密信息的方式非常有前途,并在该领域留下了 Chef 工作流程的一些奇怪之处。
这是一篇有趣的文章,开始触及主题。 https://www.hashicorp.com/blog/using-hashicorp-vault-with-chef.html
最佳做法是将密钥和密码保存在 Chef data_bags 中。数据包包含数据包项。单个 data_bag 项目为 json 格式。
例如:
{
/* This is a supported comment style */
// This style is also supported
"id": "ITEM_NAME",
"key": "value"
}
加密数据包项: 可以使用共享秘密加密对数据包项进行加密。这允许每个数据包项目存储机密信息(例如数据库密码或 ssh 密钥)或在源代码控制系统中进行管理(没有纯文本数据出现在修订历史记录中)。这可以按如下方式完成:
克里特岛密钥: 例如创建一个名为 encrypted_data_bag_secret 的密钥
$ openssl rand -base64 512 | tr -d '\r\n' > encrypted_data_bag_secret
其中 encrypted_data_bag_secret 是将包含密钥的文件的名称
加密 data_bag: 使用类似于以下的刀命令加密数据包项:
$ knife data bag create passwords mysql --secret-file /tmp/my_data_bag_key
其中“passwords”是数据包的名称,“mysql”是数据包项的名称,“/tmp/my_data_bag_key”是包含密钥的文件所在位置的路径
验证加密: 当数据包项的内容被加密时,它们在被解密之前将不可读。可以使用类似于以下的刀命令来验证加密:
$ knife data bag show passwords mysql
解密数据包: 使用类似于以下的刀命令解密加密的数据包项:
$ knife data bag show --secret-file /tmp/my_data_bag_key passwords mysql
Chef Vault可能是一个不错的选择。它提供了简单的接口,用于在厨师服务器上存储加密数据,访问管理。knife vault ...
使用命令上传、编辑、更新数据。
从配方使用ChefVault::Item.load
命令获取数据
chef_gem "chef-vault"
require 'chef-vault'
item = ChefVault::Item.load("passwords", "root")
item["password"]
设置用户,可以更新数据使用刀vault_admins
属性。
knife[:vault_admins] = [ 'example-alice', 'example-bob', 'example-carol' ]
Chef Encrypted data_bags 确实是一个合法的解决方案。除此之外,您还可以使用 ruby Gem,它允许您使用厨师节点列表的公钥加密厨师数据包项。这仅允许那些厨师节点解密加密值。参看。https://github.com/Nordstrom/chef-vault
我从未尝试过数据包,但这可能是因为我发现除了 chef-solo 之外的所有东西都太复杂了。这就是为什么我使用名为Scalarium的服务的厨师食谱。
因此,密码问题,例如私钥和各种其他凭证是一个非常棘手的问题。我也有一堆需要创建密码或正确设置密码的食谱。
通常我所做的是,我指定 scalarium 人所说的自定义 json。这个 json 类似于node.json
一些人给 chef-solo 使用的chef-solo -j node.json
.
因此,例如在Scalarium Web 界面上的自定义 json中,我有以下内容:
{"super_secure_password":"foobar"}
它的作用是,我的超级安全密码在我的厨师运行期间可用,node[:super_secure_password]
我可以在食谱或模板中使用它。
只要我只使用 Scalarium 部署我的服务器,它就可以正常工作,但我们也在本地 vagrant box 中使用我们的配方来开发环境和更轻松的测试。当我使用 vagrant(甚至是 chef-solo 本身)时,我无法访问 Scalarium 上的自定义 json。
这就是我要解决的问题,在my_recipe/attributes/default
:
set_unless[:super_secure_password] = "test123"
这意味着当我的食谱在 scalarium 之外运行时,密码仍然可用node[:super_secure_password]
并且我的食谱可以工作等等。当配方在 scalarium 上下文中执行时,它不会覆盖它们提供的内容。
目前使用最广泛且在大多数情况下足够安全的方法是使用 chef-vault。
它使用共享密钥来加密您的数据(类似于厨师加密的数据包)。此共享机密会为将使用它的每个客户端和/或用户加密(如果您允许使用它)。
好处:
- 在测试环境中,您可以使用未加密的数据
- 不将共享秘密存储为纯文本
- 一个人可能只授予少数服务器访问权限以读取和写入一些数据包
例子
export EDITOR=vi #sets your favourite text editor
knife vault create secret_data john_doe --admins "admin" --search "*:*" --mode client
上面的命令在secret_data
数据包项中创建:所有客户端john_doe
都可以修改admin
和使用。之后该命令EDITOR
将打开,因此您可以键入 o 粘贴您的秘密数据(在 json 中)。
搜索查询可以是:"role:basic"
- 这意味着只有具有角色的服务器basic
才能读取此数据
knife vault
需要一些额外的安装
在你的食谱中
chef_gem 'chef-vault' do
compile_time true if respond_to?(:compile_time)
end
require 'chef-vault'
item = ChefVault::Item.load("secret_data", "john_doe")
item["password"]
并在metadata.rb
:
depends 'chef-vault', '1.3.0'
更多信息在这里:https ://blog.chef.io/2016/01/21/chef-vault-what-is-it-and-what-can-it-do-for-you/
我建议将 IAM 角色与厨师配置一起使用
require 'chef/provisioning/aws_driver'
iam = AWS::Core::CredentialProviders::EC2Provider.new
puts iam.credentials.inspect
with_driver(
'aws:IAM:eu-west-1',
:aws_credentials => { 'IAM' => iam.credentials }
)