Secrets Engines 是 Vault 的核心组件 —— 它们使我们可以将安全性不仅仅视为一个存储问题,而是一个过程问题。无论是数据库密码、SSH 访问还是 JWT 签名:一切都可以以动态、安全且可追踪的方式进行管理 —— 前提是您了解正确的 Engines,并正确地加以使用。关键不在于种类的繁多,而在于理解与设计。想要在生产环境中有效使用 Vault,就必须深入理解 Secrets Engines。
本文将深入概述 Secrets Engines 的功能、应用场景和生命周期 —— 从如 KV、Transit 或 PKI 等通用 Engines,到面向 Cloud 和 Datenbankplattformen 的专用模块。
什么是 Secrets Engines?
Secrets Engines 是 Vault 中的专用组件,用于存储、生成、加密机密数据,或代表用户执行操作。可以将 Secrets Engine 想象为一种“可插拔服务”,它通过 Vault 中的专用路径进行启用,并根据类型执行不同的任务。
某些 Secrets Engines 主要作为安全存储使用 —— 可比作加密版本的 Redis 或 Memcached。而其他则与外部系统交互,动态生成访问凭据,例如用于 AWS IAM、Oracle 数据库或 SSH 访问的凭据。还有一些则提供加密服务,如 Encryption as a Service、TOTP 和 QR-Code 生成,或用于签发证书。
从技术角度看,每个 Secrets Engine 类似于一个虚拟文件系统,用户通过 read、write 或 delete 等操作与之交互。发送到 Vault 的请求会自动路由到挂载了对应 Engine 的路径。每个 Engine 会定义自己的一组路径和功能。
Secrets Engines 类型:Vault 生态系统概览
Vault 提供种类丰富的 Secrets Engines,大致可分为两类:
专用型 Secrets Engines
这些 Engines 面向特定平台和服务,通常需要对目标平台具备深入的专业知识:
- Cloud:AWS、Azure、Google Cloud、AliCloud
- 数据库:Cassandra、Couchbase、ElasticSearch、HANA、IBM DB2、Influx DB、MongoDB、MongoDB Atlas、MSSQL、MariaDB、MySQL、Oracle Database、PostgreSQL、Redis、Redis Elasticache、Redshift、Snowflake
- 身份服务:Kerberos、LDAP、各类云服务(包括 OCI)、RADIUS、SAML、JWT/OIDC、Okta、Github、CloudFoundry 等
- 基础设施工具:Consul、Nomad、Terraform Cloud
- 消息系统:RabbitMQ
- 其他:Venafi、SSH、TOTP、Transform、多种外部 KMS 等
需要注意的是:Vault 工程师不可能是每个平台的专家。正确配置这些 Engines 通常需要与相应平台的领域专家密切协作。
通用型 Secrets Engines
这些 Engines 属于标准组件,所有 Vault 用户都应熟悉:
- Cubbyhole:临时性、与令牌绑定的数据存储。适用于仅保存在内存中、重启后会丢失或应被丢弃的私密和易失性 Secrets。
- Key/Value (KV):最常见的 Engine,用于定义 Key 及其关联的 Value,例如用户名和密码。KV v2 支持版本控制,而 KV v1 已被视为过时。
- Database:通过插件支持 13 种以上的平台,可自动创建和吊销数据库凭据。
- Transit:提供无存储的加密服务。适用于本地处理敏感数据、但需要集中密钥管理的应用场景。
- PKI:创建和管理 X.509 证书 —— 是构建内部 CA 方案的必备组件。
- Identity:支持身份映射、别名管理和策略分配。
考试相关的 Secrets Engines
在 Vault Associate 与 Vault Operations Professional 认证考试中,您应熟练掌握以下 Secrets Engines:
- Cubbyhole
- KV
- Identity
- PKI
- Database
- Transit
我们将在后续的独立文章中对这些 Engines 进行详细讲解。
Secrets Engines 的生命周期
每个 Secrets Engine 通常都会经历以下生命周期:
- 被启用,
- 被配置,
- 被使用,
- 被定期调优(“tuned”),以及
- 在多数使用场景下,最终被停用。
尤其是那些动态生成的 Secrets Engines(如用于自动创建的数据库、云账户或租户)不仅需要启用,还必须定期进行调整(调优),并在相关基础设施组件移除时及时停用。这不仅是清理工作,更是确保数据质量与合规性(如数据保护要求)的重要措施。因此,对每一个操作的可审计性是 Vault 安全架构中的核心要素。
Secrets Engines 的启用与隔离
要使用某个 Secrets Engine,必须首先将其启用 —— 可通过 CLI、API 或 UI 完成。
Secrets Engines 必须由用户主动启用(Cubbyhole 和 Identity 除外,它们默认启用)。启用时需选择一个唯一的、可自定义的路径,作为 mount point 使用。Vault 在此过程中执行以下原则:
- 区分大小写的路径:kv/ 和 KV/ 是不同的挂载点
- 避免命名冲突:存在 foo/ 挂载点时不能启用 foo/bar/
- 每个 Engine 是隔离的:仅能访问自身的数据空间
作为工程师或终端用户,以下特性务必牢记 —— 它们也是认证考试中常见的考点:
- 默认启用:Cubbyhole 和 Identity 两个 Engine 是系统预设启用,无法停用。
- 手动启用:所有其他 Engines 都需要显式启用。
- 启用方式:可通过命令行(CLI)、API 或图形界面(UI)进行启用。
- 通过路径进行交互:与 Secrets Engine 的所有交互均通过其挂载路径进行。
- 隔离路径:每个启用的 Engine 与系统其他部分在逻辑和物理上都是隔离的。若启用租户功能,即使挂载路径相同,各个租户的 Engine 也彼此隔离。
- 路径命名灵活:路径名称不必与 Secrets Engine 的名称或类型一致。
- 区分大小写:路径对大小写敏感,kv/ 与 KV/ 属于两个不同的 Engine。
在后台,每个被启用的 Engine 会在 Vault 的存储层中分配一个随机生成的基于 UUID 的路径。该存储路径类似于 chroot。这种“Barrier View” 模型确保每个 Engine 仅能访问自身的数据。即便某个 Engine 被攻破,也无法访问同一命名空间(租户)中的其他 Secrets Engines。
专家提示:建议为 Secrets Engines 制定一套组织内部统一且一致的命名规范。若使用命名空间,强制性的命名规范可有效降低整体系统的复杂度、运维风险和操作成本。
通过命令行启用
命令 vault secrets
是通过 CLI 管理 Secrets Engines 的主要入口。常用子命令包括:
- disable:禁用 Secrets Engine
- enable:启用新的 Secrets Engine
- list:列出所有已启用的 Secrets Engines
- move:更改 Secrets Engine 的挂载路径
- tune:配置 Secrets Engine 的参数
示例
1. 在默认路径上启用 KV(Key/Value)Secrets Engine
[rramge@ol9 ~]$ vault secrets enable kv Success! Enabled the kv secrets engine at: kv/ [rramge@ol9 ~]$
验证:
[rramge@ol9 ~]$ vault secrets list Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_fe623ade per-token private secret storage identity/ identity identity_cd5a6252 identity store kv/ kv kv_62ea76c1 n/a sys/ system system_b247c51c system endpoints used for control, policy and debugging [rramge@ol9 ~]$
如您所见,除了 KV Secrets Engine 外,系统还列出了 Cubbyhole 和 Identity Engines,它们始终存在。System Engine 并不用于存储数据,而用于 Vault 的控制、策略和调试 —— 我们将在后续文章中视需要展开。
2. 在自定义路径上启用 KV(Key/Value)Secrets Engine:
在此示例中,还传入了参数 --path=<mount-point>:
[rramge@ol9 ~]$ vault secrets enable -path=mykv kv Success! Enabled the kv secrets engine at: mykv/ [rramge@ol9 ~]$
验证:
[rramge@ol9 ~]$ vault secrets list Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_fe623ade per-token private secret storage identity/ identity identity_cd5a6252 identity store kv/ kv kv_62ea76c1 n/a mykv/ kv kv_5fa9f096 n/a sys/ system system_b247c51c system endpoints used for control, policy and debugging [rramge@ol9 ~]$
3. 使用描述信息启用 KV(Key/Value)Secrets Engine
您也可以传入 --description 参数:
[rramge@ol9 ~]$ vault secrets enable -path=mykv --description="My K/V Secret Store" kv Success! Enabled the kv secrets engine at: mykv/ [rramge@ol9 ~]$
最终效果如下:
[rramge@ol9 ~]$ vault secrets list Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_fe623ade per-token private secret storage identity/ identity identity_cd5a6252 identity store kv/ kv kv_62ea76c1 n/a mykv/ kv kv_645ae3a2 My K/V Secret Store sys/ system system_b247c51c system endpoints used for control, policy and debugging [rramge@ol9 ~]$
4. 停用 Secrets Engine
我们现在将 kv/ 和 mykv/ 这两个 Secrets Engines 移除:
[rramge@ol9 ~]$ vault secrets disable mykv Success! Disabled the secrets engine (if it existed) at: mykv/ [rramge@ol9 ~]$ vault secrets disable kv Success! Disabled the secrets engine (if it existed) at: kv/ [rramge@ol9 ~]$
注意:如果您禁用了一个已有数据的 Secrets Engine,可能会造成数据丢失!停用 Secrets Engine 会删除所有相关数据 —— 在处理像 KV 或 PKI 等持久性 Engine 时,务必提前做好备份。
通过 Terraform 的 API 启用
除了 CLI,也可通过 Terraform 以声明式方式管理 Secrets Engine。您可以在此处找到用于管理 Secrets Engines 及其属性的 Terraform 模块:https://github.com/ICT-technology/terraform-vault-mount/
该模块支持在一次模块调用中动态创建和管理多个 Secrets Engines,能够主动捕捉 API 错误,实施最佳实践,并支持使用 terraform test 的自动化测试流水线。
使用示例
您可以在 examples/ 子目录中找到一个可直接运行的示例。请正确设置您的环境变量 $VAULT_ADDR 和 $VAULT_TOKEN,之后便可直接在该目录中执行该示例 —— 但请确保您是在私有开发环境中运行,而非生产环境。
该模块将创建以下 Secrets Engines:
- kv-v2
- pki
- kubernetes
- ldap
- transit
- aws
成功执行 terraform apply 后,该模块将输出已创建 Secrets Engines 的 mount-accessors 列表。这些 mount-accessors 可用于在其他 Terraform 资源的配置中作为引用,也适用于审计、动态策略分配等场景。
examples/main.tf:
### BEGIN FILE: examples/main.tf ###
module "vault\_mounts" {
source = "git::[https://github.com/ICT-technology/terraform-vault-mount.git?ref=v2025.1.3](https://github.com/ICT-technology/terraform-vault-mount.git?ref=v2025.1.3)"
mounts = {
kvv2 = {
path = "kv-v2"
type = "kv-v2"
description = "Key-Value Version 2 Secrets Engine"
options = { version = "2" }
}
```
pki = {
path = "pki"
type = "pki"
description = "PKI Secrets Engine"
default_lease_ttl_seconds = 3600
max_lease_ttl_seconds = 86400
}
kubernetes = {
path = "kubernetes"
type = "kubernetes"
description = "Kubernetes Auth Engine"
}
ldap = {
path = "ldap"
type = "ldap"
description = "LDAP Auth Engine"
options = { case_sensitive_names = "true" }
}
transit = {
path = "transit"
type = "transit"
description = "Transit Secrets Engine for Encryption-as-a-Service"
options = {
convergent_encryption = false
}
}
aws = {
path = "aws"
type = "aws"
description = "AWS Secrets Engine"
}
```
}
}
### END FILE: examples/main.tf ###
examples/outputs.tf:
### BEGIN FILE: examples/outputs.tf ###
output "mount\_accessors" {
description = "Accessors for the configured Vault mounts"
value = module.vault\_mounts.mount\_accessor
}
### END FILE: examples/outputs.tf ###
在实际操作中,对该示例执行 terraform apply 会如下所示:
[rramge@ol9 examples]$ terraform apply
[...]
Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes module.vault\_mounts.vault\_mount.this\["aws"]: Creating... module.vault\_mounts.vault\_mount.this\["transit"]: Creating... module.vault\_mounts.vault\_mount.this\["kvv2"]: Creating... module.vault\_mounts.vault\_mount.this\["ldap"]: Creating... module.vault\_mounts.vault\_mount.this\["kubernetes"]: Creating... module.vault\_mounts.vault\_mount.this\["pki"]: Creating... module.vault\_mounts.vault\_mount.this\["aws"]: Creation complete after 1s \[id=aws] module.vault\_mounts.vault\_mount.this\["pki"]: Creation complete after 1s \[id=pki] module.vault\_mounts.vault\_mount.this\["transit"]: Creation complete after 1s \[id=transit] module.vault\_mounts.vault\_mount.this\["kvv2"]: Creation complete after 1s \[id=kv-v2] module.vault\_mounts.vault\_mount.this\["kubernetes"]: Creation complete after 1s \[id=kubernetes] module.vault\_mounts.vault\_mount.this\["ldap"]: Creation complete after 1s \[id=ldap] Apply complete! Resources: 6 added, 0 changed, 0 destroyed. Outputs: mount\_accessors = { "aws" = "aws\_e2982916" "kubernetes" = "kubernetes\_6671be50" "kvv2" = "kv\_26a6e11a" "ldap" = "ldap\_8fbb6083" "pki" = "pki\_2d96cba8" "transit" = "transit\_25465e3f" } \[rramge\@ol9 examples]\$
通过 Web 界面启用
Secrets Engines 也可以通过 Web 界面启用。Vault 提供一个可选启用的 Web UI,但它设计非常简洁,更适合作为营销演示的展示界面,而非在大型生产环境中进行日常管理。
在此不打算详细介绍基于 Web 的启用方式 —— 作为一名技术娴熟、经验丰富的读者,您应已认识到在安全关键环境中,复现性配置步骤和自动化的重要性,而非依赖鼠标点击。建议您深入学习 CLI 命令,并理解 Infrastructure-as-Code 的价值,这对实践操作和认证考试准备都至关重要。
展望
在下一篇关于 HashiCorp Vault 的深度文章中,我们将初步探讨 Key/Value Secrets Engine,随后再深入展开详细内容。