Vault Secrets Operator에 대한 내용은 이전 글에서 다루었다.
이번 글에서는 Vault에 저장된 PKI 동적 시크릿을 Kubernetes Secret으로 생성하여 동기화하는 실습을 진행한다.
참고
본 실습을 위해서는 이전 실습에서 구성한 환경이 필요하다.
실습 절차
1. Vault Secrets Operator PKI 시크릿 정의2. Vault CRD 설정(VaultAuth, VaultPKISecret)
3. 인증서 생성 및 갱신 확인
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}
#...생략
'Security > Vault' 카테고리의 다른 글
HashiCorp Vault Auto Unseal 기능 사용하여 구성하기 (AWS KMS) (0) | 2024.04.03 |
---|---|
Vault Transit Secret Engine 사용하기 (0) | 2024.04.01 |
Vault Secrets Operator(VSO)를 활용한 Kubernetes secrets 관리 (정적 시크릿) (0) | 2024.02.26 |
HashiCorp Vault 란? 개념부터 설치까지 (0) | 2023.04.08 |
댓글