第4章 Vault入门:架构、部署、配置与密钥引擎

Vault 这东西,很多人第一反应是「密码保险柜」。其实远不止这些。它在我的运维工具链里,扮演的是「密钥边界」——所有敏感信息从它这里过,谁用谁取,用完就丢。今天咱们就把它拆开看看。

4.1 Vault架构概览

Vault 的整体结构其实不复杂。我刚开始接触时,花了一下午才理清各组件的关系。你想想看,一个密钥管理系统要解决三个问题:

  • 密钥存在哪?(存储后端)
  • 密钥怎么取?(认证 + 策略)
  • 密钥怎么用?(密钥引擎)

Vault 的核心组件包括:存储后端、密封机制、API 层、认证后端、策略引擎和密钥引擎。它们之间的关系,我画了张图帮你快速建立印象。

Vault 核心架构 存储后端 Consul / Etcd / 文件 密封 / 解封 HA 节点 核心层:API / 策略 / 审计 认证后端 令牌 / 租约 密钥引擎(KV, Transit, PKI, 数据库, AWS …) 每个引擎独立路径,支持动态密钥和租约

从上往下看:数据先存到存储后端,Vault 启动时默认是「密封」状态,解锁后才能操作。API 层统一处理请求,认证后端鉴权后,再通过策略决定你能不能用某个引擎。嗯,这个设计其实很简洁。

我的习惯: 存储后端我一般用 Consul,因为自带 KV 和健康检查,配合 Vault 的 HA 模式很顺。文件存储只适合实验环境,别上生产。

4.2 安装部署

部署其实不复杂。我用的是 Linux 服务器,二进制运行。推荐走官方包或直接下载 release。

# 以 ubuntu 为例
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install vault

# 或者直接下载二进制
wget https://releases.hashicorp.com/vault/1.17.0/vault_1.17.0_linux_amd64.zip
unzip vault_1.17.0_linux_amd64.zip
sudo mv vault /usr/local/bin/

我比较喜欢用二进制方式,干净,不受包管理器版本滞后影响。安装完成后,跑一下 vault --version 确认。

然后编辑配置文件 /etc/vault.d/vault.hcl。这里有个坑:生产环境千万别把 disable_mlock 设成 true,否则内存中的密钥可能被 swap 出去。我曾经因为这个被安全审计卡过一次。

storage "file" {
  path = "/opt/vault/data"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = true   # 仅测试环境,生产必须配 TLS
}

ui = true
disable_mlock = false
注意: 测试环境可以临时关 TLS,但生产中必须配置证书,否则 API 通信明文传输密钥,等于裸奔。

4.3 初始配置

启动 Vault 服务:sudo systemctl start vault。第一次启动后,Vault 处于密封状态。你需要执行初始化操作,生成解封密钥和根令牌。这会输出 5 个解封密钥(默认),以及一个初始根令牌。切记——这 5 个 shard 和根令牌要分开保存,最好打印并锁在保险柜里。我见过有人把 shard 记在便签上贴显示器,后来…不说了。

export VAULT_ADDR='http://127.0.0.1:8200'
vault operator init   # 生成 5 个 unseal key + root 

拆封需要至少 3 个 shard(默认阈值是 3)。下面是拆封步骤:

vault operator unseal {key1}
vault operator unseal {key2}
vault operator unseal {key3}

拆封完成后,用根令牌登录:

vault login {root_}

登录后可以配置认证后端。我习惯先启用 认证(默认已开),再根据业务选 LDAP 或 K8s 认证。

4.4 密钥引擎介绍

密钥引擎是 Vault 最灵活的部分。说白了,每个引擎就是一个路径下的密钥工厂。Vault 自带 10+ 种引擎,下面是我最常用的三类:

引擎类型 路径示例 典型用途
KV (v1 / v2) secret/ 静态密钥存储,v2 支持版本化
Transit transit/ 数据加解密,密钥不出 Vault
PKI pki/ 动态签发证书,自动轮换
数据库 database/ 动态生成数据库凭据

启用一个引擎很简单:

vault secrets enable -path=my-secrets kv-v2
vault secrets enable -path=encrypt transit
vault secrets enable -path=my-ca pki

每个引擎都有自己独立的策略和控制。比如 KV 引擎,你可以这样写入和读取:

vault kv put my-secrets/db-credentials username="admin" password="P@ssw0rd"
vault kv get my-secrets/db-credentials

而 Transit 引擎,密钥始终留在 Vault 内部,应用只传数据过去加密:

vault write -f encrypt/keys/my-key type=chacha20-poly1305
vault write encrypt/encrypt/my-key plaintext=$(echo -n "敏感数据" | base64)

用 Transit 引擎,数据泄露了也没用——密钥在 Vault 里,攻击者拿到的只是密文。我在一个金融项目中,要求所有支付字段的加密密钥必须由 Vault 管理,不能落在应用服务器上。Transit 完美解决这个边界问题。

数据库引擎更强大。它可以根据策略动态创建临时数据库账号,用完自动销毁。配置起来步骤多一点:

  1. 启用 database 引擎
  2. 配置数据库连接
  3. 创建角色,指定密码策略和 TTL
  4. 应用每次请求获得一个临时凭据
vault secrets enable database
vault write database/config/my-mysql \
  plugin_name=mysql-database-plugin \
  connection_url="{{username}}:{{password}}@tcp(10.0.0.1:3306)/" \
  allowed_roles="web-app" \
  username="root" \
  password="RootPass123"
vault write database/roles/web-app \
  db_name=my-mysql \
  creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" \
  default_ttl="1h" \
  max_ttl="24h"

这样每次应用调用 vault read database/creds/web-app 就能拿到一个 1 小时有效的只读数据库账号。我个人觉得这是 Vault 最吸引人的能力——动态凭据,自动轮换,根本不用手工修改连接串。

避坑: 数据库引擎对 MySQL 5.7+ 支持最好。我踩过 MySQL 5.6 的坑,`CREATE USER` 语法不同导致角色创建失败。建议用 8.0 或 MariaDB 10.3+。

PKI 引擎也是一把好手。内部 CA 签发 TLS 证书,自动吊销和续期,配合 cert-manager 在 K8s 里用非常爽。不过那得留到后面章节细讲,这里先认识一下就行。