목차

  • 들어가며
  • Vault Docker 환경 구성
  • 참고문헌

 

들어가며

본 게시물은 Vault 공식 문서의 내용과 필자의 생각을 정리하였다. Vault는 무엇인지, 어디에 사용하는지, 왜 사용하는지, 어떻게 사용하는지 서술한다. Vault를 처음 접하는 인원은 Vault의 흐름과 골격을 이해할 수 있는 시간을 갖는다. 또한 Vault를 실질적으로 사용해보는 시간을 갖는다. Vault는 Dev 서버 모드를 지원한다. Dev 서버 모드는 사전 설정이 되어있는 데모 서버라고 생각하면 좋다. 사용자는 해당 데모 서버에서 Vault를 학습할 수 있다. 시간이 괜찮으면 Vault HA를 구성한다(시간이 있으면...). 

 

본 게시물의 시리즈는 다음과 같다.

 

Vault Docker 환경 구성

[개요]

yum 패키지 설치 기능을 사용하여 Vault 환경을 구성할 수 있다. 이번에는 Docker를 활용하여 Vault 환경을 구성한다. 해당 환경을 구성하기 위해 Docker는 당연히 사용하며, Docker-Compose까지 사용한다. 디렉토리의 구조는 아래와 같다. 환경 구성 후 가동 및 테스트 API만 호출한다.

vault
 |
 -- data  
 |
 -- config
 |    | 
 |    -- config.hcl
 |
 -- docker-compose.yml

 

[Docker 설치 및 기본 설정]

Docker는 별도의 설정을 하지 않을 경우 root 권한으로만 가동할 수 있다. 아래와 같이 설정하면 user 권한에서 Docker를 제어할 수 있다. 

$yum install docker
$yum install docker-compose

$groupadd docker
$usermod -aG docker $username
$sudo systemctl start docker
$sudo chmod 666 /var/run/docker.sock

Docker 명령어 확인 및 Vault 최신 이미지를 갖고온다. 

$docker ps -a

$docker pull vault

 

[Vault - Config]

 

#config.hcl

storage "raft" {
  path = "/vault/file"#vault dir in docker
  node_id = "node1"
}

listener "tcp" {
  address = "0.0.0.0:8200"
  tls_disable = "true"
}

api_addr="http://127.0.0.1:8200"
cluster_addr="https://127.0.0.1:8201"
ui = true

참고로 Listen address를 0.0.0.0을 설정해야 정상 가동할 수 있다.

 

[Vault - docker-comopse.yml]

#docker_compose.yml

version: "2"

services:
  vault:
	image: vault:latest
	container_name: vault
	volumes:
	  - ./vault/config:/vault/config
	  - ./vault/data:/vault/data
	ports:
	  - 8200:8200
	cap_add:
	  - IPC_LOCK
	command: vault server -config=/vault/config/config.hcl

 

[Vault - Docker 구동 및 테스트]

$docker-compose up -d

$curl http://127.0.0.1:8200/v1/sys/init | jq

//응답
{"initialized":false}

위의 응답은 정상적인 반환문이다. 

Vault 서버의 초기화 작업($vault operator init)을 하지 않았기 때문에 반환문의 값은 false이다. 

 

참고문헌

https://blog.exxeta.com/en/2019/12/20/setup-hashicorp-vault-on-docker/
https://stackoverflow.com/questions/50031086/why-does-vault-by-hashicorp-require-the-ipc-lock-capability-to-be-enabled
https://stackoverflow.com/questions/45171564/using-vault-with-docker-compose-file
https://hub.docker.com/_/vault
https://github.com/hashicorp/vault/issues/441

 

Posted by 동팡

목차

  • 들어가며
  • Vault Real 서버 튜토리얼
  • 참고문헌

 

들어가며

본 게시물은 Vault 공식 문서의 내용과 필자의 생각을 정리하였다. Vault는 무엇인지, 어디에 사용하는지, 왜 사용하는지, 어떻게 사용하는지 서술한다. Vault를 처음 접하는 인원은 Vault의 흐름과 골격을 이해할 수 있는 시간을 갖는다. 또한 Vault를 실질적으로 사용해보는 시간을 갖는다. Vault는 Dev 서버 모드를 지원한다. Dev 서버 모드는 사전 설정이 되어있는 데모 서버라고 생각하면 좋다. 사용자는 해당 데모 서버에서 Vault를 학습할 수 있다. 시간이 괜찮으면 Vault HA를 구성한다(시간이 있으면...). 

 

본 게시물의 시리즈는 다음과 같다.

 

Vault Real 서버 튜토리얼

[Vault 최종 디렉토리 구성]

Vault 디렉토리에 존재하는 파일

  • config.hcl: Vault 엔진 설정 정보
  • data: 데이터를 보관하는 장소
  • keyinfo.txt: SSS 알고리즘으로 분할한 키와 Root 토큰 정보
  • start.sh: Vault를 기동하기 위한 쉘 스크립트
  • stop.sh: Vault를 종료하기 위한 쉘 스크립트

굵게 표시한 것은 필수적으로 구성해야 하는 것이며, 기울여서 표시한 것은 편리를 위해 구성한 것이다. 그러나 프로덕트 환경에서는 keyinfo.txt 파일은 별도 디바이스에 보관해야 한다. 

 

[환경 구성]

CentOS 기준, yum 명령어를 사용하여 Vault를 설치한다. 설치방법은 Vault Tutorial 페이지에서 확인할 수 있다.

$mkdir vault

$cd vault

$vi config.hcl
	
    storage "raft" {
	  path = "./data"
	  node_id = "node1"
	}

	listener "tcp" {
	  address = "127.0.0.1:8200"
	  tls_disable = "true"
	}

	api_addr="http://127.0.0.1:8200"
	cluster_addr="https://127.0.0.1:8201"
	ui = true

$mkdir data

 

아래와 같이 VAULT_ADDR 환경변수 설정

$vi ./.bash_profile
	VAULT_ADDR='http://127.0.0.1:8200'
	export VAULT_ADDR
			
$source ./.bash_profile

// 또는

$ export VAULT_ADDR='http://127.0.0.1:8200'

// 확인 
$set  | grep VAULT_ADDR

 

[Vault 서버 가동 및 초기화]

Vault 서버 가동

"-config"에는 config.hcl의 경로를 지정한다.

$vault server -config=/home1/irteamsu/vault/config.hcl &

 

Vault 서버 초기화 및 Unsealing

Vault 서버 가동 후 최초 1회 초기화 작업을 진행한다. 해당 초기화 작업으로 Vault 설정정보에 따라 SSS 분할키와 Root 토큰을 생성한다. 별도의 설정 정보가 없을 경우 threshold는 (3, 5)이다. 즉 5개의 분할키를 부여하며, 원본을 만들기 위해서는 최소 3개의 분할키가 필요하다. 필자의 경우 프로덕트 환경이 아니기 때문에 아래의 분할키와 Root 토큰을 keyinfo.txt 파일에 보관하였다. 

$vault operator init

2021-06-15T16:43:36.202+0900 [INFO]  core: pre-seal teardown complete
		Unseal Key 1: Iv9H20vmAUMkDaAfyuar2rSWyGnZgvBOhQPl7df4lrib
		Unseal Key 2: G7SnjSZPOaZwkMX9rvCyK8ssdoIMAdAYu+oDo1b9uZ+j
		Unseal Key 3: jNfpkii4QiJsuIUVwkuIm1jjIz+bzh5oalsfevXGs5Wc
		Unseal Key 4: NnruCilytFhgdQ4zCQmKeSrrV4e8Ijws663trVHAamyl
		Unseal Key 5: pqb+bP30/wAraxLITsnjza1ibDyqKIcAHTEZkDzf902W

		Initial Root Token: s.ZPBA2pFTJEtmlaUfIEHk1Lq6

		Vault initialized with 5 key shares and a key threshold of 3. Please securely
		distribute the key shares printed above. When the Vault is re-sealed,
		restarted, or stopped, you must supply at least 3 of these keys to unseal it
		before it can start servicing requests.

		Vault does not store the generated master key. Without at least 3 key to
		reconstruct the master key, Vault will remain permanently sealed!

		It is possible to generate new unseal keys, provided you have a quorum of
		existing unseal keys shares. See "vault operator rekey" for more information.

서버 가동, 초기화 작업을 완료하였다. 그러나 Vault는 아직 "Sealed" 상태이다. 위의 분할키는 Vault의 상태를 "Unsealed" 상태로 전이할 수 있다. 

$vault operator unseal G7SnjSZPOaZwkMX9rvCyK8ssdoIMAdAYu+oDo1b9uZ+j
$vault operator unseal jNfpkii4QiJsuIUVwkuIm1jjIz+bzh5oalsfevXGs5Wc
$vault operator unseal NnruCilytFhgdQ4zCQmKeSrrV4e8Ijws663trVHAamyl

위의 작업을 완료하면 Sealed false 값을 확인할 수 있다. Root 토큰으로 로그인한 사용자는 "vault operator seal" 명령을 사용하여 Vault 서버에 Sealing을 할 수 있다. root 사용자의 경우, vault operator seal을 통해 sealing을 다시 할 수 있다. 이제 Vault를 마음껏 사용할 수 있다. 

 

[Vault 가동 스크립트 작성]

Vault를 기동할 때 "Unsealing" 절차는 필수이다. 해당 절차의 편리를 위해 스크립트를 작성한다. 스크립트는 아래와 같다.

start.sh

#!/bin/bash

partOfKey1=$1
partOfKey2=$2
partOfKey3=$3

if [ "$#" != 3 ]
then
		echo "argument is not 3"
		exit
else
		vault server -config=/home1/irteamsu/vault/config.hcl &

		sleep 1
		echo -ne '\n'

		vault operator unseal $1
		vault operator unseal $2
		vault operator unseal $3
fi

 

stop.sh

#!/bin/bash

pid=`ps aux | grep 'vault server' | grep -v grep | awk '{print $2}'`

if [ -z "$pid" ]
then
	echo "server is not running"
else
	echo "shutdown..."
	kill -9 $pid
fi

추가 분기를 사용하여 kill -9, -15 옵션을 결정할 수 있다. 필자는 그냥 "-9"를 사용하였다. 프로덕트 환경의 경우, "-15" 옵션을 위한 분기 사용을 권한다. 

 

[Vault 사용 - REST API - 서버 상태 확인]

$curl http://127.0.0.1:8200/v1/sys/init | jq

 

[Vault 사용 - REST API - auth method 활성화]

(Root 토큰을 환경변수에 지정한다(VAULT_TOKEN).)

$curl -X POST -H "X-Vault-Request: true" -H "X-Vault-Token: $VAULT_TOKEN" -d '{"type":"approle","description":"","config":{"options":null,"default_lease_ttl":"0s","max_lease_ttl":"0s","force_no_cache":false},"local":false,"seal_wrap":false,"external_entropy_access":false,"options":null}' http://127.0.0.1:8200/v1/sys/auth/approle

 

[Vault 사용 - REST API - 정책 추가]

$curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request PUT \
--data '{"policy":"# Dev servers have version 2 of KV secrets engine mounted by default, so will\n# need these paths to grant permissions:\npath \"secret/data/*\" {\n  capabilities = [\"create\", \"update\"]\n}\n\npath \"secret/data/foo\" {\n  capabilities = [\"read\"]\n}\n"}' \
-D - http://127.0.0.1:8200/v1/sys/policies/acl/my-policy

커맨드 명령어를 사용하여, 추가한 정책을 확인한다.

$vault policy list

 

[Vault 사용 - REST API - SecretPath 생성]

$curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{ "type":"kv-v2" }' \
-D - http://127.0.0.1:8200/v1/sys/mounts/secret

 

[Vault 사용 -REST API - 정책 기반으로 Role 생성]

$curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"policies": ["my-policy"]}' \
-D - http://127.0.0.1:8200/v1/auth/approle/role/my-role

커맨드 명령어를 사용하여, 추가한 Role을 확인한다.

$vault list auth/approle/role
$vault read auth/approle/role/my-role
$vault read auth/approle/role/my-role/role-id

REST API를 사용하여, 추가한 Role을 확인한다.

$curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
http://127.0.0.1:8200/v1/auth/approle/role/my-role/role-id | jq -r ".data"

 

[Vault  사용 - REST API - Secret-ID 생성/확인]

$curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
http://127.0.0.1:8200/v1/auth/approle/role/my-role/secret-id | jq -r ".data"
	
//응답
{
  "secret_id": "c7d3485f-403d-0c57-320d-3eb97697d85a",
  "secret_id_accessor": "b0e25931-9e7e-4a4d-80b6-11a0087671d5",
  "secret_id_ttl": 0
}

 

[Vault 사용 - REST API - AppRole 인증 및 클라이언트 토큰 반환]

ㄴㅇ

$curl --request POST \
--data '{"role_id": "93bfae74-3356-9b0d-08b3-8c2cdc76f55a", "secret_id": "c7d3485f-403d-0c57-320d-3eb97697d85a"}' \
http://127.0.0.1:8200/v1/auth/approle/login | jq -r ".auth"


// 응답
{
  "client_token": "s.DOqgLc4sIVKJjmgVIzCIJVeZ",
  "accessor": "eRxKIqBlT3eKsKRCfvt80sLO",
  "policies": [
	"default",
	"my-policy"
  ],
  "token_policies": [
	"default",
	"my-policy"
  ],
  "metadata": {
	"role_name": "my-role"
  },
  "lease_duration": 2764800,
  "renewable": true,
  "entity_id": "d624b3eb-0e52-fb88-439f-f456a8519fa2",
  "token_type": "service",
  "orphan": true
}

 

[Vault 사용 - REST API - 클라이언트 토큰으로 Secret 저장]

먼저 클라이언트 토큰을 환경변수에 저장한다. 

$export VAULT_TOKEN="s.DOqgLc4sIVKJjmgVIzCIJVeZ"

 

REST API를 사용하여 Secret을 저장한다.

$curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{ "data": {"password": "my-long-password"} }' \
http://127.0.0.1:8200/v1/secret/data/creds | jq -r ".data"

이렇게 Dev 모드가 아닌 실제 서버를 설정하였다. 해당 서버는 vault 커맨드를 사용하여 제어할 수 있으며, REST API를 사용하여 제어할 수 있다. 본 게시글은 curl 명령과 함께 REST API를 사용하였다. 실질적으로 프로덕션 레벨에서는 클라이언트 토큰을 생성 후, Secret을 제어하는 것이다. 해당 사항은 Java/Spring환경을 구성한 후 테스트 예정이다.  

 

참고문헌

Vault 공식 튜토리얼 사이트

Posted by 동팡

목차

  • 들어가며
  • Vault Dev 서버 모드 튜토리얼
  • 참고문헌

 

들어가며

본 게시물은 Vault 공식 문서의 내용과 필자의 생각을 정리하였다. Vault는 무엇인지, 어디에 사용하는지, 왜 사용하는지, 어떻게 사용하는지 서술한다. Vault를 처음 접하는 인원은 Vault의 흐름과 골격을 이해할 수 있는 시간을 갖는다. 또한 Vault를 실질적으로 사용해보는 시간을 갖는다. Vault는 Dev 서버 모드를 지원한다. Dev 서버 모드는 사전 설정이 되어있는 데모 서버라고 생각하면 좋다. 사용자는 해당 데모 서버에서 Vault를 학습할 수 있다. 시간이 괜찮으면 Vault HA를 구성한다(시간이 있으면...). 

 

본 게시물의 시리즈는 다음과 같다.

 

Vault Dev 서버 모드 튜토리얼

CentOS 기준, yum 명령어를 사용하여 Vault를 설치한다. 설치방법은 Vault Tutorial 페이지에서 확인할 수 있다.

 

[Vault 서버 가동]

$vault server -dev &

$vault server -dev & 후의 vault 로그


[Vault 환경 변수 설정]

환경 변수 설정은 필수가 아니다. 그러나 CLI 환경에서 Vault 명령을 쉽게 사용하기 위해 환경변수를 설정한다. CentOS는 .bash_profile를 통해 환경변수를 영구 설정할 수 있지만, 그렇게 하지 않는다.

 

위의 로깅된 Root Token과 HOST에 맞게 환경변수를 설정한다.

$export VAULT_ADDR='http://127.0.0.1:8200'
$export VAULT_TOKEN="s.XmpNPoi9sRhYtdKHaQhkHP6x"

환경변수 조회 및 확인 

$ set | grep VAULT

[Vault 사용 - Secret 등록]

$vault kv put secret/hello foo=world 

설명

  • Secret, foo=world 등록
  • kv: key-value storage에 접근할 때 사용
  • put secret/hello: secret/hello라는 secret 생성(위치? 엔드포인트?)
  • foo=world: foo라는 파라메터와 함께 secret 생성
  • +) vault kv put 명령은 생성할 때 사용하지만 갱신/대체 작업에도 사용

[Vault 사용 - Secret 조회]

$vault kv get secret/hello

$vault kv get -field=foo secret/hello

$vault kv get -format=json secret/hello

설명

  • get secret/hello: secret/hello에 위치하는 Secret 조회
  • -field=foo: foo 필드의 값만 조회
  • -format=json: JSON 형식으로 조회(json, yaml, table 형식으로 조회 가능, 디폴트 값은 table)

[Vault 사용 - Secret 폐기]

$vault kv delete secret/hello

설명

  • delete: secret/hello에 위치하는 것을 폐기

[Vault 사용 - Secret Engine 생성]

Key/Value형식의 Secret Engine 생성 및 조회

$vault secrets enable -path=kv kv

$vault secrets list

Vault Secret List

[Vault 사용 - 방금 생성한 Secret Engine에 Secret 등록]

$vault kv put kv/my-secret value="s3c(eT"

$vault kv get kv/my-secret

$vault kv delete kv/my-secret

$vault kv list kv/

$vault secrets disable kv

$vault secrets enable -path=kv kv

[Vault 사용 - 토큰 생성]

토큰을 생성/로그인/폐기한다.

$vault token create

$vault login s.w5cdTSBCLaFbHAu8lHDfHpCW

$vault token revoke s.w5cdTSBCLaFbHAu8lHDfHpCW

[Vault 사용 - 토큰의 정책 설정]

$vault policy list 

$vault policy read default

$vault policy write my-policy - << EOF
# Dev servers have version 2 of KV secrets engine mounted by default, so will
# need these paths to grant permissions:
path "secret/data/*" {
  capabilities = ["create", "update"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}
EOF

$vault token lookup

$vault token create -policy=my-policy

$export VAULT_TOKEN="$(vault token create -field token -policy=my-policy)"

$vault kv put secret/creds password="my-long-password"
$vault kv put secret/creds password="my-long-password-1"

$vault kv get secret/creds   //(안됨)

$export VAULT_TOKEN="s.kZw14yyEbEIkDSRRSLEsVM8M"    //(root 토큰)
$vault kv get secret/creds(됨)

설명

  • 토큰 생성 시 정책을 적용할 수 있다.
  • 정책은 Secret에 대해 접근제어를 실시한다. 
  • 정책 "my-policy의 설명은 다음과 같다.
    • "secret/data 이하의 경로에 대해 create와 update 작업을 실시할 수 있다(udpate는 put을 통한 갱신 작업).
    • "secret/data/foo에 해당하는 경로는 read 작업을 실시할 수 있다.
  • 다음의 설명은 생략한다.

[Vault 사용 - AppRole]

위의 "토큰 생성" 부분에서 Vault는 사용자의 토큰을 인증 절차 없이 생성한다. 이유는 다음과 같다. 현재 적용된 토큰은 "루트 토큰"이다. 그래서 인증 절차 없이 사용자의 토큰을 생성할 수 있다. 그러나 일반적인 상황에서는 인증 절차가 필요하다. 대표적인 인증 절차는 ID/PW 방식을 사용할 수 있다. Vault의 AppRole은 식별값(ID)/인증값(PW)을 이용해서 토큰을 발급한다. 또한 정책을 적용할 수 있으며, 토큰에 적용 가능하다.

// approle 확인
$vault auth list | grep 'approle/'

// 리스트업이 되지 않을 경우, approle 활성화
$vault auth enable approle

// approle 확인
$vault auth list | grep 'aaprole/'

//approle에 my-role(사용자) 생성
$vault write auth/approle/role/my-role \
secret_id_ttl=10m \
token_num_uses=10 \
token_ttl=20m \
token_max_ttl=30m \
secret_id_num_uses=40 \
token_policies=my-policy

// approle 조회
$vault list auth/approle/role
$vault read auth/approle/role/my-role
$vault read auth/approle/role/my-role/role-id
$vault read -field=role_id auth/approle/role/my-role/role-id

// ROLE_ID(식별자) 환경 변수 적용 및 조회
$export ROLE_ID="$(vault read -field=role_id auth/approle/role/my-role/role-id)"
$set | grep -e VAULT -e ROLE_ID

// SECRET_ID 설정(AppRole 인증을 위한 비밀번호 개념과 비슷하다.)
// SECRET_ID(인증값) 환경 변수 적용 및 조회
// vault write를 별도로 진행해도 괜찮다.
$export SECRET_ID="$(vault write -f -field=secret_id auth/approle/role/my-role/secret-id)"
$set | grep -e SECRET_ID -e VAULT -e ROLE_ID

// 토큰 요청
// approle 인증 완료 후, 토큰을 반환받을 수 있다.
$vault write auth/approle/login role_id="$ROLE_ID" secret_id="$SECRET_ID"

 

참고문헌

Vault 공식 튜토리얼 사이트

Posted by 동팡

목차

  • 들어가며
  • 개요 
  • 용어 정의
  • 아키텍처 개요

 

들어가며

본 게시물은 Vault 공식 문서의 내용과 필자의 생각을 정리하였다. Vault는 무엇인지, 어디에 사용하는지, 왜 사용하는지, 어떻게 사용하는지 서술한다. Vault를 처음 접하는 인원은 Vault의 흐름과 골격을 이해할 수 있는 시간을 갖는다. 또한 Vault를 실질적으로 사용해보는 시간을 갖는다. Vault는 Dev 서버 모드를 지원한다. Dev 서버 모드는 사전 설정이 되어있는 데모 서버라고 생각하면 좋다. 사용자는 해당 데모 서버에서 Vault를 학습할 수 있다. 시간이 괜찮으면 Vault HA를 구성한다(시간이 있으면...). 

 

본 게시물의 시리즈는 다음과 같다.

 

개요

HashiCorp의 Vault는 민감한 데이터를 안전하게 저장하는 저장소이다. 민감한 데이터의 종류는 다음과 같다. 1)Secret 2)Credential 3)Password 4)Enctyption-Key 등이다. 이와 같이 기밀성이 요구되는 정보는 DBMS에 단순 저장하면 안 된다. Vault는 위의 개체들을 암호화하여 안전하게 저장한다. 

 

용어 정의

Storage Backend

  • Vault의 암호화된 Secret을 보관하는 곳이다. 

Barrier

  • Barrier는 Vault의 일부 구성요소를 감싸고 있다. 때문에 Vault와 Storage Backend 간의 통신은 Barrier를 거쳐야 하며, Barrier가 프록시 역할(대문 역할)을 한다. Barrier의 구성요소들은 서로 Trust 한 관계를 유지/성립한다.
  • Vault는 암호화된 데이터만 밖으로 나오게 한다.
  • Vault는 Barrier의 상태가 “unsealed”가 되어야 접근할 수 있다.

Secret Engine

  • Secret의 관리를 책임진다.
  • Secret 관련 작업은 Secret Engine으로 전달하고 Engine의 구현체마다 상이한 방식으로 저장한다. 
  • Secret Engine의 인터페이스를 활용하여 DB, File System 또는 유저가 정의한 방식으로 저장한다.

Audit Device

  • 모든 Vault의 Request/Respones는 Audit Device에 의해 감사 로깅이 된다. 

Auth Method 

  • Vault에 접근하는 클라이언트를 인증한다.
  • 인증된 클라이언트의 토큰을 반환한다.

Client Token

  • HTTP에서의 세션 ID와 같은 토큰을 반환한다.
  • Vault의 REST API를 사용하는 경우 HTTP 헤더에 토큰을 적재한다.

Secret

  • Vault에서 관리하는 비밀 객체이다.
  • Secret은 일정 주기를 가지며, 해당 주기가 만료되면 폐기해야 한다.

 

 

아키텍처 개요

High level overview of vault

[전체 흐름]

 

Vault는 기밀성이 요구되는 데이터(이하 Secret)를 안전하게 보관하는 저장소이다. Vault를 사용하기 위해서는 “unsealing” 초기화 작업이 필요하다. Vault 서버 초기화 시 Vault“sealed” 상태이다. “Unsealed-Key”는 “sealed” 상태를 “unsealed” 상태로 전이할 수 있다. “unsealed” 상태가 되면 Barrier안에 있는 Vault의 모든 기능 및 구성요소에 원활하게 접근할 수 있다.

 

Vault에서 실질적으로 Secret을 암/복호화하는 키는 "Encryption-Key"이다.

1) "Master-Key"는 “Encryption-Key”를 암호화한다.

2) "Unsealed-Key"는 “Master-Key”를 암호화한다.

3) “Unsealed-key”SSS(Shamir Secret Sharing) 알고리즘으로분할 보관한다.

 

키들의 관계는 아래 도식화 자료와 같다.

 

Vault Crypto-Key mechanism

“Encryption-Key”는 “Secret”을 안전하게 암/복호화한다. “Secret”들은 “Storage backend”에 보관하며, “Secret”에 접근하기 위해서는 REST API를 사용한다. REST API는 Create, Register, Rotate, Destroy 등의 명령을 제공하며, "Secret"을 제어할 수 있다. REST API를 사용하기 위해서는 "토큰 인증"과 "토큰에 상응하는 정책 인가" 작업이 필요하다. 

 

[고가용성]

Vault는 HA를 구성할 수 있다. HA의 구조는 Active-Standby 구조이다. 오픈 소스 버전의 경우 Standby는 Read-Only 기능을 제공하지 않는다. Standby에 요청이 들어오면 요청을 Active에 포워딩한다. Read-Only 기능은 엔터프라이즈에서 제공한다. 그래도 오픈 소스 버전에서 Hot-Standby를 제공하기 때문에 Failover는 문제없다. 제일 큰 단점은 Standby의 read-only의 미지원이다. Product 레벨에서 Vault를 사용하기 위해서는 해당 기능이 제일 필요할 것 같다.

 

Replication 방식은 PostgreSQL의 방식과 같이 Active-Standby 구성이며, Active의 변경/추가/삭제된 것에 대한 로그(WAL, Write Ahead Log) Standby에 전송한다. 데이터 처리에 있어 보통의 DBMS과 같이 WAL 기법을 사용하는 것 같다.

 

[보안 특성]

  • Vault와 클라이언트 상호 인증은 제공하지 않는다. 다만 서버에서 제공하는 네트워크 계층 보안, TLS를 제공한다.
  • 정상 토큰을 보유한 주체는 리소스("Secret")에 접근할 수 있다.
  • 토큰 인가 정책은 리소스에 접근하는 주체를 제어한다.
  • Secret에 접근하는 모든 행위를 감사 로깅한다.
  • "Secret"을 암호화하여 Storage Backend에 저장한다.
  • Vault의 Barrier를 통과하는 모든 요청과 반환은 AES-256(GCM)으로 암호화한다. IV의 경우, 자동으로 임의로 생성한다.
  • SSS(Shamir Secret Sharing) 알고리즘으로 MasterKey를 분리 보관한다.

 

[Key 회전(갱신)]

rekey 명령은 Unsealed-KeyMaster-Key를 갱신한다. 갱신된 Master-KeyEncryption-Key를 재암호화하며,갱신된 Unsealed-Key SSS에 의해 다시 분리하여 보관하여야 한다. 

rotate 명령은 Encryption-Key를 갱신한다. 기존 Encryption-Key는 별도의 keyring에 보관한다. 후의 요청들은 새로운 Encryption-Key로 암호화를 한다. Keyring에 있는 Encryption-Key는 복호화 용도에만 사용한다. 이와 같이 사용하면 re-encryption을 수행하지 않아도 괜찮다(keyring에 예전 Encryption-Key를 다 보관하고 있다. 갱신에 의미가 있나?).

 

[정책]

사용자는 Identifier/Authentication값을 요청한다. 요청 성공 시 토큰을 반환받는다. 해당 토큰은 다음과 같이 화이트 리스트 정책을 갖고 있다

# This section grants all access on "secret/*". Further restrictions can be
# applied to this broad policy, as shown below.
path "secret/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
 
# Permit reading secret/foo/bar/teamb, secret/bar/foo/teamb, etc.
path "secret/+/+/teamb" {
  capabilities = ["read"]
}
 
# Policies can also specify allowed, disallowed, and required parameters. Here
# the key "secret/restricted" can only contain "foo" (any value) and "bar" (one
# of "zip" or "zap").
path "secret/restricted" {
  capabilities = ["create"]
  allowed_parameters = {
    "foo" = []
    "bar" = ["zip", "zap"]
  }
}
 

 

Posted by 동팡