#kubernetes-cluster #secret-management #secret #kubernetes #vault

bin+lib kubevault

kubevault 将 Kubernetes 集群转换为秘密管理系统

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命令行工具

Download history 113/week @ 2024-07-29 456/week @ 2024-08-05 17/week @ 2024-08-12

每月 586 次下载

Apache-2.0

135KB
2K SLoC

Sketchy hexagon split in 3 parts

kubevault - 基于 Kubernetes 的秘密管理


[!WARNING]

该项目仍在开发中,尚未发布;请考虑我将在 main 分支上强力推送,直到第一个版本发布。另外,请记住这是我的第一个 Rust 项目,我仍在学习这种语言,所以代码可能不是最好的。

ℹ️ 关于

kubevault 是一个自制的替代方案,用于 HashiCorp Vault 或像 ASM 这样的托管秘密管理系统,用于管理秘密,旨在拥有一个更简单、资源消耗更少,但安全性也更低的系统。

kubevault 依赖于 Kubernetes 的原生功能来管理秘密(v1/Secret)、访问控制(rbac.authorization.k8s.io/v1/*)以及内部功能,如审计。

kubevault 实际上是一个简单的二进制程序,它从配置目录生成 Kubernetes 清单,并允许您以您想要的方式将它们应用到您的 Kubernetes 集群中(例如 kubectl applyGitOps 等)。它还提供了一些用于管理秘密和访问控制列表的实用程序。

📃 免责声明

[!WARNING]

注意,此项目的目标不是提供另一个 劣质 的 HashiCorp Vault 替代品,成为解决所有秘密管理问题的解决方案,或成为最安全的解决方案……事实上,此解决方案 并不安全 如这些服务,将来也不会。

其目的是提供一种简单的方式来管理我的 Kubernetes 中的秘密,避免秘密散落在便利贴上或操作员计算机上的文本文件中。只要所有秘密都加密,且加密密码或 Kubernetes 集群未被破坏,它就会保持“安全”。

因此,我不建议在生产环境中使用此项目,而如果您不想在 Kubernetes 中烦恼秘密管理(开发集群或家庭实验室)。

😮 为什么要创建自己的解决方案

考虑到 Kubernetes 中管理秘密的解决方案繁多,这是一个相当合理的问题。但在解释我的选择之前,这里是我选择秘密管理解决方案时的背景

  1. 我想将我的秘密安全存储
  2. 我想将所有我的秘密放在一个地方
  3. 我想从任何 Kubernetes 集群访问我的秘密
  4. 我想让我的秘密对我想让他们看到的人可见
  5. 我不想使用超过 1/5GB 的 RAM
  6. 我不想花时间管理解决方案
    1. 创建/修改/删除秘密并应用它们少于 30 秒
    2. 每月更新少于 10 分钟
    3. 在集群完全丢失的情况下,重建所有数据少于一个小时
  7. 我不想依赖第三方服务
  8. 我想对秘密进行版本控制
  9. 我想审计我的秘密

鉴于这些前提条件,列表相当短

  • 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 来管理机密的版本,但您也可以使用您喜欢的任何解决方案,没有什么阻止您使用 svnhgbzrfossil 等。当然,为了保持机密的安全性,我将在提交到仓库之前使用 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