Networking, Security, Protocols

Vault 설치와 사용법

Somaz 2024. 1. 24. 22:48
728x90
반응형

Overview

지난시간에 이어서 Vault 설치와 사용법에 대해서 알아보려고 한다.

kind를 사용해서 K8S Cluster 구성후 배포해볼 예정이다.

2022.10.11 - [Networking, Security, Protocols] - Vault란?

 

Vault란?

Overview 오늘은 Hashicorp Vault에 대해서 공부해보려고 한다. Vault란? HashiCorp Vault는 ID 기반 비밀 및 암호화 관리 시스템이다. Secret은 API 암호화 키, 암호 및 인증서와 같이 액세스를 엄격하게 제어하

somaz.tistory.com

 

Kind 설치

30000번 포트를 하나 더 포트포워딩 해준다. 그 이유는 외부에서 30000번을 타고 vault로 접속을 해야하기 때문이다.

2024.01.13 - [Container Orchestration/Kubernetes] - kind(Kubernetes in Docker)란?

 

kind(Kubernetes in Docker)란?

Overview kind(Kubernetes in Docker)에 대해서 알아보자. kind(Kubernetes in Docker)란? kind는 Docker 컨테이너 노드를 사용하여 로컬 Kubernetes 클러스터를 실행하기 위한 도구이다. kind는 주로 Kubernetes 자체를 테스

somaz.tistory.com

# cluster yaml 파일 생성
cat <<EOF > cluster-3nodes.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
    listenAddress: "0.0.0.0"
    protocol: TCP
- role: worker
- role: worker
EOF

# kind 설치
kind create cluster --name somaz-3nodes-kubernetes --config ./cluster-3nodes.yaml

# 설치 확인
k get nodes
NAME                                    STATUS   ROLES           AGE   VERSION
somaz-3nodes-kubernetes-control-plane   Ready    control-plane   34s   v1.27.3
somaz-3nodes-kubernetes-worker          Ready    <none>          10s   v1.27.3
somaz-3nodes-kubernetes-worker2         Ready    <none>          9s    v1.27.3

 


Vault 초기화

설치에 들어가기 전에 Vault 초기화 개념에 대해서 알아야한다.

 

HA환경, 특히 Raft 스토리지 백엔드에서 Vault를 초기화할 때 몇 가지 중요한 정보가 생성된다.

Vault를 처음 설치하면, 모든 Pod가 잠겨있다. 따라서 해제키를 사용해 잠금을 해제하고 루트 토큰을 사용해서 HA클러스터에 연결해줘야 한다.

cat cluster-keys.json
{
  "unseal_keys_b64": [
    "i1twvuaHofgdjplSZUsPTu3aTNGxyZjz6W5bElc5pnI="
  ],
  "unseal_keys_hex": [
    "8b5b70bee687a1f81d8e9952654b0f4eedda4cd1b1c998f3e96e5b125739a672"
  ],
  "unseal_shares": 1,
  "unseal_threshold": 1,
  "recovery_keys_b64": [],
  "recovery_keys_hex": [],
  "recovery_keys_shares": 0,
  "recovery_keys_threshold": 0,
  "root_token": "hvs.AQtv1aABPFtf6s6xcsVjX3sR"
}

 


 

해제 키(UNSEAL_KEY)

해당 키는 Vault의 잠금을 해제하는데 사용된다. Sealing Vault는 Vault를 잠그고 올바른 키를 사용하여 봉인을 풀 때까지 Vault에 접근할 수 없도록 하는 보안 기능이다.

 

루트 토큰(CLUSTER_ROOT_TOKEN)

Vault에 액세스하기 위한 마스터 키이다. Vault의 모든 비밀 및 구성에 대한 전체 액세스 권한을 제공

한다. 아주 중요한 키이다.

 


 

Vault 초기화 예시

1. 해제키 1개이고 잠금을 해제하는 필요한 해제키 1개일 때

k exec vault-0 -n vault -- vault operator init -key-shares=1 -key-threshold=1 -format=json > cluster-keys.json
  • `-key-shares=1` : Vault에서 생성하는 해제 키의 총 개수를 결정한다. 1로 설정했기 때문에 하나만 생성한다.
  • `-key-threshold=1` : Vault 잠금을 해제하는데 필요한 해제키를 설정한다. 1로 설정했기 때문에 해제 키 중 하나만 있으면 설정이 가능하다.
  • `-format=json` : 변수는 출력(해제 키 및 초기 루트 토큰 포함)이 JSON 형식이어야 함을 지정한다.

 

초기화 후 클러스터 로그인 방법

# 해제키 확인
cat cluster-keys.json | jq -r ".unseal_keys_b64[]"

# 해제 키 변수 등록
VAULT_UNSEAL_KEY=$(cat cluster-keys.json | jq -r ".unseal_keys_b64[]")

# 해제키로 잠금해제
kubectl exec vault-0 -n vault -- vault operator unseal $VAULT_UNSEAL_KEY

# 루트 토큰 확인
cat cluster-keys.json | jq -r ".root_token"

# 루트 토큰 변수 등록
CLUSTER_ROOT_TOKEN=$(cat cluster-keys.json | jq -r ".root_token")

# 루트 토큰으로 클러스터 로그인
kubectl exec vault-0 -n vault -- vault login $CLUSTER_ROOT_TOKEN

# 나머지 Node들 해제 및 루트 토큰 확인 및 변수 등록 방법은 동일

# 루트 토큰으로 나머지 Node들 클러스터 로그인
kubectl exec vault-1 -n vault -- vault operator raft join <http://vault-0.vault-internal:8200>
kubectl exec vault-2 -n vault -- vault operator raft join <http://vault-0.vault-internal:8200>

# 클러스터 상태확인
kubectl exec vault-0 -n vault -- vault operator raft list-peers

Node                                    Address                        State       Voter
----                                    -------                        -----       -----
38ab1d7a-8f6b-93ee-ff54-c986492b73a6    vault-0.vault-internal:8201    leader      true
bdf0efc9-91a1-1984-ee3c-f2e20849c4bd    vault-1.vault-internal:8201    follower    true
7b498967-d383-affa-fb5a-95b1650b4113    vault-2.vault-internal:8201    follower    true

 

2. 해제키 2개이고 잠금을 해제하는 필요한 해제키 2개일 때

k exec vault-0 -n vault -- vault operator init -key-shares=2 -key-threshold=2 -format=json > cluster-keys.json
cat cluster-keys.json
{
  "unseal_keys_b64": [
    "FbPft3K5JmIoqOHlvg0RvDjkvxsEnmD4BlDja6x5Gk2E",
    "Lc+wBkFg/lYlQbN3EypoJFloaOcc+9N9yPZDdNNJqBmJ"
  ],
  "unseal_keys_hex": [
    "15b3dfb772b9266228a8e1e5be0d11bc38e4bf1b049e60f80650e36bac791a4d84",
    "2dcfb0064160fe562541b377132a6824596868e71cfbd37dc8f64374d349a81989"
  ],
  "unseal_shares": 2,
  "unseal_threshold": 2,
  "recovery_keys_b64": [],
  "recovery_keys_hex": [],
  "recovery_keys_shares": 0,
  "recovery_keys_threshold": 0,
  "root_token": "hvs.Iqzs15KWDnOHm2GoZNk7aTdV"
}

 

초기화 후 클러스터 로그인 방법

  • 나머지 방법은 동일하다. 다만 해제할때 해제키가 2개 필요하기 때문에 2번해제해 줘야 한다.
# 해제 키 확인
cat cluster-keys.json | jq -r ".unseal_keys_b64[]"
FbPft3K5JmIoqOHlvg0RvDjkvxsEnmD4BlDja6x5Gk2E
Lc+wBkFg/lYlQbN3EypoJFloaOcc+9N9yPZDdNNJqBmJ

# VAULT_UNSEAL_KEY를 캡처하기 위해 변수를 만든다.
FIRST_VAULT_UNSEAL_KEY=$(jq -r '.unseal_keys_b64[0]' cluster-keys.json)
SECOND_VAULT_UNSEAL_KEY=$(jq -r '.unseal_keys_b64[1]' cluster-keys.json)

# 확인
echo $FIRST_VAULT_UNSEAL_KEY
FbPft3K5JmIoqOHlvg0RvDjkvxsEnmD4BlDja6x5Gk2E

echo $SECOND_VAULT_UNSEAL_KEY
Lc+wBkFg/lYlQbN3EypoJFloaOcc+9N9yPZDdNNJqBmJ

# 해제
kubectl exec vault-0 -n vault -- vault operator unseal $FIRST_VAULT_UNSEAL_KEY
kubectl exec vault-0 -n vault -- vault operator unseal $SECOND_VAULT_UNSEAL_KEY

# 상태확인
kubectl exec vault-0 -n vault -- vault status

Key                     Value
---                     -----
Seal Type               shamir
Initialized             true
Sealed                  false
Total Shares            2
Threshold               2
Version                 1.15.2
Build Date              2023-11-06T11:33:28Z
Storage Type            raft
Cluster Name            vault-cluster-51dc2ed2
Cluster ID              3a2c9d24-09cc-418c-ae0e-6e3e174d8676
HA Enabled              true
HA Cluster              <https://vault-0.vault-internal:8201>
HA Mode                 active
Active Since            2024-01-11T05:29:23.992412628Z
Raft Committed Index    53
Raft Applied Index      53

 

 


Vault 설치

Vault Helm Chart를 사용해서 설치해보겠다.

 


 

helm 설치

curl -fsSL -o get_helm.sh <https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3>
chmod 700 get_helm.sh
./get_helm.sh

https://somaz.tistory.com/141

 

Helm 이란? (Kubernetes Package manager)

Overview 오늘은 Kubernetes Package manager 인 Helm에 대해서 공부해보려고 한다. Helm 이란? Helm 이란 쿠버네티스 오픈 소스 패키지 매니저이다. Kubernetes용으로 구축된 소프트웨어를 제공, 공유 및 사용할

somaz.tistory.com

 


 

Vault 설치 전 사전준비

# namespace 생성
k create ns vault

# helm search
helm search repo hashicorp/vault

# helm repo 추가
helm repo add hashicorp <https://helm.releases.hashicorp.com>
helm repo update

# helm repo 추가 확인
helm repo list
NAME            URL
hashicorp       <https://helm.releases.hashicorp.com>

 

확인 방법(선택사항)

# helm 설치전 확인
helm install vault hashicorp/vault --namespace vault --dry-run

# 버전 확인
helm search repo hashicorp/vault --versions

# helm 설치(특정버전)
helm install vault hashicorp/vault --namespace vault --version 0.25.0

# 기본설정 재정의 확인
helm install vault hashicorp/vault \\
    --namespace vault \\
    --set "server.ha.enabled=true" \\
    --set "server.ha.replicas=5" \\
    --dry-run

# overide-value 확인
helm install vault hashicorp/vault \\
    --namespace vault \\
    -f override-values.yml \\
    --dry-run

 


 

Vault 설치 및 확인

helm install vault hashicorp/vault \\
    --set='server.ha.enabled=true' \\
    --set='server.ha.raft.enabled=true' \\
    -n vault

 

Pod 확인

k get po -n vault
NAME                                    READY   STATUS    RESTARTS   AGE
vault-0                                 0/1     Running   0          82s
vault-1                                 0/1     Running   0          82s
vault-2                                 0/1     Pending   0          82s
vault-agent-injector-7f7f68d457-kqlsh   1/1     Running   0          83s

kubectl exec vault-0 -n vault -- vault status
Key                Value
---                -----
Seal Type          shamir
Initialized        false
Sealed             true
Total Shares       0
Threshold          0
Unseal Progress    0/0
Unseal Nonce       n/a
Version            1.15.2
Build Date         2023-11-06T11:33:28Z
Storage Type       raft
HA Enabled         true
command terminated with exit code 2

 

Vault 초기화

k exec vault-0 -n vault -- vault operator init -key-shares=1 -key-threshold=1 -format=json > cluster-keys.json
  • `-key-shares=1` : Vault에서 생성하는 해제 키의 총 개수를 결정한다. 1로 설정했기 때문에 하나만 생성한다.
  • `-key-threshold=1` : Vault 잠금을 해제하는데 필요한 해제키를 설정한다. 1로 설정했기 때문에 해제 키 중 하나만 있으면 설정이 가능하다.
  • `-format=json` : 변수는 출력(해제 키 및 초기 루트 토큰 포함)이 JSON 형식이어야 함을 지정한다.

 

해제키 확인

cat cluster-keys.json | jq -r ".unseal_keys_b64[]"
Cx/RXjcjmJsRQAM57o9+sGbZTmODpOeQL097kbfMFQY=

 

VAULT_UNSEAL_KEY를 캡처하기 위해 변수를 만든다.

# jq 패키지 설치
sudo apt install jq

# 변수 설정
VAULT_UNSEAL_KEY=$(cat cluster-keys.json | jq -r ".unseal_keys_b64[]")

 

vault-0 잠금을 해제한다. 초기화가 완료되었다.

kubectl exec vault-0 -n vault -- vault operator unseal $VAULT_UNSEAL_KEY
Key                     Value
---                     -----
Seal Type               shamir
Initialized             true
Sealed                  false
Total Shares            1
Threshold               1
Version                 1.15.2
Build Date              2023-11-06T11:33:28Z
Storage Type            raft
Cluster Name            vault-cluster-a580d962
Cluster ID              25ccca2d-f62b-324b-8012-5c4535ddb760
HA Enabled              true
HA Cluster              <https://vault-0.vault-internal:8201>
HA Mode                 active
Active Since            2024-01-11T03:02:23.232069547Z
Raft Committed Index    52
Raft Applied Index      52

# 상태확인
kubectl exec vault-0 -n vault -- vault status

 

 


 

Vault HA 클러스터 연결

파드에서 실행되는 Vault 서버는 `vault-0` 단일 노드가 있는 Vault HA 클러스터이다.

노드 목록을 표시하려면 루트 토큰으로 로그인해야 한다.

 

루트토큰 확인

cat cluster-keys.json | jq -r ".root_token"
hvs.bOXica9b3vWqfBaiZWfASOC1

 

`CLUSTER_ROOT_TOKEN`를 캡처하기 위해 이름이 지정된 변수를 만든다.

CLUSTER_ROOT_TOKEN=$(cat cluster-keys.json | jq -r ".root_token")

 

`vault-0` 파드에 루트 토큰으로 로그인하여 Cluster에 로그인해준다.

kubectl exec vault-0 -n vault -- vault login $CLUSTER_ROOT_TOKEN

Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                  Value
---                  -----
token                hvs.AQtv1aABPFtf6s6xcsVjX3sR
token_accessor       sMX1CoAiYLZQCVGKMBgZHRKg
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

 

Vault 클러스터 내의 노드 확인

kubectl exec vault-0 -n vault -- vault operator raft list-peers
Node                                    Address                        State     Voter
----                                    -------                        -----     -----
38ab1d7a-8f6b-93ee-ff54-c986492b73a6    vault-0.vault-internal:8201    leader    true

 

동일하게 `vault-1, vault2` 파드도 진행해준다.

 

`vault-1` 파드를 `http://vault-0.vault-internal:8200` Cluster에 조인해준다.

kubectl exec vault-1 -n vault -- vault operator raft join <http://vault-0.vault-internal:8200>
Key       Value
---       -----
Joined    true

 

`vault-1` 파드에서 잠금을 해제한다. 초기화가 완료되었다.

kubectl exec vault-1 -n vault -- vault operator unseal $VAULT_UNSEAL_KEY

 

 

Vault 클러스터 상태를 확인해본다.

kubectl exec vault-0 -n vault -- vault operator raft list-peers
Node                                    Address                        State       Voter
----                                    -------                        -----       -----
38ab1d7a-8f6b-93ee-ff54-c986492b73a6    vault-0.vault-internal:8201    leader      true
bdf0efc9-91a1-1984-ee3c-f2e20849c4bd    vault-1.vault-internal:8201    follower    true

 

동일한 방법으로 `vault-2` 파드도 진행하면 된다. 다만 Kind로 진행시에, `2 node(s) didn't match pod anti-affinity rules` 해당 Message가 발생하며 `vault-2` 파드가 작동하지 않는다.

테스트를 위해 Control-Plane 에도 예약이 허용되도록 설정을 바꿔준다.

# vault-vaules.yaml
cat <<EOF > vault-values.yaml
server:
  ha:
    enabled: true
    raft:
      enabled: true
  tolerations:
    - key: "node-role.kubernetes.io/control-plane"
      operator: "Exists"
      effect: "NoSchedule"
EOF

# upgrade
helm upgrade vault hashicorp/vault -f vault-values.yaml -n vault

# upgrade2
helm upgrade vault hashicorp/vault \\
    --set='server.ha.enabled=true' \\
    --set='server.ha.raft.enabled=true' \\
    --set 'server.tolerations[0].key=node-role.kubernetes.io/control-plane' \\
    --set 'server.tolerations[0].operator=Exists' \\
    --set 'server.tolerations[0].effect=NoSchedule' \\
    -n vault

# vault-2 pod 삭제
k delete po -n vault vault-2

# 확인
k get po -n vault
NAME                                    READY   STATUS    RESTARTS   AGE
vault-0                                 1/1     Running   0          32m
vault-1                                 1/1     Running   0          32m
vault-2                                 0/1     Running   0          72s
vault-agent-injector-7f7f68d457-kqlsh   1/1     Running   0          32m

 

`vault-2` 파드를 `http://vault-0.vault-internal:8200` Cluster에 조인해준다.

kubectl exec vault-2 -n vault -- vault operator raft join <http://vault-0.vault-internal:8200>
Key       Value
---       -----
Joined    true

 

`vault-2` 파드에서 잠금을 해제한다. 초기화가 완료되었다.

kubectl exec vault-2 -n vault -- vault operator unseal $VAULT_UNSEAL_KEY

 

Vault 클러스터 상태를 확인한다.

kubectl exec vault-0 -n vault -- vault operator raft list-peers
Node                                    Address                        State       Voter
----                                    -------                        -----       -----
38ab1d7a-8f6b-93ee-ff54-c986492b73a6    vault-0.vault-internal:8201    leader      true
bdf0efc9-91a1-1984-ee3c-f2e20849c4bd    vault-1.vault-internal:8201    follower    true
7b498967-d383-affa-fb5a-95b1650b4113    vault-2.vault-internal:8201    follower    true

 


Vault Web 확인

 

NodePort로 오픈해준다.

k patch svc vault -n vault -p '{"spec": {"type": "NodePort", "ports": [{"nodePort": 30000, "port": 8200, "protocol": "TCP"}]}}'

 

웹 접속을 위해 Compute Engine 방화벽을 오픈한다.

## Firewall ##
resource "google_compute_firewall" "test_server_ssh" {
  name    = "allow-ssh-test-server"
  network = var.shared_vpc

  allow {
    protocol = "tcp"
    ports    = ["22", "30000"]
  }

  source_ranges = ["${var.public_ip}/32", "${var.public_ip2}/32", "0.0.0.0/0"]
  target_tags   = [var.test_server]

  depends_on = [module.vpc]
}

 

 

 

루트 토큰을 사용해서 로그인이 가능하다.

CLUSTER_ROOT_TOKEN=$(cat cluster-keys.json | jq -r ".root_token")

echo $CLUSTER_ROOT_TOKEN
hvs.bOXica9b3vWqfBaiZWfASOC1

 

 

이번엔 User를 생성해서 해당 User로 접속을 해본다.

kubectl exec --stdin=true --tty=true vault-0 -n vault -- /bin/sh

# userpass 활성화
vault auth enable userpass

# vault user 등록 예시
vault write auth/userpass/users/<username> password=<password> policies=<policies>

# vault user 등록
vault write auth/userpass/users/somaz password=somaz@2023 

# vault CLI 로그인 예시
vault login -method=userpass username=<username> password=<password>

 

접속이 잘된다.

 


 

Vault 활용

 


 

Vault Secret 설정

kv-v2 엔진은 `Key-Vaule` 엔진이다. 보통 ID/PW 또는 모든 `Key-Value` 값들을 사용할 때 쓴다.

# vault-0 pod 접속
kubectl exec --stdin=true --tty=true vault-0 -n vault -- /bin/sh
/ $

# kv-v2 Secret 활성화
vault secrets enable -path=secret kv-v2

Success! Enabled the kv-v2 secrets engine at: secret/

# secret/devwebapp/config를 사용하여 경로에 Secret을 생성
vault kv put secret/devdb/config username='somaz' password='somazpassword'

====== Secret Path ======
secret/data/devdb/config

======= Metadata =======
Key                Value
---                -----
created_time       2024-01-11T05:44:17.023693128Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

# secret/devwebapp/config에 Secret 생성 확인
vault kv get secret/devdb/config

====== Secret Path ======
secret/data/devdb/config

======= Metadata =======
Key                Value
---                -----
created_time       2024-01-11T05:44:17.023693128Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

====== Data ======
Key         Value
---         -----
password    somazpassword
username    somaz

 


 

Kubernetes 인증 구성

초기 루트 토큰은 모든 경로에서 모든 작업을 수행할 수 있는 권한이 있는 사용자이다.

웹 애플리케이션에는 단일 경로에 정의된 비밀을 읽는 기능만 필요하다. 이 애플리케이션은 액세스가 제한된 토큰을 인증하고 부여 받아야 한다.

# vault-0 pod 접속
kubectl exec --stdin=true --tty=true vault-0 -n vault -- /bin/sh
/ $

# Kubernetes 인증방법 활성화
vault auth enable kubernetes
  • Vault는 Kubernetes 클러스터 내의 모든 클라이언트로부터 서비스 토큰을 허용한다.
  • 인증 중에 Vault는 토큰 검토 Kubernetes 엔드포인트를 쿼리하여 서비스 계정 토큰이 유효한지 확인한다.
  • Kubernetes API의 위치를 사용하도록 Kubernetes 인증 방법을 구성한다.
  • 토큰 검토 API를 쿼리할 때 Pod의 자체 ID를 자동으로 사용하여 Kubernetes에 인증한다.

 

환경 변수가 `KUBERNETES_PORT_443_TCP_ADDR` 정의되고 Kubernetes 호스트의 내부 네트워크 주소를 참조한다.

vault write auth/kubernetes/config \\
    kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443"

 

Vault `devdb`를 활성화하는 정책을 작성한다.

# 정책 생성
vault policy write devdb - <<EOF
path "secret/data/devdb/config" {
  capabilities = ["read"]
}
EOF

# 정책 리스트 확인
vault policy list
default
devdb
root

# 정책 확인
vault policy read devdb
path "secret/data/devdb/config" {
  capabilities = ["read"]
}

 

Kubernetes 인증 역할을 생성한다.

# 역할 생성
vault write auth/kubernetes/role/db-app \\
        bound_service_account_names=somaz-app \\
        bound_service_account_namespaces=somaz \\
        policies=devdb \\
        ttl=24h

# 역할 확인
vault read auth/kubernetes/role/db-app
Key                                 Value
---                                 -----
alias_name_source                   serviceaccount_uid
bound_service_account_names         [somaz-app]
bound_service_account_namespaces    [somaz]
policies                            [devdb]
token_bound_cidrs                   []
token_explicit_max_ttl              0s
token_max_ttl                       0s
token_no_default_policy             false
token_num_uses                      0
token_period                        0s
token_policies                      [devdb]
token_ttl                           24h
token_type                          default
ttl                                 24h

 

웹 애플리케이션 배포

Vault Kubernetes 인증 역할에 지정된 Kubernetes 서비스 계정을 생성해야 한다.

# 네임스페이스와 서비스어카운트 생성
k create ns somaz
k create sa somaz-app -n somaz

 

 

웹 애플리케이션을 생성한다.

# yaml 파일생성
cat > devsomazapp.yaml <<EOF
---
apiVersion: v1
kind: Pod
metadata:
  name: devsomazapp
  labels:
    app: devsomazapp
  annotations:
    vault.hashicorp.com/agent-inject: "true"
    vault.hashicorp.com/role: "db-app"
    vault.hashicorp.com/agent-inject-secret-credentials.txt: "secret/data/devdb/config"
spec:
  serviceAccountName: somaz-app
  containers:
    - name: devsomazapp
      image: jweissig/app:0.0.1
EOF

# 생성
k apply -f devsomazapp.yaml -n somaz

# secret 확인
k exec --stdin=true --tty=true devsomazapp -c devsomazapp -n somaz -- cat /vault/secrets/credentials.txt
data: map[password:somazpassword username:somaz]
metadata: map[created_time:2024-01-11T05:44:17.023693128Z custom_metadata:<nil> deletion_time: destroyed:false version:1]

 


 

주석의 형식

주요한 점은 주석의 형식은 다음과 같아야 한다.

vault.hashicorp.com/agent-inject-secret-<unique-name>: /path/to/secret

 

2개 이상의 Secret을 정책으로 지정했다면, 아래와 같이 설정해줘야 한다.

vault.hashicorp.com/agent-inject-secret-devdb: secret/data/devdb/config
vault.hashicorp.com/agent-inject-secret-qadb: secret/data/qadb/config
vault.hashicorp.com/role: 'devdb-app'

 

테스트해본다.

# pod 접속
kubectl exec --stdin=true --tty=true vault-0 -n vault -- /bin/sh

# secret 생성
vault kv put secret/qadb/config username='qasomaz' password='qasomazpassword'

# 정책 생성
vault policy write qadb - <<EOF
path "secret/data/qadb/config" {
  capabilities = ["read"]
}
EOF

# 역할 추가
vault write auth/kubernetes/role/db-app \\
        bound_service_account_names=somaz-app \\
        bound_service_account_namespaces=somaz \\
        policies=devdb,qadb \\
        ttl=24h

# 역할 확인
vault read auth/kubernetes/role/db-app
Key                                 Value
---                                 -----
alias_name_source                   serviceaccount_uid
bound_service_account_names         [somaz-app]
bound_service_account_namespaces    [somaz]
policies                            [devdb qadb]
token_bound_cidrs                   []
token_explicit_max_ttl              0s
token_max_ttl                       0s
token_no_default_policy             false
token_num_uses                      0
token_period                        0s
token_policies                      [devdb qadb]
token_ttl                           24h
token_type                          default
ttl                                 24h

 

 

웹 애플리케이션 `yaml` 파일 변경 후 확인

# yaml 파일생성
cat > devsomazapp.yaml <<EOF
---
apiVersion: v1
kind: Pod
metadata:
  name: devsomazapp
  labels:
    app: devsomazapp
  annotations:
    vault.hashicorp.com/agent-inject: "true"
    vault.hashicorp.com/role: "db-app"
    vault.hashicorp.com/agent-inject-secret-devdb.txt: "secret/data/devdb/config"
    vault.hashicorp.com/agent-inject-secret-qadb.txt: "secret/data/qadb/config"
spec:
  serviceAccountName: somaz-app
  containers:
    - name: devsomazapp
      image: jweissig/app:0.0.1
EOF

# 생성
k apply -f devsomazapp.yaml -n somaz

# pod 재시작
k delete po -n somaz devsomazapp
k apply -f devsomazapp.yaml -n somaz

# 확인
k exec --stdin=true --tty=true devsomazapp -c devsomazapp -n somaz -- ls /vault/secrets/
devdb.txt  qadb.txt

k exec --stdin=true --tty=true devsomazapp -c devsomazapp -n somaz -- cat /vault/secrets/devdb.txt
data: map[password:somazpassword username:somaz]
metadata: map[created_time:2024-01-11T05:44:17.023693128Z custom_metadata:<nil> deletion_time: destroyed:false version:1]

k exec --stdin=true --tty=true devsomazapp -c devsomazapp -n somaz -- cat /vault/secrets/qadb.txt
data: map[password:qasomazpassword username:qasomaz]
metadata: map[created_time:2024-01-11T06:32:34.680311571Z custom_metadata:<nil> deletion_time: destroyed:false version:1]

 

 

연결 로그 확인

==> Vault Agent started! Log data will stream in below:

==> Vault Agent configuration:

           Api Address 1: <http://bufconn>
                     Cgo: disabled
               Log Level: info
                 Version: Vault v1.15.2, built 2023-11-06T11:33:28Z
             Version Sha: cf1b5cafa047bc8e4a3f93444fcb4011593b92cb

2024-01-11T09:49:04.605Z [INFO]  agent.sink.file: creating file sink
2024-01-11T09:49:04.605Z [INFO]  agent.sink.file: file sink configured: path=/home/vault/.vault-token mode=-rw-r-----
2024-01-11T09:49:04.605Z [INFO]  agent.exec.server: starting exec server
2024-01-11T09:49:04.605Z [INFO]  agent.exec.server: no env templates or exec config, exiting
2024-01-11T09:49:04.605Z [INFO]  agent.auth.handler: starting auth handler
2024-01-11T09:49:04.605Z [INFO]  agent.auth.handler: authenticating
2024-01-11T09:49:04.605Z [INFO]  agent.sink.server: starting sink server
2024-01-11T09:49:04.605Z [INFO]  agent.template.server: starting template server
2024-01-11T09:49:04.606Z [INFO] (runner) creating new runner (dry: false, once: false)
2024-01-11T09:49:04.606Z [INFO] (runner) creating watcher
2024-01-11T09:49:04.626Z [INFO]  agent.auth.handler: authentication successful, sending token to sinks
2024-01-11T09:49:04.626Z [INFO]  agent.auth.handler: starting renewal process
2024-01-11T09:49:04.626Z [INFO]  agent.sink.file: token written: path=/home/vault/.vault-token
2024-01-11T09:49:04.626Z [INFO]  agent.sink.server: sink server stopped
2024-01-11T09:49:04.627Z [INFO]  agent: sinks finished, exiting
2024-01-11T09:49:04.626Z [INFO]  agent.template.server: template server received new token
2024-01-11T09:49:04.627Z [INFO] (runner) stopping
2024-01-11T09:49:04.627Z [INFO] (runner) creating new runner (dry: false, once: false)
2024-01-11T09:49:04.627Z [INFO] (runner) creating watcher
2024-01-11T09:49:04.627Z [INFO] (runner) starting
2024-01-11T09:49:04.636Z [INFO] (runner) rendered "(dynamic)" => "/vault/secrets/devdb.txt"
2024-01-11T09:49:04.637Z [INFO] (runner) rendered "(dynamic)" => "/vault/secrets/qadb.txt"
2024-01-11T09:49:04.637Z [INFO] (runner) stopping
2024-01-11T09:49:04.637Z [INFO]  agent.template.server: template server stopped
2024-01-11T09:49:04.637Z [INFO] (runner) received finish
2024-01-11T09:49:04.637Z [INFO]  agent.auth.handler: shutdown triggered, stopping lifetime watcher
2024-01-11T09:49:04.637Z [INFO]  agent.auth.handler: auth handler stopped
2024-01-11T09:49:04.637Z [INFO]  agent.exec.server: exec server stopped

 

 


 

User Policy 설정

Web에서 Root Token을 사용하여 Policy를 확인해보면 전부 보인다.

 

Somaz 라는 User로 접속하면 아무것도 보이지 않는다.

 

 

CLI로 로그인해서 확인해본다.

vault login -method=userpass username=somaz password=somaz@2023
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                    Value
---                    -----
token                  hvs.CAESIIh84VvEP8vneC8oT3zzVIdxXCEHTGwAhkRdcViPeUA0Gh4KHGh2cy5SUHNuTjRTVmIxWWRNZHFPUUo2ZTBIVEg
token_accessor         mwevmGz8mEe6tKF8HfguHExl
token_duration         768h
token_renewable        true
token_policies         ["default" "devdb"]
identity_policies      []
policies               ["default" "devdb"]
token_meta_username    somaz

vault token lookup
Key                 Value
---                 -----
accessor            mwevmGz8mEe6tKF8HfguHExl
creation_time       1705632637
creation_ttl        768h
display_name        userpass-somaz
entity_id           5d390cf1-92cb-3d74-c3ef-d70682544cd7
expire_time         2024-02-20T02:50:37.201652198Z
explicit_max_ttl    0s
id                  hvs.CAESIIh84VvEP8vneC8oT3zzVIdxXCEHTGwAhkRdcViPeUA0Gh4KHGh2cy5SUHNuTjRTVmIxWWRNZHFPUUo2ZTBIVEg
issue_time          2024-01-19T02:50:37.201659907Z
meta                map[username:somaz]
num_uses            0
orphan              true
path                auth/userpass/login/somaz
policies            [default devdb]
renewable           true
ttl                 767h59m47s
type                service

 

 

정책 생성 후 할당한다.

# root로 로그인
vault login hvs.bOXica9b3vWqfBaiZWfASOC1

# 정책 생성
vault policy write admin - <<EOF
path "*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
EOF

vault write auth/userpass/users/somaz policies=devdb policies=admin

vault read auth/userpass/users/somaz
Key                        Value
---                        -----
policies                   [admin devdb]
token_bound_cidrs          []
token_explicit_max_ttl     0s
token_max_ttl              0s
token_no_default_policy    false
token_num_uses             0
token_period               0s
token_policies             [admin devdb]
token_ttl                  0s
token_type                 default

 

 

잘 보인다. 모든 권한을 다줬다.

 

 


Reference

https://developer.hashicorp.com/vault/tutorials/kubernetes/kubernetes-raft-deployment-guide

https://github.com/hashicorp/vault-helm

https://developer.hashicorp.com/vault/tutorials/kubernetes/kubernetes-google-cloud-gke

https://developer.hashicorp.com/vault/tutorials/kubernetes/kubernetes-external-vault#deploy-service-and-endpoints-to-address-an-external-vault

https://www.freshbrewed.science/vault-on-kubernetes-part-2-multiple-k8s-templates-and-external-ips/index.html

https://earthly.dev/blog/eso-with-hashicorp-vault/

https://devpress.csdn.net/k8s/62fce3137e66823466190e0a.html

https://developer.hashicorp.com/vault/docs/concepts/policies

728x90
반응형

'Networking, Security, Protocols' 카테고리의 다른 글

haproxy 개념 및 구성 가이드  (0) 2024.04.09
Cilium이란?  (2) 2024.02.06
Curl(Client URL)이란?  (0) 2023.05.26
SSID(Service Set Identifier)란?  (0) 2023.04.05
CDN이란?  (0) 2022.11.11