vault server -dev ==> Vault server configuration: Api Address: http://127.0.0.1:8200 Cgo: disabled Cluster Address: https://127.0.0.1:8201 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: info Mlock: supported: false, enabled: false Recovery Mode: false Storage: inmem Version: Vault v1.3.0 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 variable: PowerShell: $env:VAULT_ADDR="http://127.0.0.1:8200" cmd.exe: set VAULT_ADDR=http://127.0.0.1:8200 The unseal key and root token are displayed below incase you want to seal/unseal the Vault or re-authenticate. Unseal Key: apvm8OuIQeMHgtstu2PB5r7oFkJyyuPTtlz4yxFHa9Y= Root Token: s.15QsYBSzASsEbHifZrmIMWBH Development mode should NOT be used in production installations! ==> Vault server started! Log data will stream in below:
-dev
미리 준비된 설정으로 서버를 구동
모든 데이터는 in-memory 저장
암호화
localhost 로 listen 되며 TLS 가 없음
자동 봉인 해제
봉인 해제된 키와 엑세스 토큰을 보여줌
프로덕션 모드에서는 이 옵션 사용을 권장하지 않음.
환경변수 등록
vault CLI 를 사용하기 위해 환경변수 등록이 필요합니다.
1
export VAULT_ADDR='http://127.0.0.1:8200'
서버 구동시 출력된 도움말을 읽으면 도움이 될수있습니다.
실행된 서버의 상태를 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12
$ vault status Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 1 Threshold 1 Version 1.3.0 Cluster Name vault-cluster-a6999d5c Cluster ID 291371dc-e6a5-42d3-fca7-b2373ff70194 HA Enabled false
vault 와 secret
vault 의 핵심 기능중 하나는 비밀정보를 안전하게 읽고 쓰는것입니다. vault 에 기록된 비밀정보는 암호화하여 backend 저장소에 저장됩니다. 값을 저장소에 전달하기 전에 암호화를 하며, backend 저장소에 저장된 암호화값은 vault 없이는 해독할 수 없습니다.
write a secret
비밀정보를 작성해봅니다.
1 2 3 4 5 6 7
$ vault kv put secret/hello foo=world Key Value --- ----- created_time 2019-11-26T02:39:20.8458832Z deletion_time n/a destroyed false version 1
key 값의 접두사가 secret/ 여야만 저장이 됩니다. 이 접두사(경로)는 어떤 secrets engine 을 실행시킬지 결정하는 route 역할을 합니다.
비밀정보를 기록할때는 shell history 에 남기때문에 되도록이면 file 을 통해서 전달될수있도록 하는것이 좋다고 합니다.
getting a secret
비밀정보를 획득해봅니다.
1 2 3 4 5 6 7 8 9 10 11 12 13
$ vault kv get secret/hello ====== Metadata ====== Key Value --- ----- created_time 2019-11-26T02:39:20.8458832Z deletion_time n/a destroyed false version 1 === Data === Key Value --- ----- foo world
vault 는 저장소로부터 값을 가져올때 복호화하여 가져옵니다. 여러가지 메타 데이터가 함께 반환됨을 확인할 수 있습니다.
이 설정은 wook/ 접두사로 시작되는 경로는 kv 엔진을 사용한다 라는 의미입니다. 실제로 그런지 secrets list 를 확인해보면 알 수 있습니다.
1 2 3 4 5 6 7 8
$ vault secrets list Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_9e279c40 per-token private secret storage identity/ identity identity_8959bd02 identity store secret/ kv kv_e56557df key/value secret storage sys/ system system_dbd69f9d system endpoints used for control, policy and debugging wook/ kv kv_e01b755a n/a
이제 임의로 지정한 경로를 통해 secrets engine 을 활용한 데이터를 기록하고 확인해봅니다.
1 2 3 4 5
$ vault write wook/hello name=wook Success! Data written to: wook/hello $ vault write wook/pc cpu=amd Success! Data written to: wook/pc
1 2 3 4 5
$ vault list wook Keys ---- hello pc
secrets engine 비활성화
secrests engine 에 연결된 임의의 경로를 비활성화 시킬수도 있습니다.
1 2
$ vault secrets disable wook/ Success! Disabled the secrets engine (if it existed) at: wook/
비활성화 이후에는 wook/ 경로를 더이상 확인할 수 없는것을 볼수있습니다.
1 2
$ vault list wook No value found at wook/
1 2 3 4 5 6 7
$ vault secrets list Path Type Accessor Description ---- ---- -------- ----------- cubbyhole/ cubbyhole cubbyhole_9e279c40 per-token private secret storage identity/ identity identity_8959bd02 identity store secret/ kv kv_e56557df key/value secret storage sys/ system system_dbd69f9d system endpoints used for control, policy and debugging
다른 환경과 연동
vault 에서 제공하는 secrets engine 를 활용하여 read / write 와 같이 추상화된 인터페이스를 통해 다른 환경과 연동이 가능합니다.
예를 들면
dynamic SQL user creation
AWS IAM
등…
앞으로 등장할 내용은 정적 비밀정보 처리가 아닌 동적 처리방식을 다룹니다.
dynamic secrets (동적 비밀정보)
앞절에서 소개드린 kv 는 vault 가 기본적으로 제공하는 비밀정보 관리 도구입니다. 정적인 데이터를 다루는데 자주 사용했지만, 이것이 vault 의 핵심기능의 전부는 아닙니다.
dynamic secrets 는 kv 와 달리 엑세스 시점에 비밀정보가 생성됩니다. 즉, 엑세스 전까지는 비밀정보가 존재하지 않는다는 말입니다. 그래서 서로 다른 클라이언트간에 비밀정보 탈취에 대한 염려가 없습니다. 또한 vault 에는 사용 이후 dynamic secrets 을 해지하는 메커니즘이 내장되어있습니다. 따라서 비밀정보 유지기간을 최소화 하고 있습니다.
정리하자면, 본래 secret 정보를 app 자체가 갖고있거나 외부 저장소로부터 획득하여 사용했다면, vault 를 사용할 경우 secret 정보를 동적으로 생성하고 app 은 이를 사용하다가 필요가 없을경우 폐기 또는 vault 에 의해서 스스로 삭제될수있다고 할수있습니다. app 은 secret 정보가 필요할때마다 vault 를 이용하면 됩니다.
AWS secret 테스트
vault 를 활용해 AWS 의 IAM 유저를 동적으로 생성해보겠습니다. :star:테스트 전에 AWS 에 가입하여 root key 를 확보해두셔야 합니다.
저는 두번의 실행을 통해 IAM 유저 2개를 등록했습니다. AWS 의 IAM 을통해 생성된 유저를 확인할 수 있습니다.
secret 갱신 & 획득
lease_id 를 통해 client 는 secret 을 갱신함과 동시에 재획득이 가능합니다.
1 2 3 4 5 6 7 8 9 10 11
$ vault lease renew aws/creds/my-role/0bce07---------ff22106e WARNING! The following warnings were returned from Vault: * TTL of "768h0m0s" exceeded the effective max_ttl of "751h47m55s"; TTL value is capped accordingly Key Value --- ----- lease_id aws/creds/my-role/0bce07---------ff22106e lease_duration 751h47m55s lease_renewable true
$ vault write database/roles/my-role \ db_name=my-mysql-database \ creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" \ default_ttl="1h" \ max_ttl="24h" Success! Data written to: database/roles/my-role
# 토큰 생성 $ vault token create Key Value --- ----- token s.mTG4kSzyKbQjiGhq1cEMFqFs token_accessor n7KOg3SDRiIZq6xlsgQbWW9m token_duration ∞ token_renewable false token_policies ["root"] identity_policies [] policies ["root"] # 인증 $ vault login s.mTG4kSzyKbQjiGhq1cEMFqFs 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 s.mTG4kSzyKbQjiGhq1cEMFqFs token_accessor n7KOg3SDRiIZq6xlsgQbWW9m token_duration ∞ token_renewable false token_policies ["root"] identity_policies [] policies ["root"]
:warning: 실제로 운영자가 이렇게 토큰을 사용하여 클라이언트에 지급하는것은 좋지 못하다고 합니다. 따라서 다양한 인증 방식을 통해 토큰을 발행받아 사용하는 방식을 제공하고 있습니다.
다양한 인증 방식
vault 는 제 3 서비스가 제공하는 방식을 통해 인증을 처리할수도 있습니다.
github 인증 테스트
github 의 organization 및 개별 token 을 활용한 인증 방식을 테스트 합니다.
인증 범위는 github 의 lighten518-til 조직(github 에서 만든) 내의 유저로 설정합니다. 그 다음 명령어는 my-team 의 모든 사용자에게 default 와 my-policy 정책을 매핑하게 합니다.
:star:아직 my-policy 정책에 대한 정보를 구성하지 않았으므로 정책에 대하서는 여기서는 일단 무시하셔도 좋습니다
1 2 3 4 5
$ vault write auth/github/config organization=lighten518-til Success! Data written to: auth/github/config $ vault write auth/github/map/teams/my-team value=default,my-policy Success! Data written to: auth/github/map/teams/my-team
등록된 인증 확인
1 2 3 4 5
$ vault auth list Path Type Accessor Description ---- ---- -------- ----------- github/ github auth_github_588abfc9 n/a token/ token auth_token_e9c048f1 token based credentials
인증
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
$ vault login -method=github token=e5f6ecb31---------f2b43f181f2 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 s.1Gzm----gJa7qlW5 token_accessor 3g7h8px---UKiVMQXzsMO token_duration 768h token_renewable true token_policies ["default"] identity_policies [] policies ["default"] token_meta_org lighten518-til token_meta_username lejewk
:heavy_check_mark: vault 에 로그인 되었습니다!
이어서 policy(정책) 에 대해 보겠습니다.
polices (정책)
정책이란 vault 에 로그인한 유저가 어떤 기능을 사용할수있느냐를 정의하는것입니다. 이것을 Authorization (인가) 에 대한 부분으로 인지하셔도 좋습니다. 인증은 각각의 인증방법(github, 기타 등등…) 에 따라가고, 인가는 vault 가 정의한 정책에 매핑합니다.
# Normal servers have version 1 of KV mounted by default, so will need these # paths: path "secret/*" { capabilities = ["create"] } path "secret/foo" { capabilities = ["read"] } # Dev servers have version 2 of KV mounted by default, so will need these # paths: path "secret/data/*" { capabilities = ["create"] } path "secret/data/foo" { capabilities = ["read"] }
secret/ 의 모든 경로에 쓰기가 가능하지만 secret/foo 는 읽기만 가능하다 라는 정책입니다.
:star: vault 는 경로 기반 secrets engine 사용 패턴이므로 경로에 대해서 정책을 정하여 엄격하게 관리할 수 있습니다.
fmt
vault 는 policy 의 포맷에 대해 체크해주며 오류 발생시 error를 발생해주는 도구가 있습니다.
$ vault policy read my-policy # Normal servers have version 1 of KV mounted by default, so will need these # paths: path "secret/*" { capabilities = ["create"] } path "secret/foo" { capabilities = ["read"] } # Dev servers have version 2 of KV mounted by default, so will need these # paths: path "secret/data/*" { capabilities = ["create"] } path "secret/data/foo" { capabilities = ["read"] }
$ vault login s.vchcnwzB3pI55ja711oaXCwB 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 s.vchcnwzB3pI55ja711oaXCwB token_accessor SK2qM9OsvruupUlobYL5YBj0 token_duration 767h59m47s token_renewable true token_policies ["default""my-policy"] identity_policies [] policies ["default""my-policy"]
kv 쓰기 테스트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
$ vault kv put secret/test name=wook Key Value --- ----- created_time 2019-11-27T07:45:44.5049062Z deletion_time n/a destroyed false version 1 # foo 는 쓰기에 대한 권한이 없어 실패 $ vault kv put secret/foo age=10 Error writing data to secret/data/foo: Error making API request. URL: PUT http://127.0.0.1:8200/v1/secret/data/foo Code: 403. Errors: * 1 error occurred: * permission denied
deploy vault
배포 환경에서는 어떻게 설정되야할까요? 개발모드에서는 -dev 를 통해 미리 준비된 설정을 사용했다면, 이제는 직접 설정을 구성하여 vault 를 실행해야 합니다.
storage 는 vault 의 데이터를 저장할 backend 를 지정합니다. consul 을 지정했고 따라서 consul agent server 가 동작되야 합니다. https://www.consul.io/ 참고
listener 는 vault 의 API 를 사용할 endpoint 로 보시면 됩니다.
개발 테스트이므로 환경변수에 vault 주소를 등록해주셔야 합니다.
1
export VAULT_ADDR=http://127.0.0.1:8200
server start with config.hcl
먼저 consul 을 실행시킵니다.
1
consul agent -dev
이후 vault 를 설정파일과 함께 실행합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
$ vault server -config=config.hcl WARNING! mlock is not supported on this system! An mlockall(2)-like syscall to prevent memory from being swapped to disk is not supported on this system. For better security, only run Vault on systems where this call is supported. If you are running Vault in a Docker container, provide the IPC_LOCK cap to the container. ==> Vault server configuration: Api Address: http://127.0.0.1:8200 Cgo: disabled Cluster Address: https://127.0.0.1:8201 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: info Mlock: supported: false, enabled: false Recovery Mode: false Storage: consul (HA available) Version: Vault v1.3.0 ==> Vault server started! Log data will stream in below:
vault 초기화
-dev 모드와 다르게 vault 를 사용하려면 초기화가 필요합니다. :warning: 초기화 없이 cli 를 사용하게 될경우 봉인 오류가 발생됩니다.
1 2 3 4 5 6 7
$ vault kv put secret/wook a=b Error making API request. URL: GET http://127.0.0.1:8200/v1/sys/internal/ui/mounts/secret/wook Code: 503. Errors: * Vault is sealed
초기화는 backend 서버가 시작된 경우 1회만 실행하면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
$ vault operator init Unseal Key 1: 6VoUsGk140OnDi2Z3OcXBJyr/cS3Zv+gnAGDOteiOeFO Unseal Key 2: 4wrk+3AX7Z39BKSZcAsGNO+5Zsn1s4MjWK/2N5o0Tc7U Unseal Key 3: HIqhJ9p5rRaYjN8Rjhm6bDMO+zVlyy3Tc2HD+0MeY6dJ Unseal Key 4: hkmXS/d6Wdmg4xkyJVLlWJP8L8uEKhmKbOH0nOm1PNfE Unseal Key 5: /GJp/G+7aoMjTqarPqmxYtN+oSEw38C4kWZNQNuw6zsf Initial Root Token: s.eRWvoMPfKdxk2ja7kqIlSuR6 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.
:star:이때 생산된 봉인 해제키와 루트 토큰을 잘 갖고 계셔야합니다. 이 키또한 관리대상이므로 vault’s PGP 또는 keybase.io 를 활용한다고 합니다.
sear / unseal (봉인 / 해제)
초기화된 모든 vault 서버는 봉인된 상태로 시작합니다. vault 는 물리서버에 접근할수있으나 해독 방법을 모르기때문에 데이터를 읽을수는 없습니다. vault 가 데이터를 해독하는 방법을 가르치는 과정을 vault unseal 이라고 합니다.
vault 가 시작될때마다 unseal 을 해야합니다. 이 과정은 API 와 CLI 를 통해 수행할 수 있습니다.
unseal 을 하려면 임계값 개수(최소) 의 unseal key 를 소유하고 있어야 합니다. (3개) Vault initialized with 5 key shares and a key threshold of 3
첫번째 해제
1 2 3 4 5 6 7 8 9 10 11 12
$ vault operator unseal 6VoUsGk140OnDi2Z3OcXBJyr/cS3Zv+gnAGDOteiOeFO Key Value --- ----- Seal Type shamir Initialized true Sealed true Total Shares 5 Threshold 3 Unseal Progress 1/3 Unseal Nonce 0195ceed-69fd-dd26-cb82-604952a572ae Version 1.3.0 HA Enabled true
두번째, 세번째 해제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
$ vault operator unseal hkmXS/d6Wdmg4xkyJVLlWJP8L8uEKhmKbOH0nOm1PNfE $ vault operator unseal 4wrk+3AX7Z39BKSZcAsGNO+5Zsn1s4MjWK/2N5o0Tc7U Key Value --- ----- Seal Type shamir Initialized true Sealed false# <-- false 로 해제됨을 확인 가능 Total Shares 5 Threshold 3 Version 1.3.0 Cluster Name vault-cluster-6075fd5f Cluster ID c08caafe-09e6-c546-3216-b30a5d289ece HA Enabled true HA Cluster n/a HA Mode standby Active Node Address <none>
authentication (인증)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
$ vault login s.eRWvoMPfKdxk2ja7kqIlSuR6 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 s.eRWvoMPfKdxk2ja7kqIlSuR6 token_accessor OcjXZLaLlkAIO9cyZj8eRrMZ token_duration ∞ token_renewable false token_policies ["root"] identity_policies [] policies ["root"]