Keywhiz 是一个用于管理和分发 Secrets 的系统。它非常适合服务导向架构 (SOA)。此处提供了演示格式的概览
每个组织都有需要 Secrets 的服务或系统。Secrets 例如:
常见做法包括将 Secrets 放在代码旁边的配置文件中,或者带外地(out-of-band)复制文件到服务器。前者容易泄露,后者难以追踪。
Keywhiz 让 Secrets 管理更轻松、更安全。Keywhiz 集群中的服务器将 Secrets 集中存储在加密的数据库中。客户端使用双向认证 TLS (mTLS) 来检索它们有权访问的 Secrets。认证用户通过 CLI 管理 Keywhiz。为了启用工作流程,Keywhiz 通过 mTLS 提供了自动化 API。
Keywhiz 可靠且已在生产环境中使用,但偶尔的更改可能会破坏 API 的向后兼容性。
Keywhiz 服务器提供用于访问和管理 Secrets 的 JSON API。它用 Java 编写,基于 Dropwizard。
Keysync 是一个 Keywhiz 客户端,它使用带有客户端证书的 mTLS 从 Keywhiz 服务器检索 Secrets,并将它们存储在 tmpfs 中。
将 Secrets 以文件形式呈现使 Keywhiz 几乎兼容所有软件。除了 Keywhiz 管理之外,Secrets 的使用者只需要知道如何读取文件。
Keysync 只将所有 Secrets 存储在内存中(通过 tmpfs),并且永不将其持久化到磁盘。如果服务器断电,所有 Secrets 都将安全地从该服务器上移除。
Keysync 的设计减轻了 Keywhiz 服务器中断的影响,因为所有必要的 Secrets 都存储在本地,即使 Keysync 进程重启也可以访问。仅在服务器重启时才需要完全同步 Secrets。
Keywhiz CLI 是一个用于 Keywhiz 管理的 Java 程序。可以查询、添加、移除客户端、Secrets 和组,或将它们相互关联。用户可以认证并使用 CLI。
Keywhiz 大量使用 mTLS 和 X509 证书。它甚至可以帮助为其他服务分发和轮换它们!但是,它假定存在一个 PKI 系统。如果不存在 PKI 或希望为开发环境设置 PKI,可以考虑使用 certstrap 来构建一个简单的初始 PKI。
数据模型由客户端、Secrets、组和用户组成。
客户端通过客户端证书标识。数据库中的条目可以启用/禁用访问或提升自动化权限。
Secrets 具有全局唯一名称,可以包含任何二进制内容。例如,helloworldsrv-database.yml
。Secrets 是不可变的,但可以同时存在多个有序版本。可以添加任意键值元数据以增加可扩展性。
组是将客户端和 Secrets 绑定在一起的粘合剂。客户端被分配到组中(例如,针对主机上的服务、服务本身等)。Secrets 也被分配到组中。如果客户端和 Secrets 共享任何组,客户端将有权访问该 Secret。组不是层级结构,也不能包含其他组。
用户是经过认证的 Keywhiz 管理员。认证是可定制的,目前支持 LDAP 和 bcrypt 哈希密码。初次认证后,后续请求需要 Keywhiz Server 提供的加密 cookie。
服务器和 CLI 的源代码可在 square/keywhiz 中获取。Keysync 源代码在 square/keysync 中。要检出 Keywhiz 源代码:
$ git clone https://github.com/square/keywhiz.git && cd keywhiz
Keywhiz 将数据存储在 MySQL 中,需要 5.7 或更高版本。
从 keywhiz 仓库的根目录,构建服务器:
$ mvn package -am -pl server
运行任何迁移:
$ java -jar server/target/keywhiz-server-*-SNAPSHOT-shaded.jar preview-migrate server/src/main/resources/keywhiz-development.yaml $ java -jar server/target/keywhiz-server-*-SNAPSHOT-shaded.jar migrate server/src/main/resources/keywhiz-development.yaml
添加一个管理员用户:
$ java -jar server/target/keywhiz-server-*-SNAPSHOT-shaded.jar add-user server/src/main/resources/keywhiz-development.yaml
启动服务器:
$ java -jar server/target/keywhiz-server-*-SNAPSHOT-shaded.jar server server/src/main/resources/keywhiz-development.yaml
从 keywhiz 仓库的根目录:
$ mvn package -am -pl cli
运行 CLI 并获取用法说明:
$ ./cli/target/keywhiz-cli-*-SNAPSHOT-shaded.jar
在开发环境中,您可以使用 --devTrustStore
,例如:
$ ./cli/target/keywhiz-cli-*-SNAPSHOT-shaded.jar --devTrustStore --user keywhizAdmin list groups
您可能希望为该命令设置别名以方便使用:
$ alias keywhiz.cli="/path/to/keywhiz-cli-*-SNAPSHOT-shaded.jar"
请参阅 Keysync 的 README。
更多示例可在 Wiki 中找到,这里列举一些。
在开发环境中,您可以使用 --devTrustStore
,这些示例假定您想使用默认的 keywhizAdmin
用户。
在生产环境中,您需要创建自己的用户并确保您的证书已正确签名和信任。
$ keywhiz.cli --devTrustStore --user keywhizAdmin login $ keywhiz.cli add secret --name mySecretName < mySecretFile
自动化 API 需要客户端证书和客户端数据库表中设置 automationAllowed=true
。为了开发目的,您可以使用预生成的 client.p12
密钥库:
$ cat request.json { "name":"example.keytab", "description":"example kerberos keytab", "content":"a2V5dGFiIGNvbnRlbnQ=", "metadata":{"owner":"root","group":"root","mode":"0400"} } $ curl --cert ./server/src/test/resources/clients/client.p12:ponies -H "Content-Type:application/json" -d @request.json https://localhost:4444/automation/secrets/
$ keywhiz.cli --devTrustStore --user keywhizAdmin assign secret --name example.keytab --group kerberos
$ curl --cert ./server/src/test/resources/clients/client.p12:ponies -X PUT "https://localhost:4444/automation/secrets/$SECRET_ID/groups/$GROUP_ID"
Keywhiz 和本网站的源代码可在 GitHub 上获取。
如果您想为 Keywhiz 贡献代码,可以通过 GitHub 完成,即 fork 仓库并发送 pull request。
提交代码时,请尽量遵循现有的约定和风格,以保持代码的可读性。同时,请确保您的代码能够编译并通过测试,可以通过运行 mvn clean verify
来检查。
在您的代码被接受到项目中之前,您还必须签署个人贡献者许可协议 (Individual Contributor License Agreement)。我们使用 cla-assistant.io,当您打开 pull request 时,系统会提示您签署。
Copyright 2015 Square, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://apache.ac.cn/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.