본문 바로가기
Security/Vault

Vault Secrets Operator(VSO)를 활용한 Kubernetes secrets 관리 (PKI 동적 시크릿)

by wlsdn3004 2024. 2. 28.
728x90
반응형

 

Vault Secrets Operator에 대한 내용은 이전 글에서 다루었다.

 

Vault Secrets Operator(VSO)를 활용한 Kubernetes secrets 관리(정적 시크릿)

Vault Secrets Operator(VSO)란? Vault Secrets Operator(이하 "VSO"라 한다)를 사용하면 Pod가 기본적으로 Kubernetes Secrets의 Vault Secrets을 사용할 수 있다. Vault Secrets Operator는 지원되는 CRD(Custom Resource Definitions)의

wlsdn3004.tistory.com

 

이번 글에서는 Vault에 저장된 PKI 동적 시크릿을 Kubernetes Secret으로 생성하여 동기화하는 실습을 진행한다.

Information Panel

참고

본 실습을 위해서는 이전 실습에서 구성한 환경이 필요하다.

 

 

1. Vault Secrets Operator PKI 시크릿 정의


PKI 시크릿을 사용하기 위해 Vault 서버에서 pki 시크릿 엔진을 활성화한다.

# Vault Pod 접근
$ kubectl exec -it -n vault vault-0 -- /bin/sh

# Vault root token으로 로그인
$ vault login {vault_root_token}

# pki 시크릿 엔진 활성화
$ vault secrets enable -path=pki pki

 

시크릿 엔진에 대한 구성 옵션을 설정한다.

  • 최대 TTL은 24시간, 기본 TTL은 1시간으로 설정했다.
$ vault secrets tune -max-lease-ttl=86400s -default-lease-ttl=3600s pki
Success! Tuned the secrets engine at: pki/

 

정상 설정되었는지 확인한다.

$ vault read sys/mounts/pki/tune
Key                  Value
---                  -----
default_lease_ttl    1h
description          n/a
force_no_cache       false
max_lease_ttl        24h

 

24시간 사용할 수 있는 루트 인증서를 생성한다.

$ vault write -field=certificate pki/root/generate/internal \
   common_name="root.example.com" \
   ttl="86400h"

# 루트 인증서 확인
-----BEGIN CERTIFICATE-----
#...생략
BQAwGzEZMBcGA1UEAxMQcm9vdC5leGFtcGxlLmNvbTAeFw0yNDAyMjcwMzE0MzVa
Fw0yNDAyMjgwMzE1MDVaMBsxGTAXBgNVBAMTEHJvb3QuZXhhbXBsZS5jb20wggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEzF9fAZSpWAqsZVAPw+Ccdn8h
I92GUIvHkCbbmammH98CAl+v8csKbdEUz6WptMVJ2Unww9plkqhkPFJOcr6K8Gkd
HRqtUpQ0HTT3imUHIQEgcxTw3INWEUlLFIh2pX/rz0gALHzNv8G5ixBk0asv5OW+
#...생략
-----END CERTIFICATE-----

 

실제 생성된 루트 인증서에 대한 내용을 확인해 보면 다음과 같다.

$ openssl x509 -noout -text -in {인증서 파일}
Certificate:
    Data:
        Version: 3 (0x2)
#...생략
        Issuer: CN = root.example.com
        Validity
            Not Before: Feb 28 03:14:35 2024 GMT
            Not After : Feb 29 03:15:05 2024 GMT
        Subject: CN = root.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
#...생략
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier:
                1F:96:A3:00:3F:4D:5E:57:5A:41:6A:7F:1D:10:D9:AD:61:F0:63:DF
            X509v3 Authority Key Identifier:
                1F:96:A3:00:3F:4D:5E:57:5A:41:6A:7F:1D:10:D9:AD:61:F0:63:DF
            X509v3 Subject Alternative Name:
                DNS:root.example.com
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
#...생략

 

루트 인증서 기반 PKI role을 생성한다.

  • 인증서 갱신 테스트를 위해 TTL 2분으로 설정한다.
$ vault write pki/roles/pki-role \
  key_bits=4096 \
  ttl="120s" \
  max_ttl="120s" \
  allow_ip_sans=true \
  allowed_domains="example.com" \
  allow_subdomains=true

 

VSO에서 사용할 정책을 추가한다.

  • 여기서 추가하는 정책은 앞서 진행한 VSO 정적 시크릿 포스팅 글(Kuberenetes Auth Method 구성)에서 생성한 "vso-policy" 정책에 추가하는 설정이다.
$ vault policy write vso-policy - <<EOF
# 기존 정책
path "vso-test/data/secret" {
  capabilities = ["read"]
}

# 아래 정책 추가
path "pki/issue/pki-role" {
  capabilities = ["create", "update"]
}

path "pki/revoke" {
  capabilities = ["update"]
}
EOF

 

설정이 완료되었으면 Vault Pod에서 빠져나간다.

$ exit

 

 

2. Vault CRD 설정(VaultAuth, VaultPKISecret)


Kubernetes에 Vault 서버 인증을 위한 VaultAuth CRD를 작성하여 적용한다.

$ kubectl apply -f -<<EOF
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
  name: dynamic-auth
  namespace: default
spec:
  kubernetes:
    audiences:
    - vault
    role: vso
    serviceAccount: vso-sa
    tokenExpirationSeconds: 600
  method: kubernetes
  mount: kubernetes
EOF

 

Vault PKI 동적 시크릿을 Kubernetes 시크릿으로 생성 및 동기화를 위해 "VaultPKISecret" CRD를 작성하여 적용한다.

  • 2분마다 인증서가 갱신되는 설정이다.
$ kubectl apply -f -<<EOF
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultPKISecret
metadata:
  name: vault-pki
  namespace: default
spec:
  mount: pki
  role: pki-role
  commonName: test.example.com
  format: pem
  expiryOffset: 5s
  ttl: 2m
  destination:
    name: secretpki
    create: true
  revoke: true
  clear: true
  vaultAuthRef: dynamic-auth
EOF

 

Kubernetes에 생성된 Secret을 확인한다.

$ kubectl get secrets
NAME        TYPE                             DATA   AGE
#...생략
secretpki   Opaque                           7      0s

 

 

3.  인증서 생성 및 갱신 확인


실제 Vault UI 대시보드에서 생성된 인증서를 확인해 보자.

  • Vault UI 대시보드 로그인
  • [Secrets Engines] 선택 > "pki/" 선택 > [Certificates] 선택

 

총 3개의 인증서가 보인다.

1개는 root 인증서이고, 나머지 2개는 "VaultPKISecret" CRD 설정에 의해 생성된 인증서와 2분 후 갱신된 인증서이다.

 

다음은 최초 생성된 인증서이다.

 

다음은 2분 후 갱신된 인증서이다.

 

 

Operator(VSO) Pod 로그를 통해 인증서 생성 및 갱신 과정을 확인할 수 있다.

$ kubectl logs -n vault deploy/vault-secrets-operator-controller-manager
#...생략
# VaultPKISecret CRD를 통해 secret이 생성되어 발생한 로그
2024-02-28T05:33:21Z    INFO    Must sync       {"controller": "vaultpkisecret", "controllerGroup": "secrets.hashicorp.com", "controllerKind": "VaultPKISecret", "VaultPKISecret": {"name":"vault-pki","namespace":"default"}, "namespace": "default", "name": "vault-pki", "reconcileID": "34213185-5d9c-4569-b818-16134f1033d8", "reason": "InitialSync"}
2024-02-28T05:33:22Z    INFO    Successfully updated the secret {"controller": "vaultpkisecret", "controllerGroup": "secrets.hashicorp.com", "controllerKind": "VaultPKISecret", "VaultPKISecret": {"name":"vault-pki","namespace":"default"}, "namespace": "default", "name": "vault-pki", "reconcileID": "34213185-5d9c-4569-b818-16134f1033d8", "horizon": "1m56.815590208s"}

#...생략
# 2분 후 인증서 갱신되어 발생한 로그
2024-02-28T05:35:19Z    INFO    Must sync       {"controller": "vaultpkisecret", "controllerGroup": "secrets.hashicorp.com", "controllerKind": "VaultPKISecret", "VaultPKISecret": {"name":"vault-pki","namespace":"default"}, "namespace": "default", "name": "vault-pki", "reconcileID": "dde27b94-3be6-4754-be59-b771d9bd562e", "reason": "InRenewalWindow"}

#...생략
# 기존 인증서 revoke로 발생한 로그
2024-02-28T05:35:20Z    INFO    Revoking certificate "0c:76:e5:d1:23:47:02:eb:6e:12:0b:d9:72:34:57:80:35:73:1a:93"      {"controller": "vaultpkisecret", "controllerGroup": "secrets.hashicorp.com", "controllerKind": "VaultPKISecret", "VaultPKISecret": {"name":"vault-pki","namespace":"default"}, "namespace": "default", "name": "vault-pki", "reconcileID": "dde27b94-3be6-4754-be59-b771d9bd562e"}

 

리소스 정리를 위해 "VaultPKISecret"를 삭제하면 생성되었던 Kubernetes secret이 삭제되고, "revoke:true" 설정에 의해 기존 인증서도 revoke 되어 사용할 수 없게 된다.

$ kubectl delete vaultpkisecrets.secrets.hashicorp.com vault-pki

 

삭제 후 Operator(VSO) Pod 로그를 확인해 보면 다음과 같이 revoke 된 인증서 로그를 확인할 수 있다.

$ kubectl logs -n vault deploy/vault-secrets-operator-controller-manager
#...생략
2024-02-28T05:36:38Z    INFO    handleDeletion  Revoking certificate "6a:d0:dc:9a:26:93:e8:d9:b3:07:13:77:55:66:73:2a:bd:6b:3b:f5"      {"controller": "vaultpkisecret", "controllerGroup": "secrets.hashicorp.com", "controllerKind": "VaultPKISecret", "VaultPKISecret": {"name":"vault-pki","namespace":"default"}, "namespace": "default", "name": "vault-pki", "reconcileID": "673462d8-1beb-455f-b76a-e49f7ccab38d", "finalizer": "vaultpkisecrets.secrets.hashicorp.com/finalizer", "isSet": true}
#...생략

 

 

반응형

댓글