Hashicorp Vault 密钥管理

FreeGuideOnline 最新 2026-07-11

path "secret/data/*" { capabilities = ["read"] }


这个策略授予对 `secret/data` 下所有路径的只读权限。策略与令牌绑定,实现最小权限。

### 1.4 审计设备(Audit Devices)
Vault 会记录所有请求和响应(不含敏感值),可输出到文件、syslog、Elasticsearch 等,满足合规要求。

---

## 二、安装与快速启动

### 2.1 下载安装
从 [HashiCorp 官网](https://developer.hashicorp.com/vault/downloads) 下载对应系统的二进制包,解压后将 `vault` 可执行文件放入 `PATH` 路径中。

验证安装:
```bash
vault version

2.2 启动开发模式

注意:开发模式只用于学习和实验,数据存储在内存中,每次重启都会丢失。切勿用于生产。

vault server -dev -dev-root-token-id="root"

终端会输出一个监听地址(默认 http://127.0.0.1:8200)和根令牌 root。保持此终端运行。

另开一个终端,配置环境变量:

export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='root'

现在你可以用 CLI 与 Vault 交互了。

2.3 生产级启动概览

生产环境通常使用 RAFT 集成存储或外部存储(如 Consul),通过配置文件指定 storagelistener,并进行 vault operator init 初始化分割密钥(Unseal Keys)。初始化后 Vault 处于密封状态,需要用一定数量的 Unseal Key 解封才能使用。这种设计确保了任何单点存储泄露不会直接暴露明文。


三、使用 KV 秘密引擎管理静态密钥

KV 引擎是最常用的静态秘密存储方式,分为 v1 和 v2 两个版本。v2 增加了版本控制、软删除和元数据管理,推荐使用 kv v2。

3.1 启用 KV v2 引擎

默认挂载点 secret/ 在 dev 模式下已经创建为 kv v2 引擎。生产环境需要手动启用:

vault secrets enable -path=my-secrets kv-v2

这条命令在路径 my-secrets 上挂载了一个 kv v2 引擎。

3.2 写入和读取秘密

写入秘密:

vault kv put my-secrets/database username="dbadmin" password="s3cret!"

读取秘密:

vault kv get my-secrets/database

输出会包含版本号、元数据以及实际的数据字段。

3.3 版本管理(仅在 v2)

kv v2 保留多个版本,你可以查看历史版本:

vault kv get -version=1 my-secrets/database

软删除一个版本(保留数据,但标记为删除):

vault kv delete my-secrets/database

彻底删除所有版本:

vault kv metadata delete my-secrets/database

恢复已软删除的版本:

vault kv undelete -versions=2 my-secrets/database

3.4 数据编码与结构化

秘密值可以是任意 JSON 对象,所以你可以存储复杂结构:

vault kv put my-secrets/app config='{"host":"db.example.com","port":5432}'

读取时直接获得完整的 JSON 对象,方便机器解析。


四、动态秘密:按需生成临时凭证

动态秘密是 Vault 最强大的能力之一,它按需创建凭证,并在租约到期后自动撤销,彻底杜绝长期凭证泄露风险。

4.1 动态数据库凭证示例(PostgreSQL)

步骤 1:启用数据库秘密引擎

vault secrets enable database

步骤 2:配置数据库连接

我们需要提供数据库的连接 URL 和用于创建/删除角色的管理员凭证。

vault write database/config/my-postgres-db \
    plugin_name=postgresql-database-plugin \
    allowed_roles="read-role" \
    connection_url="postgresql://{{username}}:{{password}}@localhost:5432/postgres?sslmode=disable" \
    username="vault_admin" \
    password="admin_secret"

步骤 3:定义角色(Role)

角色会映射到一组 SQL 语句,用于创建临时用户。

创建 read-role,执行一条创建用户并授权只读的语句:

vault write database/roles/read-role \
    db_name=my-postgres-db \
    creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
    default_ttl="1h" \
    max_ttl="24h"
  • {{name}}{{password}}{{expiration}} 是 Vault 自动填充的变量。
  • default_ttlmax_ttl 控制凭证生命周期。

步骤 4:获取动态凭证

vault read database/creds/read-role

输出包含 usernamepasswordlease_idlease_duration。现在你可以用这个临时用户连接数据库读取数据。租约到期后,Vault 会自动运行 revocation_statements 删除用户。

4.2 动态云凭证(以 AWS 为例)

同样先启用 AWS 引擎,配置根 IAM 用户权限,然后创建可以生成临时 IAM 用户的角色。应用只需要请求 vault read aws/creds/my-role,即可获得 access_keysecret_key,这些凭证的有效期由策略控制,到期自动撤销。


五、Transit 引擎:加解密即服务

Transit 引擎允许应用在不接触底层加密密钥的情况下执行加密操作,非常适合保护传输中的数据或存储加密。

5.1 启用 Transit 并创建密钥环

vault secrets enable transit
vault write -f transit/keys/orders key_type=ecdsa-p256

这条命令创建一个名为 orders 的密钥,用于后续加密。

5.2 加密数据

需要加密的数据必须先进行 base64 编码。

# 加密
vault write transit/encrypt/orders plaintext=$(echo -n "creditcard=4111111111111111" | base64)

返回 ciphertext,这是加密后的结果。

5.3 解密数据

# 解密
vault write transit/decrypt/orders ciphertext="vault:v1:lccC52cz5UZ9iKT+..."

解密结果中的 plaintext 仍然是 base64 编码,解码后即可得到原始数据:

echo "Y3JlZGl0Y2FyZD00MTExMTExMTExMTExMTEx" | base64 -d

Transit 引擎还支持密钥轮换、数据重加密、签名验证等功能,应用完全无需关心密钥生命周期。


六、访问控制:策略与令牌管理

6.1 编写策略文件

创建文件 app-read.hcl

# 允许读取 my-secrets 路径下的数据
path "my-secrets/data/*" {
  capabilities = ["read"]
}

# 允许列出路径(可选)
path "my-secrets/metadata/*" {
  capabilities = ["list"]
}

将策略写入 Vault:

vault policy write app-read app-read.hcl

6.2 生成受限制的令牌

使用该策略创建一个新令牌:

vault token create -policy=app-read