Overview
지난시간에 이어서 Vault 설치와 사용법에 대해서 알아보려고 한다.
kind를 사용해서 K8S Cluster 구성후 배포해볼 예정이다.
2022.10.11 - [Networking, Security, Protocols] - Vault란?
Kind 설치
30000번 포트를 하나 더 포트포워딩 해준다. 그 이유는 외부에서 30000번을 타고 vault로 접속을 해야하기 때문이다.
2024.01.13 - [Container Orchestration/Kubernetes] - kind(Kubernetes in Docker)란?
# 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
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://earthly.dev/blog/eso-with-hashicorp-vault/
https://devpress.csdn.net/k8s/62fce3137e66823466190e0a.html
https://developer.hashicorp.com/vault/docs/concepts/policies
'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이란? (2) | 2022.11.11 |