HashiCorp Vault:密钥管理平台
HashiCorp Vault:密钥管理平台
什么是Vault
HashiCorp Vault是一个用于安全访问秘密的工具。它提供了一个统一的接口来管理任何秘密,包括KV secrets、密码、证书、API密钥等。
Vault架构
Vault架构组件:
├── Auth Methods: 认证方法
├── Secrets Engines: 密钥引擎
├── Policies: 访问策略
├── Tokens: 访问令牌
└── Audit Backend: 审计后端
安装和启动
开发模式
# 开发模式启动(不推荐生产环境)
vault server -dev
# 使用配置文件启动
vault server -config=/etc/vault/config.hcl
生产配置
# /etc/vault/config.hcl
storage "consul" {
address = "consul:8500"
path = "vault/"
tls_ca_file = "/etc/vault/tls/ca.crt"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault/tls/server.crt"
tls_key_file = "/etc/vault/tls/server.key"
}
api_addr = "https://vault.example.com:8200"
cluster_addr = "https://vault.example.com:8201"
密钥引擎
KV密钥引擎
# 启用KV密钥引擎
vault secrets enable -path=secret kv-v2
# 存储密钥
vault kv put secret/myapp/config \
username=admin \
password=secretpass
# 读取密钥
vault kv get secret/myapp/config
# 获取特定字段
vault kv get -field=username secret/myapp/config
# 列出密钥
vault kv list secret/
# 删除密钥
vault kv delete secret/myapp/config
数据库密钥引擎
# 启用数据库引擎
vault secrets enable database
# 配置PostgreSQL连接
vault write database/config/postgresql \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@db:5432/mydb" \
allowed_roles="readonly" \
username="vault" \
password="vault-pass"
# 创建角色
vault write database/roles/readonly \
db_name=postgresql \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
# 获取数据库凭据
vault read database/creds/readonly
PKI密钥引擎
# 启用PKI引擎
vault secrets enable pki
# 配置最大TTL
vault secrets tune -max-lease-ttl=87600h pki
# 生成根证书
vault write pki/root/generate/internal \
common_name="Example CA" \
ttl=87600h
# 配置URLs
vault write pki/config/urls \
issuing_certificates="https://vault:8200/v1/pki/ca" \
crl_distribution_points="https://vault:8200/v1/pki/crl"
# 创建角色
vault write pki/roles/web-server \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl=720h
# 生成证书
vault write pki/issue/web-server \
common_name="web.example.com" \
ttl=72h
认证方法
Kubernetes认证
# 启用Kubernetes认证
vault auth enable kubernetes
# 配置Kubernetes认证
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc" \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
token_reviewer_jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token
# 创建角色
vault write auth/kubernetes/role/app-role \
bound_service_account_names=app-sa \
bound_service_account_namespaces=production \
policies=app-policy \
ttl=1h
AppRole认证
# 启用AppRole认证
vault auth enable approle
# 创建AppRole
vault write auth/approle/role/app-role \
secret_id_ttl=10m \
token_num_uses=10 \
token_ttl=20m \
token_max_ttl=30m \
secret_id_num_uses=40 \
policies=app-policy
# 获取Role ID
vault read auth/approle/role/app-role/role-id
# 生成Secret ID
vault write -f auth/approle/role/app-role/secret-id
# 登录
vault write auth/approle/login \
role_id=<role_id> \
secret_id=<secret_id>
访问策略
策略配置
# app-policy.hcl
path "secret/data/myapp/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "database/creds/readonly" {
capabilities = ["read"]
}
path "pki/issue/web-server" {
capabilities = ["create", "update"]
}
# 禁止访问其他路径
path "secret/data/admin/*" {
capabilities = ["deny"]
}
应用策略
# 写入策略
vault policy write app-policy app-policy.hcl
# 查看策略
vault policy read app-policy
# 删除策略
vault policy delete app-policy
Kubernetes集成
Vault Agent注入
# vault-agent-injector.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
namespace: production
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "app-role"
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
vault.hashicorp.com/agent-inject-template-config: |
{{- with secret "secret/data/myapp/config" -}}
export DB_USERNAME="{{ .Data.data.username }}"
export DB_PASSWORD="{{ .Data.data.password }}"
{{- end }}
spec:
serviceAccountName: app-sa
containers:
- name: app
image: myapp:latest
command: ["sh", "-c", "source /vault/secrets/config && ./start.sh"]
CSI Provider
# vault-csi-provider.yaml
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
serviceAccountName: app-sa
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: vault-secrets
mountPath: /vault/secrets
readOnly: true
volumes:
- name: vault-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: vault-backend
监控和审计
启用审计日志
# 启用文件审计后端
vault audit enable file file_path=/var/log/vault-audit.log
# 启用Syslog审计后端
vault audit enable syslog tag=vault facility=auth
# 查看审计日志
vault audit list
Prometheus监控
# 启用Prometheus指标
vault metric address=0.0.0.0:9102
# Prometheus配置
scrape_configs:
- job_name: 'vault'
static_configs:
- targets: ['vault:9102']
最佳实践
- 使用生产存储后端: 使用Consul等生产级存储
- 启用TLS: 所有通信使用TLS加密
- 最小权限: 应用最小权限原则
- 定期轮换: 定期轮换密钥和令牌
- 审计日志: 启用并监控审计日志
- 高可用: 部署Vault集群实现高可用