第二十七章:密钥与凭证管理
“密钥管理是安全的最后一公里 — 再好的加密算法,密钥泄露了也白搭。”
mindmap
root((密钥管理))
HashiCorp Vault
Secret Engines
Auth Methods
动态密钥
PKI
云密钥服务
AWS KMS
Azure Key Vault
GCP Secret Manager
K8s Secrets
External Secrets
Sealed Secrets
CSI Driver
密钥轮换
零停机
自动化
泄露检测
TruffleHog
GitLeaks
27.1 密钥管理挑战
常见的密钥管理反模式:
❌ 硬编码在代码中:password = "admin123"
❌ 存储在环境变量:容器重启后可能丢失
❌ 提交到 Git:即使删除,历史中仍然存在
❌ 共享密钥:多个服务使用同一个密钥
❌ 永不轮换:密钥一用就是几年
❌ 明文传输:通过 Slack/邮件分享密钥
27.2 HashiCorp Vault
Vault 是最流行的密钥管理工具:
Vault 架构:
┌─────────────────────────────────────────┐
│ Vault Server │
│ ┌──────────┐ ┌──────────┐ │
│ │ Secret │ │ Auth │ │
│ │ Engines │ │ Methods │ │
│ │ │ │ │ │
│ │ • KV │ │ • Token │ │
│ │ • PKI │ │ • AppRole│ │
│ │ • Transit│ │ • K8s │ │
│ │ • Database│ │ • AWS │ │
│ │ • SSH │ │ • OIDC │ │
│ └──────────┘ └──────────┘ │
│ ┌──────────────────────────────────┐ │
│ │ Storage Backend │ │
│ │ Consul / Raft / PostgreSQL │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
Secret Engines
Engine |
用途 |
特点 |
|---|---|---|
KV |
键值存储 |
版本化、审计 |
PKI |
证书管理 |
动态签发 X.509 证书 |
Transit |
加密即服务 |
不暴露密钥,只提供加解密 API |
Database |
数据库凭证 |
动态生成、自动过期 |
SSH |
SSH 证书 |
签发短期 SSH 证书 |
AWS/GCP/Azure |
云凭证 |
动态生成云平台凭证 |
AppRole 认证
import hvac
# 使用 AppRole 认证
client = hvac.Client(url='https://vault.example.com:8200')
client.auth.approle.login(
role_id='your-role-id',
secret_id='your-secret-id',
)
# 读取密钥
secret = client.secrets.kv.v2.read_secret_version(
path='myapp/database',
mount_point='secret',
)
db_password = secret['data']['data']['password']
# 动态数据库凭证
creds = client.secrets.database.generate_credentials(
name='my-role',
mount_point='database',
)
print(f"Username: {creds['data']['username']}")
print(f"Password: {creds['data']['password']}")
print(f"TTL: {creds['lease_duration']}s") # 自动过期!
# PKI — 签发证书
cert = client.secrets.pki.generate_certificate(
name='web-server',
common_name='api.example.com',
mount_point='pki',
)
print(f"Certificate: {cert['data']['certificate']}")
print(f"Private Key: {cert['data']['private_key']}")
Vault + SPIRE 集成
# SPIRE Server 使用 Vault 作为上游 CA
UpstreamAuthority "vault" {
plugin_data {
vault_addr = "https://vault.example.com:8200"
pki_mount_point = "pki"
approle_auth_mount_point = "auth/approle"
approle_id = "spire-role-id"
approle_secret_id = "spire-secret-id"
}
}
27.3 Kubernetes Secrets 安全
External Secrets Operator
# 从 Vault 同步密钥到 K8s Secret
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: db-credentials
data:
- secretKey: username
remoteRef:
key: secret/data/myapp/database
property: username
- secretKey: password
remoteRef:
key: secret/data/myapp/database
property: password
27.4 密钥轮换
零停机轮换策略
双密钥轮换(Blue-Green):
┌─────────────────────────────────────────┐
│ 阶段 1:添加新密钥 │
│ 活跃密钥:[Key-A] │
│ 新密钥: [Key-B](开始接受) │
├─────────────────────────────────────────┤
│ 阶段 2:切换主密钥 │
│ 活跃密钥:[Key-B](用于签名/加密) │
│ 旧密钥: [Key-A](仍然接受验证) │
├─────────────────────────────────────────┤
│ 阶段 3:移除旧密钥 │
│ 活跃密钥:[Key-B] │
│ 旧密钥: [Key-A](已移除) │
└─────────────────────────────────────────┘
27.5 密钥泄露检测
# TruffleHog — 扫描 Git 历史中的密钥
trufflehog git https://github.com/org/repo --only-verified
# GitLeaks — 快速扫描
gitleaks detect --source . --verbose
# Pre-commit Hook 防止提交密钥
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
27.6 小结
HashiCorp Vault 是最全面的密钥管理工具,支持动态密钥、PKI、加密即服务
动态密钥(数据库凭证、云凭证)自动过期,大幅降低泄露风险
External Secrets Operator 将 Vault 密钥安全同步到 Kubernetes
密钥轮换 应该自动化,使用双密钥策略实现零停机
Pre-commit Hook + CI 扫描 防止密钥泄露到代码仓库