ecsimsw
Vault hands-on, 가장 기본적인 기능들 본문
Vault 시작하기
Vault의 가장 기본적인 기능들을 소개한다.
0. Vault dev server 실행
1. Secret Engine의 개념과 Secret 생성
2. Seal / Unseal
3. Auth engine / Auth method
4. Policy로 접근 가능 리소스, 액션 제한
5. Entity, 여러 인증 방식을 사용자로 묶어 관리
6. Group, 여러 Entity를 집합으로 관리
0. 간단한 Dev server 실행
Dev server 설치가 간단해서 로컬에서 먼저 테스트해 보기 좋다. 실 서버는 정책이나 설정, Audit을 저장할 저장소가 필요하지만 개발 서버는 인 메모리로 실행되어 Vault 외 준비할 것들이 없다.
1. vault 설치
brew tap hashicorp/tap
brew install hashicorp/tap/vault
2. 개발 모드로 서버 활성화
vault server -dev
3. 서버를 실행하면 아래와 같은 설정 상태가 출력된다.
==> Vault server configuration:
Api Address: http://127.0.0.1:8200
Cgo: disabled
Cluster Address: https://127.0.0.1:8201
Environment Variables: GODEBUG, HOME, HOMEBREW_CELLAR, HOMEBREW_PREFIX, HOMEBREW_REPOSITORY, INFOPATH, JAVA_HOME, LC_CTYPE, LOGNAME, LaunchInstanceID, MANPATH, OLDPWD, PATH, PWD, SECURITYSESSIONID, SHELL, SHLVL, SSH_AUTH_SOCK, TERM, TERM_PROGRAM, TERM_PROGRAM_VERSION, TERM_SESSION_ID, TMPDIR, USER, XPC_FLAGS, XPC_SERVICE_NAME, _, __CFBundleIdentifier
Go Version: go1.20.1
Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
Log Level:
Mlock: supported: false, enabled: false
Recovery Mode: false
Storage: inmem
Version: Vault v1.13.1, built 2023-03-23T12:51:35Z
Version Sha: 4472e4a3fbcc984b7e3dc48f5a8283f3efe6f282
The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.
Unseal Key: Nt/l0dkyduoT1PFZO2iu3eK5ZIJa0/OGFfKTca5NOxE=
Root Token: hvs.3GA3ysUB88mj8mf7ZC5Fh4AS
Development mode should NOT be used in production installations!
이 중 기억해야 할 값은 Api Address, Unseal key, Root token이다. Api address는 Vault 서버 요청 주소가 되고, Unseal key는 Vault를 Seal/Unseal 할 때 사용되는 키 값이 된다. Root token은 모든 Vault의 메인 권한이 된다. 은행장을 인증할 방법이라고 생각하면 된다.
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_DEV_ROOT_TOKEN_ID=hvs.3GA3ysUB88mj8mf7ZC5Fh4AS
우선 최초 설정을 위해 ROOT_TOKEN으로 Vault를 접속한다.
4. Check status
vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.13.1
Build Date 2023-03-23T12:51:35Z
Storage Type inmem
Cluster Name vault-cluster-d2f82bdf
Cluster ID 06cf1ff5-cd73-4c2a-73a1-3823b47c2306
HA Enabled false
이렇게 Vault 설치가 끝났다. 이제 이 개발 모드로 Vault를 먼저 테스트할 수 있다.
5. Vault GUI
Vault는 GUI를 제공한다. 관리자 설정을 할 때나 처음 사용법을 익힐 때는 GUI가 편할 것 같다. `http://127.0.0.1:8200`으로 접속하면 로그인을 요구할 텐데 처음 초기 설정에선 root token으로 접속한다. 재밌는게 root token 은 브라우저에 저장 자체를 안 해서 매번 접속마다, 새로고침마다 토큰을 입력해줘야 한다.
1. Secrets Engines / Secret
Vault에 비밀 키를 저장해 볼 것이다. Vault는 다양한 형태의 키 저장을 제공한다. 실습에선 Key:Value 값을 저장한다.
1-1. Create Scecret engine
어떤 시크릿 형태를 저장할지 선택한다.
예시로는 KV 형태의 시크릿을 담는 Secret engine을 생성했다.
Type : KV
EngineName : onboarding/test
VersionCode : v2
1-2 SecretEngine에 Secret을 저장한다.
onboarding/test를 path로 secretEngine에 두 개의 Secret을 저장해 보았다.
1-3 이번에는 vault CLI 툴로 'onboarding/test'에 생성한 KV list를 출력해 본다.
vault kv list onboarding/test
Keys
----
MyPasswordList
MyPersonalInfo
1-4. 키 'MyPersonalInfo'에 해당하는 값을 가져온다.
vault kv get onboarding/test/MyPersonalInfo
=========== Secret Path ===========
onboarding/test/data/MyPersonalInfo
======= Metadata =======
Key Value
--- -----
created_time 2023-04-18T08:09:06.704805Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
======= Data =======
Key Value
--- -----
Age 99
Name Jinhwan
NickName ecsimsw
PhoneNumber 01012341234
2. Seal / Unseal
Seal / Unseal로 Vault 접근 전체를 봉인하고 풀 수 있다.
vault operator seal
루트 권한으로 Seal 하면 Vault의 모든 권한이 무효된다. Root 권한조차 어떤 값도 읽어 올 수 없다.
Unseal은 Vault를 처음 실행시켰을 때 출력되는 unseal 키로 해제할 수 있다. 더 나아가면 unseal 키를 여러 개 생성하고 지정 개수 이상의 키 입력이 되었을 때만 unseal 할 수 있도록 설정할 수 있다. 예를 들어 이 값을 5 / 3으로 하게 되면 5개의 unseal 키가 생성되어 다섯 명의 관리자에게 뿌려지고 unseal 하고 싶을 때는 이 다섯 명의 관리자 중 3명이 이상이 본인 unseal 키를 입력하여 해제를 동의한 후에나 unseal이 가능하게 된다.
vault operator unseal
3. Auth method
이번에는 Vault 인증 방식을 정의하려고 한다. Github auth engine을 생성한다는 얘기는 사용자가 Github 토큰으로 Vault를 인증할 수 있다는 말이 된다.
Access → Auth methods에서 새로운 인증 방식을 생성한다.
여러 인증 방식을 제공한다. 내 경우에는 아마 Github 토큰이나, Kubernetes SA를 이용한 인증을 가장 많이 사용할 것 같다. 예시에서는 Username & Password 방식을 이용하려 한다.
이렇게 만든 인증 방식은 auth-engine에 저장된다. 예시에선 auth-engine의 ‘users’ path를 생성했다. Secret-engine 이랑 방식이 똑같다. 저장하려는 데이터/인증 타입으로 XXX-engine을 path로 만들고 그 아래 데이터/인증을 쌓는 식이다.
앞서 생성한 username/password로 vault에 인증할 수 있다.
vault login -method=userpass username=ecsimsw -path=users
4. Policy
접근할 수 있는 리소스들, 실행할 수 있는 액션, key retation period 등을 정책으로 만들 수 있다. hcl format을 사용한다. https://developer.hashicorp.com/vault/docs/concepts/policies
4-0. Policy 생성
vault policy write policy-name {policy-file.hcl}
4-1. Policy 예시 1
‘onboarding-test-list’를 정의했다. 'onboarding/test' secret engine에 하위에 정의된 secret 리스트를 조회할 수 있도록 한다.
path "onboarding/test/*" {
capabilities = ["list"]
}
이 정책을 사용하는 유저는 아래와 같이 onboarding/test 아래 secret 목록은 확인할 수 있지만 그 secret 내부를 읽을 순 없다.
4-2. Policy 예시 2
‘onboarding-test-mypersonalinfo-readonly’을 정의했다. onboarding/test의 Secret 중 MyPersonalInfo라는 Secret만 read와 list 권한을 부여한다.
path "onboarding/test/data/MyPersonalInfo" {
capabilities = ["read", "list"]
}
path에 secretEngine path(onboarding/test)와 secret name(MyPersonalInfo) 사이에 'data’가 추가된 이유는 해당 secretEngine이 KV version2 타입이기 때문이다. (https://developer.hashicorp.com/vault/docs/secrets/kv/kv-v2)
4-3. 생성된 정책
생성된 정책 목록은 다음과 같다.
이 두 정책이 동시에 추가된 유저의 경우 onboarding/test 아래 secret 들은 목록을 조회할 수 있으면서, 그 값을 읽을 수 있는 것은 onboarding/test/MyPersonalInfo 뿐이 되는 것이다.
4-4. TIP :: This most specific path will win!
If you have two paths: secret/* and secret/abc/* in the same policy and try to interact with secret in path secret/abc/123, then the capabilities in the latter path will apply.
5. Entity로 인증 방식 묶기
한 사람이 여러 인증 방식을 가질 수 있다. A라는 사람이 Vault 인증을 github과 username 방식 둘 다를 사용하고자 하는 상황을 대비한다. 물론 하나의 토큰으로 관리되는 상황이 가장 좋겠지만 당장 여러 인증 방식을 사용하고 있는 서비스에서 한 번에 Vault 하나의 인증 방식으로 바꾸기 보다 기존에 사용하던 방식 유지와 동시에 이 여러 인증 방식들을 묶은 vault 유저 하나를 만들어 공존할 수 있도록 하려 한다.
5-1. Entities
Vault에 테스트 세 auth-method를 준비했다. 모두 다른 방식의 인증 방식이지만 다 나를 부르는 다른 이름들이다. 각 이름으로 어디에서 사용되는지, 누가 사용하는지 한번에 확인하기 어렵다. 이를 묶고 규칙 있는 이름으로 부르고 싶다. (ex, 사번, 실명 등)
User로 Vault에 최초 로그인 시 Entity가 생성된다. 현재는 각각의 인증 방식이 모두 하나의 Entity로 사용되고 있는 상황이다.
5-2. Create Entity
아래처럼 Entity를 생성한다. Name을 Vault 사용자 공통의 규칙으로 작성하는 것을 추천한다. 예시의 경우 영문 성+이름을 규칙으로 했고 Policy로 해당 Entity에게 부여할 권한 정책을 추가해 주었다. MetaData는 Tag 개념으로 Team을 표시했다.
5-3. Merge entities
미리 생성되었던 세 개의 서로 다른 entity (ecsimsw, jinhwan, nick)을 방금 생성한 하나의 entity(KimJinHwan)에 merge 하려고 한다. KimJinHwan에 정의된 Name과 Policies, MetaData로 나머지 세 인증 방식을 합칠 수 있다.
merge 후 entity 목록은 다음과 같다. 인증 방식마다 따로 존재하던 entity들이 KimJinHwan의 aliases로 포함되었다. 포함된 인증 방식은 모두 같은 Entity에 속하게 되므로 KimJinHwan의 정책과 MetaData를 따르게 된다. merged 된 인증 방식으로 기존에 KimJinHwan에 추가했던 정책을 따라 권한이 생긴 것을 확인할 수 있다.
6. Group으로 사용자 묶기
6-0. 여러 Entity를 Group으로 묶어 관리할 수 있다.
한 사람이 여러 인증 방식을 갖는 것을 Entity로 묶어 관리하였다. 이번에는 여러 사람을 Group으로 묶어 관리될 수 있도록 한다.
위 Entity에서 June, Juan은 DevOps 팀, Nancy, Jean, Eric은 Backend 팀, Nick은 두 팀 모두에 속하도록 설정할 것이다.
6-1. Group 예시
‘Team-DevOps’로 Group을 생성한다.
Entity 생성과 마찬가지로 Group 전체에 추가할 정책과 MetaData, 그룹에 포함될 멤버를 선택한다. 두 그룹에 Policy 정의된 대로 멤버들이 권한을 갖게 된다.
6-2. 두 그룹에 공통으로 포함된 유저는 어떻게 권한을 갖게 될까
공통으로 포함된 유저는 본인에게 적용된 모든 정책에 capabilities로 allow 된 합집합에 대한 권한을 갖게 된다. 위 예시에서 Nick이 모든 액션이 가능한 Team-DevOps와 읽기 액션만 가능한 Team-Backend에 공통으로 포함되었다고 하면 예시의 Nick은 Team-DevOps를 따라 모든 권한이 부여된다.
단, ‘Deny’가 ‘Allow’ 보다 더 우선순위가 높다. Team-DevOps에 allow 권한이 있다고 하더라도 아래와 같이 Team-Backend에 deny 정책이 있다면 Nick은 해당 Secret을 접근할 수 없게 된다. (AWS의 IAM Policy의 정책과 같다.)
path "devops/data/AWS_CREDENTIALs" {
capabilities = ["deny"]
}
'Architecture > Infrastructure' 카테고리의 다른 글
Kubernetes apt repository updated : NO_PUBKEY B53DC80D13EDEF05 (0) | 2023.06.06 |
---|---|
Vault Dynamic secret 으로 AWS 키를 보다 안전하게 관리하는 방법 (0) | 2023.04.25 |
AWS 자원 생성 시 태깅을 강제하는 IAM Policy (0) | 2023.03.13 |
Route53의 private hosted zone으로 내부 서비스 도메인 관리하기 (0) | 2023.01.15 |
리버스 프록시 부하분산 개념과 시연 (2) | 2022.06.17 |