본문 바로가기
클라우드

Vault 암호화 관리 시스템 개념, Transit Secret Engine 예제

by 정권이 내 2024. 3. 25.

Vault, 암호화 관리 시스템

 

Vault 기본 개념

img

Vault는 비밀 및 암호화 관리 시스템으로, 안전하고 제한된 액세스를 제공합니다.

사용자, 기계, 앱 등의 클라이언트를 인증하고 권한을 부여하여 비밀 및 민감한 데이터에 접근할 수 있도록 합니다. 이는 통합된 인터페이스를 통해 모든 비밀에 엄격한 액세스 제어와 자세한 로그를 제공합니다.

 

Vault Workflow

img

  • 인증(Authenticate): 볼트에서 인증은 클라이언트가 제공한 정보를 사용하여 인증하는 과정입니다. 클라이언트가 인증되면 토큰이 생성되고 해당 토큰은 정책과 연결됩니다.
  • 검증(Validation): 볼트는 클라이언트를 Github, LDAP, AppRole 등과 같은 제3자 신뢰할 수 있는 소스에 대해 검증합니다.
  • 권한 부여(Authorize): 클라이언트의 권한은 볼트의 보안 정책으로 결정됩니다. 이 정책은 클라이언트의 Vault 토큰과 관련된 API 엔드포인트에 액세스할 수 있는 규칙을 정의하는 일련의 규칙입니다. 정책은 볼트에서 특정 경로 및 작업에 대한 액세스를 허용하거나 거부하는 선언적인 방법을 제공합니다.
  • 액세스(Access): 볼트는 클라이언트의 신원과 연결된 정책을 기반으로 토큰을 발급하여 비밀, 키 및 암호화 기능에 대한 액세스를 부여합니다. 클라이언트는 그들의 볼트 토큰을 사용하여 이후 작업을 수행할 수 있습니다.

 

Vault 설치

CentOS-8 환경에서 설치와 테스트를 진행하였습니다.

$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
$ sudo yum -y install vault

 

dev 서버 실행

vault server -dev

 

외부 접속을 허용하려면 다음 옵션을 추가하면 됩니다.

-dev-listen-address="0.0.0.0:8200"

 

Unseal Key / Root Koken 확인

dev 서버 실행시 Unseal key, Root Token 정보를 확인할수 있습니다.

WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.

You may need to set the following environment variables:

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

The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.

Unseal Key: xxxxxxxxxxxxxxx
Root Token: xxxxxxxxxxxxxxx

Development mode should NOT be used in production installations!

 

VAULT 환경변수 저장

터미널에서 Vault Client로 테스트를 하기위해 VAULT_ADDR, VAULT_TOKEN환경변수를 저장합니다.

$ export VAULT_ADDR='http://127.0.0.1:8200'
$ export VAULT_TOKEN="xxxxxxxxxxxxxxxxxx"

 

Vault 실행 확인

환경변수 설정이 완료되었으면 vault명령어로 Vault의 상태를 확인해볼수 있습니다.

$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.15.6
Build Date      2024-02-28T17:07:34Z
Storage Type    inmem
Cluster Name    vault-cluster-7c9c1e8b
Cluster ID      1c0d67a8-f040-0c82-a849-5d7a3c796ae2
HA Enabled      false

 

Secrets Engines

Secrets Engines은 데이터를 저장, 생성, 또는 암호화하는 Vault의 구성요소입니다. 이들은 역할에 따라 다양하게 분류되며, 일부는 데이터를 단순히 저장 및 읽기만 하고, 다른 일부는 동적 자격증명을 생성하거나, 암호화 서비스와 같은 기능을 제공합니다.

Vault에서 Secrets Engines은 가상 파일 시스템처럼 동작하여, 사용자가 읽기, 쓰기, 삭제 등의 작업을 수행할 수 있습니다.

아래설명에서 Secrets Engines는 편의상 암호엔진이라고 표현하겠습니다.

 

Secrets Engines Lifecycle

암호엔진의 라이프 사이클은 Enable, Disable, Move, Tune4가지가 있습니다.

  • Enable: 암호엔진을 활성화 하여 클라이언트나 API를 통해 해당 엔진을 사용할수 있게합니다. 활성화한 엔진의 기본 경로는 엔진의 타입명으로 지정되어 만약 aws를 활성화 했다면 aws/ 경로가 해당 엔진의 기본경로가 됩니다.
  • Disable: 암호엔진을 비활성화 하여 엔진의 설정정보나 저장된 데이터가 모두 폐기됩니다.
  • Move: 엔진의 지정된 경로를 변경하는 명령입니다. 기존 경로로 생성된 정보들은 모두 폐기되지만 설정정보는 보존됩니다.
  • Tune: 옵션으로 지정한 경로에 해당하는 암호 엔진의 설정정보를 변경합니다.

 

활성화된 암호엔진 목록은 vault secrets list명령으로 확인할수 있습니다. -detailed옵션을 추가하면 더 상세하게 확인할수 있습니다.

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_a986cae0    per-token private secret storage
identity/     identity     identity_ca1dc2ec     identity store
kv/           kv           kv_9ed35794           n/a
secret/       kv           kv_f6bcb37e           key/value secret storage
sys/          system       system_699ab2cc       system endpoints used for control, policy and debugging

 

Authentication, 증명

Vault를 사용하기 위해서는 가장 먼저 Authentication 단계를 거쳐야 하는데 터미널에서는 dev 서버 실행시 출력되는 root Token으로 볼트의 모든 서비스에 접근하여 사용할수 있고 새로운 토큰도 생성할수 있습니다.

일반적으로 볼트를 사용할때는 외부에서 Vault의 Auth Method API를 사용해서 자격증명을 얻은후에 볼트 서비스를 사용하기 때문에 root Token으로 토큰을 생성하여 터미널에서 작업하는 방식의 설명은 생략하겠습니다.

 

Auth Method

Auth Method는 유저에게 볼트 접속과 권한을 지정하는 방법입니다. 이 글에서는 Userpass 방식을 사용하여 예제를 진행하는데 그 외에도 AWS, Github 등 여러가지 방식에 대한 설명은 볼트 공식사이트에서 확인 하시기 바랍니다.

 

루트 토큰이 지정되있는 터미널에서 아래 명령어로 Auth Method를 활성화 하고 Userpass를 설정하겠습니다.

# Userpass 활성화
$ vault auth enable userpass

# Userpass 설정(id: ksr930, pw: 123qwe)
$ vault write auth/userpass/users/ksr930 password=123qwe

 

Auth Method를 설정할때 Policy(권한 정책)를 지정할수 있습니다. 아래 명령어는 my-policy라는 권한 정책을 지정하는 예제입니다.

$ vault write auth/userpass/users/ksr930 password=123qwe policies=my-policy

 

터미널에서 Userpass 방식으로 볼트에 로그인 해보겠습니다.

$ vault login -method=userpass username=ksr930
Password (will be hidden): 

WARNING! The VAULT_TOKEN environment variable is set! The value of this
variable will take precedence; if this is unwanted please unset VAULT_TOKEN or
update its value accordingly.

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                  xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
token_accessor         ZTyLcQOCr4c4rFTRgU7z8YHB
token_duration         768h
token_renewable        true
token_policies         ["default"]
identity_policies      []
policies               ["default"]
token_meta_username    ipron

ksr930 사용자에 대한 userpass 설정시 policies를 따로 지정하지 않았기 때문에 default 정책이 부여되었습니다. 참고로 default 정책으로는 볼트에 로그인하는것 외에는 대부분의 작업을 할수없으니 사용자에게 적절한 policies를 지정하는것은 중요합니다.

 

Policies, 권한 정책

Policies는 사용자가 접근 가능한 권한(Authorization)을 지정 하는것입니다. Authentication는 여러가지 Auth Method 방식으로 사용할수 있지만 Policies는 일정한 규칙이 있습니다.

 

Policy 문법

Policy 문법은 Json 형식과 호환되며 예제를 확인해보겠습니다.

path "transit/encrypt/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "transit/decrypt/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

위 Policy Format 의 내용은 Transit Secrets Engines 에 대한 권한입니다. 참고로 Transit 암호엔진은 사용자가 요청한 데이터를 암호화 하거나 암호화된 데이터를 복호화 해주는 엔진입니다.

사용자는 transit/encrypt/*, transit/decrypt/* 경로에 대해 "create", "read", "update", "delete", "list" 명령을 사용할수 있는 권한을 가지고 있는데 암호화, 복호화에 대한 읽기, 쓰기, 변경, 생성, 목록 확인과 같은 모든 기능을 사용할수 있습니다.

 

경로(path)에 대한 정책의 우선순위는 아래와 같이 결정됩니다.

  • 명시적인 경로 (transit/decrypt/)
  • 와일드카드 사용 (transit/*)

 

root, default권한은 기본 내장된 정책으로 삭제할수 없습니다.

  • default: 토큰을 사용하는 모든 유저들에게 제공되는 기본 정책
  • root: 루트 토큰을 사용하는 유저들에게만 제공되는 기본 정책 (Linux의 root user 개념)

 

Policy 작성

Policy 작성은 vault policy write명령어로 동작합니다.

 

Policy 파일 작성

$ vi transit-policy.hcl
path "transit/encrypt/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "transit/decrypt/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

 

작성한 파일로 Policy를 지정

$ vault policy write my-policy transit-policy.hcl
Success! Uploaded policy: my-policy

 

정책 목록을 확인하고 my-policy 정책 내용을 확인 해보겠습니다.

$ vault policy list
default
my-policy
root
$ vault policy read my-policy
path "transit/encrypt/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "transit/decrypt/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

 

Transit Secrets Engines, 암복호화

img

Transit Secrets Engines은 데이터를 암호화하고 복호화 하는데 사용하는 서비스입니다. Transit 엔진으로 암호화 되는 데이터는 볼트에서 저장하지 않으므로 서비스 자체로 암호화 기능을 수행합니다.

 

Transit 암호엔진을 활성화 하고 my-key라는 이름의 암호화 키를 만들어보겠습니다.

$ vault secrets enable transit
$ vault write -f transit/keys/my-key
Key                       Value
---                       -----
allow_plaintext_backup    false
auto_rotate_period        0s
deletion_allowed          false
derived                   false
exportable                false
imported_key              false
keys                      map[1:1710922767]
latest_version            1
min_available_version     0
min_decryption_version    1
min_encryption_version    0
name                      my-key
supports_decryption       true
supports_derivation       true
supports_encryption       true
supports_signing          false
type                      aes256-gcm96

 

이제 Encrypt Key를 사용해서 데이터를 암호화 하는데 이때 암호화 할 데이터인 plaintext 값은 반드시 base64로 인코딩된 값이어야 합니다.

vault write transit/encrypt/my-key plaintext=$(echo "my secret data" | base64)
Key            Value
---            -----
ciphertext     vault:v1:zSFSqPsjEBVuDDttT4SRPLoODerqAUlWJ+gj0QI21k7A5mruMD5X+9dRxw==
key_version    1

 

암호화된 데이터는 vault:v1:로 시작하는데 vault는 고정값이며 v1은 키 버전에 해당하는 텍스트 입니다.

암호화된 데이터를 다시 복호화 해보겠습니다.

$ vault write transit/decrypt/my-key ciphertext=vault:v1:zSFSqPsjEBVuDDttT4SRPLoODerqAUlWJ+gj0QI21k7A5mruMD5X+9dRxw==
Key          Value
---          -----
plaintext    bXkgc2VjcmV0IGRhdGEK

 

결과값이 base64로 인코딩된 값이 나오는데 디코딩까지 한번에 확인 해보겠습니다.

$ vault write -field=plaintext transit/decrypt/my-key ciphertext=vault:v1:zSFSqPsjEBVuDDttT4SRPLoODerqAUlWJ+gj0QI21k7A5mruMD5X+9dRxw== | base64 --decode

my secret data

 

반응형

댓글