19.8.5 密钥、证书与敏感信息管理
本节聚焦密钥、证书与敏感信息的全生命周期管理,目标是确保机密信息“可用可控、最小暴露、可审可追”。在平台化场景中,需统一密钥与证书的存储、分发、轮换、吊销与审计机制,避免硬编码、明文落盘与无序复制带来的扩散风险。
原理草图(密钥/证书托管与分发)
关键策略与落地规范#
- 统一密钥托管(Vault/云KMS),分级分权访问;
- 按环境/租户隔离,生产与测试密钥严禁复用;
- 强制轮换与吊销流程,证书有效期与续期策略明确;
- 启用加密传输与静态加密,统一审计与告警;
- 关键服务启用双向TLS,支持证书吊销检查(CRL/OCSP)。
安装与初始化示例(HashiCorp Vault)#
环境:Linux单机测试,便于理解流程
1)安装 Vault(二进制方式)
# 1. 下载
wget https://releases.hashicorp.com/vault/1.13.3/vault_1.13.3_linux_amd64.zip
unzip vault_1.13.3_linux_amd64.zip
sudo mv vault /usr/local/bin/
# 2. 验证
vault version
2)配置与启动(开发模式示例)
# 开发模式仅用于测试,生产需使用TLS与持久化存储
export VAULT_ADDR='http://127.0.0.1:8200'
vault server -dev -dev-root-token-id=root
预期效果:服务监听 127.0.0.1:8200,root token 为 root。
密钥存储与获取示例(KV 引擎)#
# 1. 登录
vault login root
# 2. 启用 KV v2
vault secrets enable -path=secret kv-v2
# 3. 写入密钥
vault kv put secret/app/db username=appuser password='S3cure!Pass'
# 4. 读取密钥
vault kv get secret/app/db
命令解释
- secrets enable:启用存储引擎;
- kv put/get:写入/读取密钥;
- -path=secret:路径前缀,避免默认冲突。
动态凭证示例(MySQL)#
1)启用数据库引擎与配置连接
vault secrets enable database
vault write database/config/app-mysql \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \
allowed_roles="app-role" \
username="root" \
password="RootPass!"
2)配置动态角色
vault write database/roles/app-role \
db_name=app-mysql \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON appdb.* TO '{{name}}'@'%';" \
default_ttl="1h" \
max_ttl="24h"
3)申请动态凭证
vault read database/creds/app-role
预期效果:返回一次性用户与密码,有效期 1h。
证书管理示例(自建 CA + 业务证书)#
1)启用 PKI 引擎与根 CA
vault secrets enable pki
vault secrets tune -max-lease-ttl=8760h pki
vault write pki/root/generate/internal \
common_name="ops-root-ca.local" \
ttl=8760h
2)配置签发与角色
vault write pki/roles/app-server \
allowed_domains="app.local" \
allow_subdomains=true \
max_ttl="720h"
3)签发证书
vault write pki/issue/app-server \
common_name="api.app.local" \
ttl="168h"
预期效果:输出 certificate、private_key、issuing_ca,可用于 Nginx/服务端 TLS 配置。
使用示例:Nginx 双向 TLS(mTLS)#
文件结构
/etc/nginx/ssl/
server.crt
server.key
ca.crt
Nginx 配置
server {
listen 443 ssl;
server_name api.app.local;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# 验证客户端证书
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_verify_client on;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
验证命令
# 客户端携带证书访问
curl -k --cert client.crt --key client.key https://api.app.local
敏感信息分级与脱敏展示示例(配置管理规范)#
# /opt/app/config/secret.yaml
classification: core
data:
db_password: "****" # 展示脱敏
api_token: "****"
# 原始值由 Vault 动态注入或启动时拉取
建议:配置仓库仅保存脱敏占位符,应用启动时拉取真实值。
排错与诊断#
1)Vault 无法启动
- 检查端口占用:
ss -lntp | grep 8200
- 检查配置与日志:
journalctl -u vault -n 50
2)动态凭证获取失败
- 验证数据库连接:
mysql -h127.0.0.1 -uroot -p'RootPass!' -e "select 1;"
- 检查 Vault 配置:
vault read database/config/app-mysql
3)TLS 握手失败
- 验证证书链:
openssl verify -CAfile ca.crt server.crt
- 查看 Nginx 错误日志:
tail -f /var/log/nginx/error.log
运维实践清单#
- 禁止在代码/镜像/配置仓库存明文密钥;
- 通过动态凭证替代长期密钥;
- 密钥拉取必须走统一出口并审计;
- 轮换与吊销与变更流程绑定,支持回滚;
- 定期密钥健康检查与泄露应急预案。
练习与实践#
1)使用 Vault 存储 app/db 密钥并写一个脚本拉取注入环境变量。
2)签发一张 *.app.local 证书,配置 Nginx 启用双向 TLS 并完成访问验证。
3)模拟“证书过期”场景:将证书 TTL 改为 1h,观察续期与服务影响。
4)在 CI/CD 流水线中使用短期 Token 拉取密钥并部署应用,记录审计日志。