← 返回首页
🔧

HashiCorp Vault:密钥管理平台

📂 devops ⏱ 3 min 488 words

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']

最佳实践

  1. 使用生产存储后端: 使用Consul等生产级存储
  2. 启用TLS: 所有通信使用TLS加密
  3. 最小权限: 应用最小权限原则
  4. 定期轮换: 定期轮换密钥和令牌
  5. 审计日志: 启用并监控审计日志
  6. 高可用: 部署Vault集群实现高可用