注意
本章内容为 DeepSeek 对话总结归档而来,文章内容由博主全程测试,此文档原目的是为了记录 HashiCort Vault 可以实现 Mysql 数据库动态凭据管理(PCI规范要求数据库密钥需要动态轮换),仅限参考
📋 项目概述
目标
实现基于HashiCorp Vault的MySQL数据库凭据动态管理,包括动态角色、静态角色自动轮换、监控告警和安全审计。
架构组件
Vault Server : 凭据管理中心
MySQL : 目标数据库
动态角色 : 短期凭据(30分钟TTL)
静态角色 : 长期凭据(24小时自动轮换)
监控体系 : 租约管理、健康检查、告警规则
🔧 阶段1:基础环境配置
1.1 MySQL容器部署
1
2
3
4
5
6
7
8
9
10
# 启动MySQL测试容器
docker run -d \
--name mysql-vault-test \
-e MYSQL_ROOT_PASSWORD = rootpassword123 \
-e MYSQL_DATABASE = vault_test \
-p 3306:3306 \
mysql:8.0
# 验证连接
docker exec -i mysql-vault-test mysql -uroot -prootpassword123 -e "SHOW DATABASES;"
1.2 Vault数据库引擎配置
1
2
3
4
5
6
7
8
9
10
# 启用数据库密钥引擎
/opt/vault/bin/vault secrets enable database
# 配置MySQL连接
/opt/vault/bin/vault write database/config/mysql-vault \
plugin_name = mysql-database-plugin \
connection_url = "{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \
allowed_roles = "vault-dynamic-role" \
username = "root" \
password = "rootpassword123"
🔐 阶段2:动态角色配置
2.1 动态角色定义
1
2
3
4
5
6
/opt/vault/bin/vault write database/roles/vault-dynamic-role \
db_name = mysql-vault \
creation_statements = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT, INSERT, UPDATE, DELETE ON vault_test.* TO '{{name}}'@'%';" \
default_ttl = "30m" \
max_ttl = "2h" \
revocation_statements = "REVOKE ALL PRIVILEGES ON vault_test.* FROM '{{name}}'@'%'; DROP USER '{{name}}'@'%';"
2.2 动态凭据使用
1
2
3
4
5
# 获取动态凭据
/opt/vault/bin/vault read database/creds/vault-dynamic-role
# 验证MySQL权限
mysql -u<动态用户名> -p<动态密码> -e "SHOW GRANTS;"
🔄 阶段3:静态角色自动轮换
3.1 创建静态用户
1
2
# 在MySQL中创建静态用户
docker exec -i mysql-vault-test mysql -uroot -prootpassword123 -e 'CREATE USER "vault_static_user"@"%" IDENTIFIED BY "TempPassword123!"; GRANT SELECT, INSERT ON vault_test.* TO "vault_static_user"@"%";'
3.2 配置静态角色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 更新数据库配置支持静态角色
/opt/vault/bin/vault write database/config/mysql-vault \
plugin_name = mysql-database-plugin \
connection_url = "{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \
allowed_roles = "vault-dynamic-role,app-static-user" \
username = "root" \
password = "rootpassword123"
# 配置静态角色(24小时自动轮换)
/opt/vault/bin/vault write database/static-roles/app-static-user \
db_name = mysql-vault \
username = "vault_static_user" \
rotation_statements = "ALTER USER 'vault_static_user'@'%' IDENTIFIED BY '{{password}}';" \
rotation_period = "86400"
3.3 获取静态凭据
1
2
3
4
5
# 获取当前静态凭据
/opt/vault/bin/vault read database/static-creds/app-static-user
# 查看静态角色状态
/opt/vault/bin/vault read database/static-roles/app-static-user
📊 阶段4:监控审计体系
4.1 审计日志配置
1
2
3
4
5
6
7
8
9
# 创建审计日志目录
sudo mkdir -p /opt/vault/audit
sudo chown cxd: /opt/vault/audit
# 启用文件审计
/opt/vault/bin/vault audit enable file file_path = /opt/vault/audit/vault-audit.log
# 验证审计配置
/opt/vault/bin/vault audit list
4.2 监控策略配置
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
# 创建数据库监控策略
/opt/vault/bin/vault policy write db-monitor - << EOF
path "database/creds/vault-dynamic-role" {
capabilities = ["read"]
}
path "database/creds/dev-readonly" {
capabilities = ["read"]
}
path "database/creds/app-rw" {
capabilities = ["read"]
}
path "database/roles/*" {
capabilities = ["read"]
}
path "database/static-creds/app-static-user" {
capabilities = ["read"]
}
path "sys/leases/renew" {
capabilities = ["update"]
}
path "sys/leases/lookup" {
capabilities = ["update"]
}
EOF
# 创建监控令牌
/opt/vault/bin/vault token create -policy= db-monitor -display-name= "db-monitor-token" -ttl= 24h
4.3 监控脚本
租约管理脚本 (/opt/vault/bin/lease-manager.sh)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
export VAULT_ADDR = 'http://127.0.0.1:8200'
echo "=== Vault租约管理 ==="
# 列出所有动态凭据租约
echo "1. 活跃的动态凭据租约:"
/opt/vault/bin/vault list sys/leases/lookup/database/creds/vault-dynamic-role 2>/dev/null
# 查看租约详情(如果有租约)
LEASE_IDS = $( /opt/vault/bin/vault list sys/leases/lookup/database/creds/vault-dynamic-role 2>/dev/null | tail -n +3)
if [ ! -z " $LEASE_IDS " ] ; then
echo -e "\n2. 租约详情:"
for lease in $LEASE_IDS ; do
echo "租约: $lease "
/opt/vault/bin/vault lease lookup database/creds/vault-dynamic-role/$lease 2>/dev/null | grep -E "(lease_duration|expire_time)"
done
fi
# 检查MySQL中的动态用户
echo -e "\n3. MySQL中的动态用户:"
docker exec mysql-vault-test mysql -uroot -prootpassword123 -e "SELECT user, host FROM mysql.user WHERE user LIKE 'v-%';" 2>/dev/null
echo -e "\n4. 静态角色状态:"
/opt/vault/bin/vault read database/static-creds/app-static-user 2>/dev/null | grep -E "(username|last_vault_rotation|rotation_period)"
echo -e "\n=== 管理完成 ==="
轮换监控脚本 (/opt/vault/bin/rotation-monitor.sh)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
export VAULT_ADDR = 'http://127.0.0.1:8200'
echo "=== 凭据轮换监控 ==="
date
# 检查静态角色轮换状态
echo -e "\n1. 静态角色轮换状态:"
STATIC_INFO = $( /opt/vault/bin/vault read database/static-creds/app-static-user 2>/dev/null)
echo " $STATIC_INFO " | grep -E "(last_vault_rotation|next_vault_rotation|rotation_period)"
# 检查动态角色配置
echo -e "\n2. 动态角色TTL配置:"
/opt/vault/bin/vault read database/roles/vault-dynamic-role 2>/dev/null | grep -E "(default_ttl|max_ttl)"
# 检查活跃租约数量
echo -e "\n3. 活跃租约统计:"
LEASE_COUNT = $( /opt/vault/bin/vault list sys/leases/lookup/database/creds/vault-dynamic-role 2>/dev/null | tail -n +3 | wc -l)
echo "活跃动态凭据租约: $LEASE_COUNT "
# 检查MySQL用户数量
echo -e "\n4. MySQL用户统计:"
docker exec mysql-vault-test mysql -uroot -prootpassword123 -e "SELECT COUNT(*) as '动态用户数' FROM mysql.user WHERE user LIKE 'v-%';" 2>/dev/null
echo -e "\n=== 监控完成 ==="
🚨 阶段5:高级监控告警
5.1 Prometheus指标配置
1
2
3
4
# 启用Vault Prometheus指标
/opt/vault/bin/vault write sys/metrics/config \
usage_gauge_period = "30s" \
maximum_gauge_cardinality = 500
5.2 健康检查脚本 (/opt/vault/bin/vault-health-check.sh)
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
#!/bin/bash
export VAULT_ADDR = 'http://127.0.0.1:8200'
echo "=== Vault健康检查 ==="
date
# 检查Vault状态
echo -e "\n1. Vault服务状态:"
/opt/vault/bin/vault status 2>/dev/null
# 检查密封状态
echo -e "\n2. 密封状态:"
/opt/vault/bin/vault status 2>/dev/null | grep -E "(Sealed|Initialized)"
# 检查数据库引擎状态
echo -e "\n3. 数据库引擎状态:"
/opt/vault/bin/vault secrets list -detailed | grep database
# 检查租约状态
echo -e "\n4. 租约状态:"
ACTIVE_LEASES = $( /opt/vault/bin/vault list sys/leases/lookup/database/creds/vault-dynamic-role 2>/dev/null | tail -n +3 | wc -l)
echo "活跃动态租约: $ACTIVE_LEASES "
# 检查静态角色状态
echo -e "\n5. 静态角色状态:"
STATIC_TTL = $( /opt/vault/bin/vault read database/static-creds/app-static-user 2>/dev/null | grep ttl | awk '{print $2}' )
echo "静态角色TTL: $STATIC_TTL "
# 检查审计日志
echo -e "\n6. 审计日志状态:"
AUDIT_LOG_SIZE = $( sudo ls -lh /opt/vault/audit/vault-audit.log 2>/dev/null | awk '{print $5}' || echo "N/A" )
echo "审计日志大小: $AUDIT_LOG_SIZE "
echo -e "\n=== 健康检查完成 ==="
# 退出码判断
if /opt/vault/bin/vault status 2>/dev/null | grep -q "Sealed.*false" ; then
echo "✅ Vault健康状态: 正常"
exit 0
else
echo "❌ Vault健康状态: 异常"
exit 1
fi
5.3 告警规则 (/opt/vault/bin/vault-alert-rules.yml)
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
groups :
- name : vault_alerts
rules :
- alert : VaultSealed
expr : vault_core_sealed == 1
for : 1m
labels :
severity : critical
annotations :
summary : "Vault实例已密封"
description : "Vault实例 {{ $labels.instance }} 处于密封状态,需要解封"
- alert : HighLeaseUsage
expr : count(vault_expire_num_leases) > 50
for : 5m
labels :
severity : warning
annotations :
summary : "租约使用率过高"
description : "Vault实例 {{ $labels.instance }} 活跃租约数量超过50个"
- alert : StaticCredentialExpiring
expr : vault_database_static_role_rotation_scheduled{role="app-static-user"} < 3600
for : 2m
labels :
severity : warning
annotations :
summary : "静态凭据即将轮换"
description : "静态角色 {{ $labels.role }} 将在1小时内自动轮换"
- alert : DatabaseConnectionFailure
expr : increase(vault_database_connection_errors_total[5m]) > 3
for : 2m
labels :
severity : critical
annotations :
summary : "数据库连接频繁失败"
description : "Vault到数据库的连接在5分钟内失败超过3次"
5.4 自动清理脚本 (/opt/vault/bin/vault-cleanup.sh)
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
#!/bin/bash
export VAULT_ADDR = 'http://127.0.0.1:8200'
echo "=== Vault清理维护 ==="
date
# 清理过期的租约
echo -e "\n1. 清理过期租约:"
EXPIRED_LEASES = $( /opt/vault/bin/vault list sys/leases/lookup/database/creds/vault-dynamic-role 2>/dev/null | tail -n +3)
if [ ! -z " $EXPIRED_LEASES " ] ; then
for lease in $EXPIRED_LEASES ; do
LEASE_INFO = $( /opt/vault/bin/vault lease lookup database/creds/vault-dynamic-role/$lease 2>/dev/null)
if echo " $LEASE_INFO " | grep -q "lease expired" ; then
echo "清理过期租约: $lease "
/opt/vault/bin/vault lease revoke database/creds/vault-dynamic-role/$lease 2>/dev/null
fi
done
fi
# 清理MySQL中的孤立用户
echo -e "\n2. 清理MySQL孤立用户:"
docker exec mysql-vault-test mysql -uroot -prootpassword123 -e "
SELECT CONCAT('DROP USER \\'', user, '\\'@\\'', host, '\\';')
FROM mysql.user
WHERE user LIKE 'v-%'
AND user NOT IN (
SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(json_extract(creation_statement, ' $[0]'), '''', 2), '''', -1)
FROM vault_token.vault_dynamic_users
);" 2>/dev/null
# 轮转审计日志(如果超过100MB)
echo -e "\n3. 审计日志维护:"
AUDIT_LOG_SIZE = $( sudo ls -l /opt/vault/audit/vault-audit.log 2>/dev/null | awk '{print $5}' )
if [ " $AUDIT_LOG_SIZE " -gt 104857600 ] ; then # 100MB
echo "审计日志超过100MB,执行轮转"
sudo mv /opt/vault/audit/vault-audit.log /opt/vault/audit/vault-audit.log.$( date +%Y%m%d_%H%M%S)
sudo systemctl reload vault # 重新加载以创建新日志文件
fi
echo -e "\n=== 清理完成 ==="
📈 运维最佳实践
日常运维命令
1
2
3
4
5
6
7
8
9
10
# 查看所有配置状态
/opt/vault/bin/lease-manager.sh
/opt/vault/bin/rotation-monitor.sh
/opt/vault/bin/vault-health-check.sh
# 手动轮换静态凭据
/opt/vault/bin/vault write -force database/rotate-role/app-static-user
# 查看审计日志
sudo tail -f /opt/vault/audit/vault-audit.log | jq .
定时任务配置
1
2
3
4
5
6
7
8
9
# 添加到crontab
# 每5分钟健康检查
*/5 * * * * /opt/vault/bin/vault-health-check.sh >> /var/log/vault-health.log 2>& 1
# 每小时租约监控
0 * * * * /opt/vault/bin/lease-manager.sh >> /var/log/vault-lease.log 2>& 1
# 每天凌晨清理维护
0 2 * * * /opt/vault/bin/vault-cleanup.sh >> /var/log/vault-cleanup.log 2>& 1
故障排查指南
Vault密封状态 : 使用解封密钥解封
数据库连接失败 : 检查MySQL服务状态和网络连通性
凭据生成失败 : 检查数据库用户权限和Vault角色配置
租约过期 : 检查TTL配置和租约续期逻辑
🔒 安全注意事项
最小权限原则 : 所有角色按需分配最小必要权限
凭据生命周期 : 动态凭据30分钟TTL,静态凭据24小时自动轮换
审计追踪 : 所有操作记录到审计日志
监控告警 : 实时监控关键指标并设置告警
定期维护 : 定期清理过期租约和孤立用户
📚 总结
本方案实现了完整的数据库凭据动态管理:
✅ 动态凭据 : 短期访问,自动回收
✅ 静态凭据 : 长期使用,自动轮换
✅ 安全审计 : 完整操作记录
✅ 监控告警 : 实时状态监控
✅ 自动化运维 : 脚本化日常维护
通过这套体系,可以有效提升数据库访问安全性,降低凭据泄露风险,实现合规性要求。
📝 参考资料
Vault官方文档
HashiCorp Vault 实施对话记录