7 个版本 (稳定)
1.1.0 | 2024 年 8 月 9 日 |
---|---|
1.0.4 | 2024 年 8 月 6 日 |
1.0.0 | 2024 年 8 月 5 日 |
0.1.0 | 2024 年 8 月 1 日 |
#190 在 命令行工具
每月 586 次下载
135KB
2K SLoC
kubevault - 基于 Kubernetes 的秘密管理
[!WARNING]
该项目仍在开发中,尚未发布;请考虑我将在
main
分支上强力推送,直到第一个版本发布。另外,请记住这是我的第一个 Rust 项目,我仍在学习这种语言,所以代码可能不是最好的。
ℹ️ 关于
kubevault
是一个自制的替代方案,用于 HashiCorp Vault 或像 ASM 这样的托管秘密管理系统,用于管理秘密,旨在拥有一个更简单、资源消耗更少,但安全性也更低的系统。
kubevault
依赖于 Kubernetes 的原生功能来管理秘密(v1/Secret
)、访问控制(rbac.authorization.k8s.io/v1/*
)以及内部功能,如审计。
kubevault
实际上是一个简单的二进制程序,它从配置目录生成 Kubernetes 清单,并允许您以您想要的方式将它们应用到您的 Kubernetes 集群中(例如 kubectl apply
、GitOps
等)。它还提供了一些用于管理秘密和访问控制列表的实用程序。
📃 免责声明
[!WARNING]
注意,此项目的目标不是提供另一个 劣质 的 HashiCorp Vault 替代品,成为解决所有秘密管理问题的解决方案,或成为最安全的解决方案……事实上,此解决方案 并不安全 如这些服务,将来也不会。
其目的是提供一种简单的方式来管理我的 Kubernetes 中的秘密,避免秘密散落在便利贴上或操作员计算机上的文本文件中。只要所有秘密都加密,且加密密码或 Kubernetes 集群未被破坏,它就会保持“安全”。
因此,我不建议在生产环境中使用此项目,而如果您不想在 Kubernetes 中烦恼秘密管理(开发集群或家庭实验室)。
😮 为什么要创建自己的解决方案?
考虑到 Kubernetes 中管理秘密的解决方案繁多,这是一个相当合理的问题。但在解释我的选择之前,这里是我选择秘密管理解决方案时的背景
- 我想将我的秘密安全存储
- 我想将所有我的秘密放在一个地方
- 我想从任何 Kubernetes 集群访问我的秘密
- 我想让我的秘密对我想让他们看到的人可见
- 我不想使用超过 1/5GB 的 RAM
- 我不想花时间管理解决方案
- 创建/修改/删除秘密并应用它们少于 30 秒
- 每月更新少于 10 分钟
- 在集群完全丢失的情况下,重建所有数据少于一个小时
- 我不想依赖第三方服务
- 我想对秘密进行版本控制
- 我想审计我的秘密
鉴于这些前提条件,列表相当短
AWS Secrets Manager, Azure Key Vault, Google Secret Manager, HashiCorp Vault Cloud, ...第三方服务1Password, LastPass, Dashlane, ...第三方服务HashiCorp Vault, Open Bao相当重且管理/维护复杂Bitwarden, Vaultwarden, ...没有易于使用的 ACL 系统且没有 Kubernetes 集成- 可能还有其他一些,但我没有
找到或寻找它们
最终,我没有找到一个能满足我所有需求解决方案...所以我决定创建自己的解决方案。
🚀 开始使用
TLDR;
# Install kubevault
cargo binstall kubevault
# Create a new vault and your first secrets
kubevault new vault
cat <<EOS > vault/kvstore/my-first-secret
---
# This is my first secret
username: "myusername"
password: "mysecretpassword"
EOS
cat <<EOU > vault/access_control/me
# This is my first user
**
EOU
# Apply the changes
kubectl create namespace vault-kvstore
kubevault generate | kubectl apply -f -
📦 安装
二进制文件名为 kubevault
,与项目名称相同,适用于 Linux、macOS 和 Windows。
然而,由于它不是一个广为人知的东西,它不在不同操作系统的包管理器中提供。目前,安装它的唯一方法是通过 cargo
或从 发布页面 下载二进制文件。
如果您已安装 cargo
,可以使用以下命令安装它
cargo install kubevault
或者,可以使用 cargo bininstall 直接从 Github 安装二进制文件
cargo binstall kubevault
🏗️ 如何使用它?
kubevault
二进制文件非常易于使用,有几个命令
kubevault new <vault_dir>
:创建一个新的密室目录结构kubevault generate
:从密室目录生成 Kubernetes 清单- 默认情况下,
kubevault generate
将将清单输出到标准输出。要生成所有清单到目录中,请使用--output-dir
选项
- 默认情况下,
kubevault can-read <user>
:列出用户可以读取的秘密- 以下是一个输出示例
KUBEVAULT_DIR=tests/fixtures/vault target/release/kubevault can-read alice --show-only-allowed List of secrets accessible by user 'alice': ● production-applicationb-postgresql ("production/applicationB/postgresql") ● production-applicationb-cloudflare ("production/applicationB/cloudflare") ● production-applicationb-openai ("production/applicationB/openai") ● production-applicationa-sendgrid ("production/applicationA/sendgrid") ● noproduction-users-alice ("noproduction/users/alice")
- 以下是一个输出示例
- (待办事项)
kubevault external-secret-store <user>
:根据当前的 Kubernetes 配置为用户生成 ExternalSecretStore 清单
☸ 如何将其与 External Secrets 集成?
当创建一个使用 kubevault
的用户时,还会创建一个包含 CA 和连接到 "vault" Kubernetes 集群所使用的令牌的关联机密。这个机密必须被提取,才能在目标集群中使用,以提供对外部机密的访问。
[!注意]
以下命令假定托管机密的 Kubernetes 集群可以通过
vault.kubernetes
> (上下文kubevault
) 访问,并且 vault 已安装在vault-kvstore
命名空间中。<context>
指的是目标集群的上下文。
kubectl --context kubevault get secret --namespace vault-kvstore <user>-token -ojson | jq '.type |= "Opaque" | .metadata |= {name: "vault.kubernetes"}' \
| kubectl --context <context> apply --namespace external-secret --filename -
cat <<EOM | kubectl --context <context> apply --filename -
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: vault.kubernetes
spec:
provider:
kubernetes:
remoteNamespace: vault-kvstore
server:
url: https://vault.kubernetes:6443
caProvider:
type: Secret
name: vault.kubernetes
namespace: external-secret
key: ca.crt
auth:
token:
bearerToken:
name: vault.kubernetes
namespace: external-secret
key: token
EOM
您还可以使用 kubevault external-secret-store <user>
命令,根据以下命令生成基于用户的 ClusterSecretStore
清单
kubevault external-secret-store --kubeconfig <kubeconfig> --context vault.kubernetes <user> | kubectl apply --context <context> --filename -
⚙️ 它是如何工作的?
该解决方案由 2 个 必需 组件组成
- Kubernetes 用于管理机密、用户和 ACL
- 我想将我的秘密安全存储
- 至少,它们在
etcd
数据库中被加密(或对于 k3s,在 SQLite 数据库中)
- 至少,它们在
- 我想将所有我的秘密放在一个地方
- 我想让我的秘密对我想让他们看到的人可见
- 我不想 使用超过 500MB 的 RAM
- 在我的情况下,我将使用已经运行用于关键任务的 Kubernetes 集群[^1],因此这不会花费我任何费用
- 我不想花时间管理解决方案
- 如上所述,管理解决方案的时间已包含在托管这些机密的集群的维护中
- 我希望 审计我的机密[^2]
- 我想将我的秘密安全存储
- External Secrets 用于从外部访问机密
- 我想从任何 Kubernetes 集群访问我的秘密
最后一个剩下的问题是机密的版本控制。为此,我个人使用 git
来管理机密的版本,但您也可以使用您喜欢的任何解决方案,没有什么阻止您使用 svn
、hg
、bzr
、fossil
等。当然,为了保持机密的安全性,我将在提交到仓库之前使用 transcrypt
对其进行加密。但是,就像 git
一样,您也可以使用您喜欢的任何解决方案。另外,因为所有机密都存储在 YAML 格式中,因此可以使用 SOPS
来处理加密功能。
只需添加一点魔法,您就完成了...这就是 kubevault
的作用所在。它是一个简单的二进制文件,可以从配置目录生成 Kubernetes 清单,并允许您以您想要的方式将其应用到您的 Kubernetes 集群中。但是,为了运行,它需要一个特定的目录结构。
📂 目录结构
为了将机密与配置分开,使用以下目录结构
└── vault # Root vault directory, also called the "vault_dir"
├── access_control # Directory containing users and their ACLs
│ ├── user1
│ ├── user2
│ └── ...
└── kvstore # Directory containing all secrets, in a YAML format
├── AAA
└── BBB
└── CCC
└── ...
这是 kubevault
二进制文件正常工作的唯一要求。 kvstore
目录包含所有以 YAML 格式存储的机密,而 access_control
目录包含用户及其 ACL。
🔓 访问控制列表
使用这种基于 Kubernetes 的架构的优点是用户只有一个可能的行为;读取。这极大地简化了 ACL 管理;它只需要用户和他们可以访问的机密之间的一种关系。为了保持简单,ACL 只是一个与用户关联的 globs
(基于 crates:glob-match) 列表,用于过滤他们可以读取或不能读取的文件(或机密)。
例如,如果用户 user1
需要访问秘密 AAA
以及 BBB/CCC
中的所有内容,但不包括 BBB/CCC/EEE
,则在 access_control
目录下创建名为 user1
的文件,内容如下
# Access control rules for user1
AAA
BBB/CCC/**
!BBB/CCC/EEE
[!注意]
🟥 欺骗,裁判!
我确实通过将写入 ACL 的部分委托给
git
服务器来作弊。然而,最受欢迎的git
服务器或提供商都提供在存储库上管理 ACL 的可能性...... 所以让我们利用它吧 😄
🛡️ 漏洞报告
对于报告漏洞,请直接联系我,邮箱为 [email protected]。PGP 公钥可以在我的 Keyoxide 个人资料 中找到。
📜 许可证
本项目受 Apache 2.0 许可证 许可。
[^1]: 更多信息请见 nex·rpi
[^2]: 更多信息请见 Auditing Kubernetes 文档
依赖关系
~163MB
~2M SLoC