HashiCorp Vault 密钥管理系统部署与运维实战

一、概述

HashiCorp Vault 是企业级密钥管理解决方案,提供安全的密钥存储、动态密钥生成、数据加密等服务。本文介绍 Vault 的生产环境部署方案与运维实践。

1.1 核心功能

  • 密钥存储:安全存储 API 密钥、密码、证书等敏感信息
  • 动态密钥:按需生成临时凭证,自动轮换
  • 数据加密:加密即服务 (EaaS),无需管理密钥
  • 审计日志:完整的访问审计追踪
  • 多后端支持:Consul、Raft、数据库等存储后端

1.2 架构组件

1
2
3
4
5
6
7
8
9
10
11
12
┌─────────────────────────────────────────────────────────┐
│ Vault Server │
├─────────────┬─────────────┬─────────────┬───────────────┤
│ Secrets │ Auth │ System │ Storage │
│ Engines │ Methods │ Backend │ Backend │
├─────────────┼─────────────┼─────────────┼───────────────┤
│ - KV │ - Token │ - Audit │ - Raft │
│ - Database │ - LDAP/AD │ - Seal │ - Consul │
│ - PKI │ - OIDC │ - Health │ - PostgreSQL │
│ - Transit │ - Kubernetes│ - Metrics │ - MySQL │
│ - SSH │ - AWS IAM │ │ - S3 │
└─────────────┴─────────────┴─────────────┴───────────────┘

二、部署方案选择

2.1 存储后端对比

后端类型 适用场景 高可用 复杂度
Raft (Integrated) 生产环境首选 支持 (3/5 节点)
Consul 已有 Consul 集群 支持
PostgreSQL 依赖现有 DB 需额外配置
In-Memory 开发测试 不支持

2.2 推荐架构

生产环境:3 节点 Raft 集群 + 负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
                ┌─────────────┐
│ HAProxy │
│ / Nginx │
└──────┬──────┘
┌───────────────┼───────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Vault-1 │ │ Vault-2 │ │ Vault-3 │
│ (Leader) │ │ (Follower) │ │ (Follower) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
└───────────────┴───────────────┘
Raft Consensus

三、安装部署

3.1 系统准备

1
2
3
4
5
6
7
8
9
10
11
12
# 所有节点执行
# 创建 vault 用户和组
sudo useradd --system --home /etc/vault.d --shell /bin/false vault

# 创建数据目录
sudo mkdir -p /opt/vault/data
sudo chown vault:vault /opt/vault/data
sudo chmod 700 /opt/vault/data

# 创建配置目录
sudo mkdir -p /etc/vault.d
sudo chown vault:vault /etc/vault.d

3.2 安装 Vault

1
2
3
4
5
6
7
8
# 下载并安装
wget https://releases.hashicorp.com/vault/1.15.4/vault_1.15.4_linux_amd64.zip
unzip vault_1.15.4_linux_amd64.zip
sudo mv vault /usr/local/bin/

# 验证安装
vault version
# 输出:Vault v1.15.4

3.3 配置 Raft 集群

节点 1 配置 (/etc/vault.d/vault.hcl):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-1"

retry_join {
leader_api_addr = "https://vault-1.example.com:8201"
}
retry_join {
leader_api_addr = "https://vault-2.example.com:8201"
}
retry_join {
leader_api_addr = "https://vault-3.example.com:8201"
}
}

listener "tcp" {
address = "0.0.0.0:8200"
cluster_address = "0.0.0.0:8201"
tls_cert_file = "/etc/vault.d/tls/vault.crt"
tls_key_file = "/etc/vault.d/tls/vault.key"
tls_min_version = "tls12"
}

api_addr = "https://vault-1.example.com:8200"
cluster_addr = "https://vault-1.example.com:8201"

ui = true

log_level = "info"

audit {
file {
file_path = "/var/log/vault/audit.log"
log_raw = false
}
}

节点 2、3 配置:修改 node_idapi_addrcluster_addr

3.4 TLS 证书配置

1
2
3
4
5
6
7
8
9
10
# 生成自签名证书 (生产环境请使用正式证书)
openssl genrsa -out vault.key 2048
openssl req -new -key vault.key -out vault.csr \
-subj "/CN=vault.example.com/O=HashiCorp"
openssl x509 -req -days 365 -in vault.csr -signkey vault.key -out vault.crt

# 复制到所有节点
sudo cp vault.crt vault.key /etc/vault.d/tls/
sudo chown vault:vault /etc/vault.d/tls/*
sudo chmod 600 /etc/vault.d/tls/vault.key

3.5 systemd 服务配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# /etc/systemd/system/vault.service
[Unit]
Description=HashiCorp Vault
Documentation=https://www.vaultproject.io/docs/
Requires=network-online.target
After=network-online.target

[Service]
User=vault
Group=vault
ExecStart=/usr/local/bin/vault server -config=/etc/vault.d/vault.hcl
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
1
2
3
4
# 启动服务
sudo systemctl daemon-reload
sudo systemctl enable vault
sudo systemctl start vault

四、初始化与配置

4.1 初始化 Vault

1
2
3
4
5
# 在节点 1 执行初始化
export VAULT_ADDR="https://vault-1.example.com:8200"
export VAULT_CACERT="/etc/vault.d/tls/vault.crt"

vault operator init -key-shares=5 -key-threshold=3

输出示例

1
2
3
4
5
6
Unseal Key 1: xxxxxx-1
Unseal Key 2: xxxxxx-2
Unseal Key 3: xxxxxx-3
Unseal Key 4: xxxxxx-4
Unseal Key 5: xxxxxx-5
Initial Root Token: hvs.xxxxxxxxxxxxx

重要:安全保存 Unseal Keys 和 Root Token!

4.2 解封 Vault

1
2
3
4
5
6
7
# 每个节点都需要解封 (至少需要 3 个 key)
vault operator unseal <unseal-key-1>
vault operator unseal <unseal-key-2>
vault operator unseal <unseal-key-3>

# 查看状态
vault status

4.3 加入集群 (节点 2、3)

1
2
3
4
# 在节点 2、3 执行
vault operator raft join https://vault-1.example.com:8200

# 然后同样执行 unseal 操作

4.4 验证集群状态

1
vault operator raft list-peers

输出示例

1
2
3
4
5
Node     Address                State       Voter
---- ------- ----- -----
vault-1 vault-1:8201 leader true
vault-2 vault-2:8201 follower true
vault-3 vault-3:8201 follower true

五、认证方法配置

5.1 启用 AppRole 认证 (推荐用于应用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 启用 AppRole
vault auth enable approle

# 创建角色
vault write auth/approle/role/webapp \
token_policies="webapp-policy" \
token_ttl=1h \
token_max_ttl=4h \
secret_id_num_uses=10 \
secret_id_ttl=24h

# 获取 RoleID
vault read auth/approle/role/webapp/role-id

# 获取 SecretID
vault write -f auth/approle/role/webapp/secret-id

5.2 启用 Kubernetes 认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启用 Kubernetes auth
vault auth enable kubernetes

# 配置 Kubernetes API 地址
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

# 创建角色
vault write auth/kubernetes/role/webapp \
bound_service_account_names="vault-app" \
bound_service_account_namespaces="production" \
policies="webapp-policy" \
ttl=1h

5.3 启用 LDAP/AD 认证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 启用 LDAP
vault auth enable ldap

# 配置 LDAP 服务器
vault write auth/ldap/config \
url="ldaps://ldap.example.com" \
userattr="uid" \
userdn="ou=users,dc=example,dc=com" \
groupdn="ou=groups,dc=example,dc=com" \
binddn="cn=admin,dc=example,dc=com" \
bindpass="password" \
certificate=@/etc/vault.d/tls/ldap-ca.crt

# 创建策略映射
vault write auth/ldap/groups/admins policies=admin-policy

六、Secrets 引擎配置

6.1 KV Secrets Engine (键值存储)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 启用 KV v2
vault secrets enable -path=secret kv-v2

# 写入密钥
vault kv put secret/webapp/database \
username="dbuser" \
password="s3cr3t" \
host="db.example.com"

# 读取密钥
vault kv get secret/webapp/database

# 列出密钥
vault kv list secret/webapp/

# 删除密钥
vault kv delete secret/webapp/database

# 查看历史版本
vault kv history secret/webapp/database

6.2 Database Secrets Engine (动态数据库凭证)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 启用数据库引擎
vault secrets enable database

# 配置 MySQL 连接
vault write database/config/mysql \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(db.example.com:3306)/" \
allowed_roles="webapp-role" \
username="vault-admin" \
password="admin-password"

# 创建角色
vault write database/roles/webapp-role \
db_name=mysql \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; \
GRANT SELECT, INSERT, UPDATE ON webapp.* TO '{{name}}'@'%';" \
default_ttl="1h" \
max_ttl="24h"

# 获取动态凭证
vault read database/creds/webapp-role

6.3 PKI Secrets Engine (证书管理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 启用 PKI
vault secrets enable pki

# 配置最大租期
vault secrets tune -max-lease-ttl=87600h pki

# 生成根证书
vault write -format=json pki/root/generate/internal \
common_name="example.com" \
ttl=87600h > root_ca.json

# 配置 URL
vault write pki/config/urls \
issuing_certificates="$VAULT_ADDR/v1/pki/ca" \
crl_distribution_points="$VAULT_ADDR/v1/pki/crl"

# 创建角色
vault write pki/roles/webapp \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl="720h" \
key_type="rsa" \
key_bits=2048

# 签发证书
vault write -format=json pki/issue/webapp \
common_name="app.example.com" \
ttl="720h" > cert.json

6.4 Transit Secrets Engine (加密即服务)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启用 Transit
vault secrets enable transit

# 创建加密密钥
vault write -f transit/keys/webapp-key \
type="aes256-gcm96"

# 加密数据
vault write transit/encrypt/webapp-key \
plaintext=$(echo -n "sensitive-data" | base64)

# 解密数据
vault write transit/decrypt/webapp-key \
ciphertext="vault:v1:xxxxx"

七、策略与权限管理

7.1 创建策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# webapp-policy.hcl
path "secret/data/webapp/*" {
capabilities = ["read", "list"]
}

path "database/creds/webapp-role" {
capabilities = ["read"]
}

path "transit/encrypt/webapp-key" {
capabilities = ["update"]
}

path "transit/decrypt/webapp-key" {
capabilities = ["update"]
}

# 禁止访问
path "secret/metadata/*" {
capabilities = ["deny"]
}
1
2
# 应用策略
vault policy write webapp-policy webapp-policy.hcl

7.2 策略最佳实践

  1. 最小权限原则:只授予必要的权限
  2. 路径隔离:不同应用使用不同的路径前缀
  3. 定期审计:审查策略使用情况
  4. 版本管理:策略变更纳入版本控制

八、运维管理

8.1 备份与恢复

1
2
3
4
5
6
7
8
# 使用 raft 快照备份
vault operator raft snapshot save vault-backup.snap

# 恢复快照 (会覆盖当前数据)
vault operator raft snapshot restore vault-backup.snap

# 验证快照
vault operator raft snapshot inspect vault-backup.snap

8.2 监控指标

1
2
3
4
5
6
7
8
9
10
11
12
# 启用 Prometheus 指标
# 在配置中添加:
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}

# 关键指标:
# - vault_core_unsealed: 是否已解封
# - vault_runtime_alloc_bytes: 内存使用
# - vault_token_count: 活跃令牌数
# - vault_raft_fsm_pending: Raft 待处理操作

8.3 日志管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 审计日志位置
/var/log/vault/audit.log

# 查看审计日志
tail -f /var/log/vault/audit.log | jq .

# 审计日志格式 (JSON)
{
"time": "2026-03-15T10:00:00Z",
"type": "request",
"auth": {...},
"request": {...},
"response": {...}
}

8.4 密钥轮换

1
2
3
4
5
6
7
8
9
10
11
# 轮换加密密钥 (Transit)
vault write -f transit/keys/webapp-key/rotate

# 轮换数据库凭证 (自动)
# 租期到期后自动轮换

# 手动撤销令牌
vault token revoke <token>

# 撤销所有 AppRole 生成的令牌
vault token revoke -mode=path auth/approle/role/webapp

8.5 健康检查

1
2
3
4
5
6
7
8
9
10
11
12
# 基本健康检查
vault status

# 详细健康检查
vault operator diagnose

# API 健康端点
curl -s https://vault-1.example.com:8200/v1/sys/health

# 负载均衡器健康检查配置
# GET /v1/sys/health
# 200: 正常,429: standby,500: sealed/down

九、安全加固建议

9.1 网络层面

  1. TLS 加密:所有通信强制使用 TLS 1.2+
  2. 防火墙规则:限制 8200/8201 端口访问
  3. 私有网络:集群通信在私有网络进行
  4. 负载均衡:使用反向代理隐藏真实节点

9.2 访问控制

  1. 多因素认证:关键操作要求 MFA
  2. IP 限制:基于 IP 的访问控制
  3. 令牌租期:设置合理的 TTL
  4. 定期轮换:定期轮换根令牌和 Unseal Keys

9.3 操作安全

  1. Unseal Keys 分发:分给不同管理员保管
  2. 审计日志:启用并定期审查
  3. 备份加密:备份文件加密存储
  4. 灾备演练:定期进行恢复演练

十、常见问题排查

10.1 Vault 无法启动

1
2
3
4
5
6
7
8
9
10
# 检查配置
vault server -config=/etc/vault.d/vault.hcl -dev

# 检查日志
journalctl -u vault -f

# 常见错误:
# - 端口被占用
# - TLS 证书无效
# - 存储目录权限错误

10.2 集群节点无法加入

1
2
3
4
5
6
7
8
# 检查网络连通性
telnet vault-1.example.com 8201

# 检查 Raft 状态
vault operator raft list-peers

# 重新加入
vault operator raft join https://vault-1.example.com:8200

10.3 性能问题

1
2
3
4
5
6
7
8
9
10
# 检查 Raft 延迟
vault operator raft list-peers -detailed

# 检查存储性能
iostat -x 1

# 优化建议:
# - 使用 SSD 存储
# - 增加内存
# - 调整 Raft 参数

十一、总结

Vault 是企业密钥管理的核心基础设施,正确部署和运维至关重要。建议:

  1. 生产环境使用 Raft 集群:3 或 5 节点保证高可用
  2. 启用审计日志:满足合规要求
  3. 定期备份:防止数据丢失
  4. 最小权限:严格控制访问范围
  5. 监控告警:及时发现异常

通过合理的架构设计和运维实践,Vault 可以为企业提供一个安全、可靠、可扩展的密钥管理平台。