VSO 클라이언트 캐시 저장·암호화

VSO 클라이언트 캐시 저장·암호화 (Vault client cache persistence and encryption)

Vault 시크릿 엔진으로 VSO 클라이언트 캐시를 저장하고 암호화하는 방법을 다룹니다.

출처: 문서

본문

기본적으로 Vault 클라이언트 캐시영속화되지 않아요. Vault Secrets Operator(VSO)와 함께 transit 시크릿 엔진을 사용해 클라이언트 캐시를 Vault 서버에 저장하고 암호화할 수 있습니다.

동적 시크릿 모범 사례: Vault 동적 시크릿을 사용한다면 클라이언트 캐시를 영속화·암호화할 것을 강력히 권장해요. 그래야 동적 시크릿 리스가 재시작·업그레이드를 거쳐도 유지됩니다.

시작하기 전에

1단계: VSO용 키와 정책 구성

Vault CLI나 Terraform을 사용해 transit에 키를 추가하고 캐시 정보를 암호화·복호화하는 정책을 정의해요.

Shell:

export VAULT_NAMESPACE=<NAMESPACE>
export VAULT_TRANSIT_PATH=<TRANSIT_PATH>

vault write -f ${VAULT_TRANSIT_PATH}/keys/vso-client-cache

vault policy write operator - <<EOF
path "${VAULT_TRANSIT_PATH}/encrypt/vso-client-cache" {
  capabilities = ["create", "update"]
}

path "${VAULT_TRANSIT_PATH}/decrypt/vso-client-cache" {
  capabilities = ["create", "update"]
}
EOF

Terraform:

locals {
  transit_path      = "<TRANSIT_PATH>"
  transit_namespace = "<NAMESPACE>"
}

resource "vault_transit_secret_cache_config" "cache" {
  namespace = local.transit_namespace
  backend   = local.transit_path
  size      = 500
}

resource "vault_transit_secret_backend_key" "cache" {
  namespace        = local.transit_namespace
  backend          = local.transit_path
  name             = "vso-client-cache"
  deletion_allowed = true
}

data "vault_policy_document" "operator_transit" {
  rule {
    path         = "${local.transit_path}/encrypt/${vault_transit_secret_backend_key.cache.name}"
    capabilities = ["create", "update"]
    description  = "encrypt"
  }
  rule {
    path         = "${local.transit_path}/decrypt/${vault_transit_secret_backend_key.cache.name}"
    capabilities = ["create", "update"]
    description  = "decrypt"
  }
}

resource "vault_policy" "operator" {
  namespace = vault_transit_secret_backend_key.cache.namespace
  name      = "operator"
  policy    = data.vault_policy_document.operator_transit.hcl
}

2단계: 쿠버네티스 인증 역할 만들기

Vault CLI나 Terraform을 사용해 Vault Secrets Operator용 쿠버네티스 인증 역할을 만들어요.

Shell:

export VAULT_NAMESPACE=<NAMESPACE>

vault write auth/<AUTH_MOUNT>/role/operator \
  bound_service_account_names=vault-secrets-operator-controller-manager \
  bound_service_account_namespaces=vault-secrets-operator \
  token_period="24h" \
  token_policies=operator \
  audience="vault"

Terraform:

data "vault_auth_backend" "kubernetes" {
  namespace = "<NAMESPACE>"
  path      = "<AUTH_MOUNT>"
}

resource "vault_kubernetes_auth_backend_config" "local" {
  namespace       = data.vault_auth_backend.kubernetes.namespace
  backend         = data.vault_auth_backend.kubernetes.path
  kubernetes_host = "https://kubernetes.default.svc"
}

resource "vault_kubernetes_auth_backend_role" "operator" {
  namespace                        = data.vault_auth_backend.kubernetes.namespace
  backend                          = vault_kubernetes_auth_backend_config.local.backend
  role_name                        = "operator"
  bound_service_account_names      = ["vault-secrets-operator-controller-manager"]
  bound_service_account_namespaces = ["vault-secrets-operator"]
  token_period                     = 120
  token_policies = [
    vault_policy.operator.name,
  ]
  audience = "vault"
}

3단계: VSO용 Vault 연결 구성

Vault Secrets Operator API를 사용해 VSO와 Vault 서버 사이에 VaultConnection을 추가해요.

참고: VSO용 연결이 이미 있다면 다음 단계로 넘어가세요.

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultConnection
metadata:
  name: local-vault-server
  namespace: vault-secrets-operator
spec:
  address: 'https://vault.vault.svc.cluster.local:8200'

4단계: 암호화된 클라이언트 캐시 저장 활성화

HelmHelm 설치의 경우 server.clientCache 구성을 설치(또는 업그레이드)해요.

controller:
  manager:
    clientCache:
      persistenceModel: direct-encrypted
      storageEncryption:
        enabled: true
        vaultConnectionRef: local-vault-server
        keyName: vso-client-cache
        transitMount: <TRANSIT_MOUNT>
        namespace: <NAMESPACE>
        method: kubernetes
        mount: <AUTH_MOUNT>
        kubernetes:
          role: operator
          serviceAccount: vault-secrets-operator-controller-manager
          tokenAudiences: ["vault"]

OLM/OperatorHubOpenShift OperatorHub 설치의 경우:

  1. 저장용 VaultAuth 항목을 클러스터에 추가해요.

apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
  name: operator
  namespace: vault-secrets-operator
  labels:
    cacheStorageEncryption: 'true'
spec:
  kubernetes:
    role: operator
    serviceAccount: vault-secrets-operator-controller-manager
    tokenExpirationSeconds: 600
    audiences: ["vault"]
  method: kubernetes
  mount: <AUTH_MOUNT>
  namespace: <NAMESPACE>
  storageEncryption:
    keyName: vso-client-cache
    mount: <TRANSIT_MOUNT>
  vaultConnectionRef: local-vault-server
  1. VSO의 구독(subscription)에서 VSO_CLIENT_CACHE_PERSISTENCE_MODEL 환경 변수를 설정해요.
spec:
  name: vault-secrets-operator
  channel: stable
  config:
    env:
      - name: VSO_CLIENT_CACHE_PERSISTENCE_MODEL
        value: direct-encrypted

OperatorHub로 오퍼레이터를 설치했다면 구독을 편집하고 VSO_CLIENT_CACHE_PERSISTENCE_MODEL 환경 변수를 설정해요.

Web Console — Operators 메뉴 → Installed Operators → "Vault Secrets Operator" 선택 → 오른쪽 위 작업 메뉴에서 "Edit Subscription" 클릭.

CLI:

oc edit subscription      \
  vault-secrets-operator  \
  -n vault-secrets-operator

VSO_CLIENT_CACHE_PERSISTENCE_MODEL 환경 변수가 유지되면 오퍼레이터 배포의 파드가 재시작됩니다.

선택: 클라이언트 캐시 저장·암호화 확인

  1. Vault Secrets Operator가 시작 시 다음 정보를 로그하는지 확인해요.
Starting manager    {"clientCachePersistenceModel": "direct-encrypted",
    "clientCacheSize": 10000}
  1. Vault Secrets Operator가 사용자를 대신해 Vault에 인증할 때 "Setting up Vault Client for storage encryption" 메시지를 로그하는지 확인해요.
{"level":"info","ts":"2024-02-22T00:41:46Z","logger":"clientCacheFactory",
"msg":"Setting up Vault Client for storage encryption","persist":true,
"enforceEncryption":true,"cacheKey":"kubernetes-59ebf88ccb963a22226bad"}
  1. 암호화된 캐시가 올바른 네임스페이스 아래 vso-cc-<auth method> 접두사를 가진 쿠버네티스 시크릿으로 저장되는지 확인해요. 예:
$ kubectl get secrets -n vault-secrets-operator
...
NAME                                       TYPE     DATA   AGE
vso-cc-kubernetes-0147431c618992b6adfed1   Opaque   2      73s
...

더 알아보기 (Learn more)