Vault 맛보기

2019-09-17
  • vault
  • 공식 문서

    설치부터 해보자

    다운을 받자

    /tools/vault 폴더를 만들고 거기에 설치할 계획이다.
    docker 버전으로 기동을 한다고해도 vault cli 때문이라도 깔아놓자.

    #download vault 1.1.2
    $ wget https://releases.hashicorp.com/vault/1.1.2/vault_1.1.2_linux_amd64.zip
    $ mkdir /tools/vault
    $ unzip vault_1.1.2_linux_amd64.zip -d /tools/vault
    

    압축풀었으면 환경변수를 세팅하자.

    #setting vault path
    $ cd ~
    $ vim .bashrc
    
    #>>>>>>>>>>>>>> editor start
    export VAULT_HOME=/tools/vault
    export PATH=${VAULT_HOME}:${PATH}
    export VAULT_ADDR='http://127.0.0.1:8200'
    export VAULT_ROOT_TOKEN=''
    #<<<<<<<<<<<<<< editor end
    
    $ source .bashrc
    

    설치가 잘되었는지 vault cli 를 사용해보자

    #verifying the installation
    $ vault
    #set vault autocomplete to bash
    $ vault -autocomplete-install
    $ exec $SHELL
    

    개발모드란게 있지만..

    #run vault server dev mode
    $ vault server -dev
    

    사용해본적은 없다.

    운영모드로 세팅해보자

    config.hcl

    storage "file" {
      path = "/mnt/vault/data"
    }
    
    listener "tcp" {
      address = "0.0.0.0:8200"
      tls_disable = false
    }
    
    ui = true
    

    ui = true 옵션을 넣었기 떄문에 vault ui url = http://host.domain.name:8200/ui 에 접속했을 경우 웹 페이지가 나와야한다.

    세팅을 했으면 기동을 해보자

    • non-docker 버전으로 아래와 같이 실행을 하던지,
    $ vault server -config=config.hcl
    $ vault operator init
    
    • docker 버전으로 아래와 같이 실행을 하자.
    #config init
    $ docker run
     --cap-add=IPC_LOCK
     -e 'VAULT_LOCAL_CONFIG={"backend": {"file": {"path": "/vault/file"}}, "listener": {"tcp": { "address": "0.0.0.0:8200", "tls_disable": "true"}}, "ui": "true", "default_lease_ttl": "168h", "max_lease_ttl": "720h"}'
     -d
     -p 8200:8200
     --name=dev-vault
     docker.io/vault:1.1.2 server
    

    Unseal 을 해보자

    초기에 vault 가 실행되거나 재기동이 되면 sealed 상태가 되어 사용할 수 없게 된다.
    이때 사용할 수 있는 명령은 status, operator init 뿐인듯.
    unseal key 5개 중 아무거나 3개로 unseal 하여 사용하자.
    root key 는 잘 숨겨놓자.

    # 아래키는 여러번 실행해본 docker 버전의 vault 의 키 중 하나이다.
    Unseal Key 1: zmQlHaFap7yo/onSXDLGtzUQwz/cgNc3igd7dvSsPl9M
    Unseal Key 2: 0R1XXjz2szSJW3q05eapTs2ST6npYsHROHEr0l1aMyez
    Unseal Key 3: 5YwtvQcIP+VzX/TMkb0UDSaw+R9ZDftx3eDAmHn7Tn8Q
    Unseal Key 4: 45mBEZsh4dC71EUq2SXgC7owz3NFx04cqaQEMlDp1Yqo
    Unseal Key 5: HP18QROkknaL8ZAyMFfMZmBh/cxuKfUiq/Zx9nOlW8Bj
    
    Initial Root Token: s.syVRoWESdXjZU0iaPDXROlEv
    
    $ vault operator unseal
    Unseal Key (will be hidden):
    

    이제 설치 끝! 사용해보자

    secret engine 을 활성화 하자

    단순하게 사용할거니까 KV Secrets Engine 를 활성화 시킨다.
    버전이 두개가 있으므로 둘다 써보자.

    Version 1 과 Version 2 의 차이점은 K/V 의 버전 유무다. Version 2 는 K/V 셋의 버전을 관리해준다.

    $ vault secrets enable -version=1 -path=my-secret1 kv
    Success! Enabled the kv secrets engine at: my-secret1/
    
    $ vault secrets enable -version=2 -path=my-secret2 kv
    Success! Enabled the kv secrets engine at: my-secret2/
    

    활성화한 secret engine 에 데이터를 써보자

    Version 1 에선 read/write 또는 kv get/put명령어를 사용했지만, Version 2 에선 kv get/put 만 사용한다고 한다.

    먼저 version 1 부터

    $ vault write my-secret1/hello foo=bar
    Success! Data written to: my-secret1/hello
    
    $ vault read my-secret1/hello
    Key                 Value
    ---                 -----
    refresh_interval    168h
    foo                 bar
    
    $ vault write my-secret1/hello hello=world
    Success! Data written to: my-secret1/hello
    
    $ vault read my-secret1/hello
    Key                 Value
    ---                 -----
    refresh_interval    168h
    hello               world
    
    $ vault write my-secret1/hello foo=bar hello=world
    Success! Data written to: my-secret1/hello
    
    $ vault read my-secret1/hello
    Key                 Value
    ---                 -----
    refresh_interval    168h
    foo                 bar
    hello               world
    

    그 다음은 version 2

    $ vault kv put my-secret2/hello bar=foo
    Key              Value
    ---              -----
    created_time     2019-09-17T14:10:37.317296459Z
    deletion_time    n/a
    destroyed        false
    version          1
    
    # Version 1 과 달리 version 정보가 포함된 metadata 가 보인다
    
    $ vault kv get my-secret2/hello
    ====== Metadata ======
    Key              Value
    ---              -----
    created_time     2019-09-17T14:10:37.317296459Z
    deletion_time    n/a
    destroyed        false
    version          1
    
    === Data ===
    Key    Value
    ---    -----
    bar    foo
    
    $ vault kv put my-secret2/hello world=hello bar=foo
    Key              Value
    ---              -----
    created_time     2019-09-17T14:13:25.68859452Z
    deletion_time    n/a
    destroyed        false
    version          2
    
    # version 정보가 2로 올라간다.
    
    $ vault kv get my-secret2/hello
    ====== Metadata ======
    Key              Value
    ---              -----
    created_time     2019-09-17T14:13:25.68859452Z
    deletion_time    n/a
    destroyed        false
    version          2
    
    ==== Data ====
    Key      Value
    ---      -----
    bar      foo
    world    hello
    
    # version 을 명시하여 가져올 수 도 있다.
    
    $ vault kv get -version=1 my-secret2/hello
    ====== Metadata ======
    Key              Value
    ---              -----
    created_time     2019-09-17T14:10:37.317296459Z
    deletion_time    n/a
    destroyed        false
    version          1
    
    === Data ===
    Key    Value
    ---    -----
    bar    foo
    
    

    secret engine 비활성화

    $ vault secrets enable -version=1 -path=temp kv
    Success! Enabled the kv secrets engine at: temp/
    
    $ vault secrets disable temp
    Success! Disabled the secrets engine (if it existed) at: temp/
    

    TOKEN 을 사용해보자

    정책 파일 .hcl 작성

    .hcl 확장자는 Hashicorp Configuration Language 를 의미함

    Version 1Version 2 에 대한 다른 정책을 기반으로 다른 두 토큰을 만들 예정이므로, Version 1my-secret1/* 에 접근할 my-policy1.hclVersion 2my-secret2/* 에 접근할 my-policy2.hcl 을 만든다.

    my-policy1.hcl

    path "my-secret1/*" {
      capabilities = ["create", "read", "update", "delete", "list"]
    }
    

    my-policy2.hcl

    path "my-secret2/*" {
      capabilities = ["create", "read", "update", "delete", "list"]
    }
    

    정책파일을 업로드 한다.

    업로드 하기 전 정합성 체크를 한다.

    $ vault policy fmt my-policy1.hcl
    Success! Formatted policy: my-policy1.hcl
    
    $ vault policy fmt my-policy2.hcl
    Success! Formatted policy: my-policy2.hcl
    

    정합성이 확인된 파일로 my-policy 란 이름으로 정책을 만든다.

    $ vault policy write my-policy1 ./my-policy1.hcl
    Success! Uploaded policy: my-policy1
    
    $ vault policy write my-policy2 my-policy2.hcl
    Success! Uploaded policy: my-policy2
    

    만들어진 정책을 확인해본다.

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

    만든 정책으로 토큰을 발급해본다

    $ vault token create -policy=my-policy1
    Key                  Value
    ---                  -----
    token                s.Jb0UpJBV0bdtWYO8TxlDwphk
    token_accessor       V8cFQMqcGSJihrFDbIzkBBqG
    token_duration       168h
    token_renewable      true
    token_policies       ["default" "my-policy1"]
    identity_policies    []
    policies             ["default" "my-policy1"]
    
    $ vault token create -policy=my-policy2
    Key                  Value
    ---                  -----
    token                s.BnRO5kDRZTAHHRMvZIk8qwia
    token_accessor       90iSQdmmxhYSFaVq0CX4uSKb
    token_duration       168h
    token_renewable      true
    token_policies       ["default" "my-policy2"]
    identity_policies    []
    policies             ["default" "my-policy2"]
    

    발급한 토큰을 사용해보자

    1. 토큰 로그인
    2. 정책상의 경로로 write, kv put
    3. 정책상의 경로로 read, kv get
    4. 정책에 없는 경로로 read, kv get

    Version 1 부터 해본다.

    # 로그인
    $ vault login s.Jb0UpJBV0bdtWYO8TxlDwphk
    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.Jb0UpJBV0bdtWYO8TxlDwphk
    token_accessor       V8cFQMqcGSJihrFDbIzkBBqG
    token_duration       167h52m53s
    token_renewable      true
    token_policies       ["default" "my-policy1"]
    identity_policies    []
    policies             ["default" "my-policy1"]
    
    # version 1 에선 read/write 명령어가 된다
    $ vault write my-secret1/hello world=1
    Success! Data written to: my-secret1/hello
    
    # 데이터 확인
    $ vault read my-secret1/hello
    Key                 Value
    ---                 -----
    refresh_interval    168h
    world               1
    
    # version 1 에선 kv get/put 도 된다.
    $ vault kv put my-secret1/hello world=2 foo=bar
    Success! Data written to: my-secret1/hello
    
    # 데이터 확인
    $ vault kv get my-secret1/hello
    ==== Data ====
    Key      Value
    ---      -----
    foo      bar
    world    2
    
    # 정책상에 없는 경로 접근
    $ vault read my-secret2/hello
    Error reading my-secret2/hello: Error making API request.
    
    URL: GET http://127.0.0.1:8200/v1/my-secret2/hello
    Code: 403. Errors:
    
    * 1 error occurred:
            * permission denied
    

    이번엔 Version 2

    # 로그인
    $ vault login s.BnRO5kDRZTAHHRMvZIk8qwia
    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.BnRO5kDRZTAHHRMvZIk8qwia
    token_accessor       90iSQdmmxhYSFaVq0CX4uSKb
    token_duration       167h50m9s
    token_renewable      true
    token_policies       ["default" "my-policy2"]
    identity_policies    []
    policies             ["default" "my-policy2"]
    
    # version 2 에선 read/write 명령을 사용할 수 없다.
    $ vault write my-secret2/hello world=1
    Error writing data to my-secret2/hello: Error making API request.
    
    URL: PUT http://127.0.0.1:8200/v1/my-secret2/hello
    Code: 404. Errors:
    
    
    WARNING! The following warnings were returned from Vault:
    
      * Invalid path for a versioned K/V secrets engine. See the API docs for the
      appropriate API endpoints to use. If using the Vault CLI, use 'vault kv put'
      for this operation.
    
    # 마찬가지
    $ vault read my-secret2/hello
    WARNING! The following warnings were returned from Vault:
    
      * Invalid path for a versioned K/V secrets engine. See the API docs for the
      appropriate API endpoints to use. If using the Vault CLI, use 'vault kv get'
      for this operation.
    
    # 버전이 보인다. 이전에 몇번 데이터를 넣어서 버전이 3 이다.
    $ vault kv put my-secret2/hello world=1
    Key              Value
    ---              -----
    created_time     2019-09-18T08:38:14.993018446Z
    deletion_time    n/a
    destroyed        false
    version          3
    
    # 데이터 확인
    $ vault kv get my-secret2/hello
    ====== Metadata ======
    Key              Value
    ---              -----
    created_time     2019-09-18T08:38:14.993018446Z
    deletion_time    n/a
    destroyed        false
    version          3
    
    ==== Data ====
    Key      Value
    ---      -----
    world    1
    
    # 정책에 없는 경로로 접근
    $ vault kv get my-secret1/hello
    Error making API request.
    
    URL: GET http://127.0.0.1:8200/v1/sys/internal/ui/mounts/my-secret1/hello
    Code: 403. Errors:
    
    * preflight capability check returned 403, please ensure client's policies grant access to path "my-secret1/hello/"
    

    K/V Version 2 에선 secret engine 뒤에 data 가 붙는다고 한다. Version 1 에선 필요 없지만 Version 2 에선 data 를 붙여줘야 한다.

    발급 토큰 삭제

    # 둘다 없애고
    $ vault token revoke s.Jb0UpJBV0bdtWYO8TxlDwphk
    Success! Revoked token (if it existed)
    
    $ vault token revoke s.BnRO5kDRZTAHHRMvZIk8qwia
    Success! Revoked token (if it existed)
    
    # 로그인하려면 실패한다.
    $ vault login s.BnRO5kDRZTAHHRMvZIk8qwia
    Error authenticating: error looking up token: Error making API request.
    
    URL: GET http://127.0.0.1:8200/v1/auth/token/lookup-self
    Code: 403. Errors:
    
    * permission denied