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
|
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
|
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_id、api_addr、cluster_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
| [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
| 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
| 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
| vault operator raft join https://vault-1.example.com:8200
|
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
| 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
vault read auth/approle/role/webapp/role-id
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
| vault auth enable kubernetes
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
| vault auth enable 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
| 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
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
| 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
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
| 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 策略最佳实践
- 最小权限原则:只授予必要的权限
- 路径隔离:不同应用使用不同的路径前缀
- 定期审计:审查策略使用情况
- 版本管理:策略变更纳入版本控制
八、运维管理
8.1 备份与恢复
1 2 3 4 5 6 7 8
| 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
|
telemetry { prometheus_retention_time = "30s" disable_hostname = true }
|
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 .
{ "time": "2026-03-15T10:00:00Z", "type": "request", "auth": {...}, "request": {...}, "response": {...} }
|
8.4 密钥轮换
1 2 3 4 5 6 7 8 9 10 11
| vault write -f transit/keys/webapp-key/rotate
vault token revoke <token>
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
curl -s https://vault-1.example.com:8200/v1/sys/health
|
九、安全加固建议
9.1 网络层面
- TLS 加密:所有通信强制使用 TLS 1.2+
- 防火墙规则:限制 8200/8201 端口访问
- 私有网络:集群通信在私有网络进行
- 负载均衡:使用反向代理隐藏真实节点
9.2 访问控制
- 多因素认证:关键操作要求 MFA
- IP 限制:基于 IP 的访问控制
- 令牌租期:设置合理的 TTL
- 定期轮换:定期轮换根令牌和 Unseal Keys
9.3 操作安全
- Unseal Keys 分发:分给不同管理员保管
- 审计日志:启用并定期审查
- 备份加密:备份文件加密存储
- 灾备演练:定期进行恢复演练
十、常见问题排查
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
|
10.2 集群节点无法加入
1 2 3 4 5 6 7 8
| telnet vault-1.example.com 8201
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
| vault operator raft list-peers -detailed
iostat -x 1
|
十一、总结
Vault 是企业密钥管理的核心基础设施,正确部署和运维至关重要。建议:
- 生产环境使用 Raft 集群:3 或 5 节点保证高可用
- 启用审计日志:满足合规要求
- 定期备份:防止数据丢失
- 最小权限:严格控制访问范围
- 监控告警:及时发现异常
通过合理的架构设计和运维实践,Vault 可以为企业提供一个安全、可靠、可扩展的密钥管理平台。