Vault 基礎教學

Gary Ng
11 min readJul 7, 2024

--

https://www.omniwaresoft.com.tw/wp-content/uploads/2022/04/vault.png

mac 安裝 vault

 brew tap hashicorp/tap
brew install hashicorp/tap/vault

確認是否安裝成功

vault -v

用 dev 模式啟用 vault

vault server -dev

注意 dev 模式僅用於測試、開發用!切記不要在 production 環境下使用 dev mode。

為了測試在 1 個 tab 使用 vault server -dev 後在另外一個 tab export vault 環境變數

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

設定環境變數後就可以簡單地進行測試,例如: get, put kv

設定資料指令如下:

vault put secret/mysecrets {key}={value} {key2}={value2}

存取資料指令如下

valut get secret/mysecrets

vault 引擎類型分有三種可以使用

  1. 通用型:

適用於簡單的儲存需求,例如: API 密鑰、密碼等。

2. v1

適用於需要有版本控制的情境。

3. v2

v1 功能的進化版,提供多種的資料儲存型別,例如: list, dict。

vault 預設的儲存的secret為 secret ,倘若使用尚未定義的則會出錯。

想要 put 到尚未定義的 secret 會出現以下錯誤

列出目前 vault 擁有的儲存secret

vault secrets list

倘若需要設定新的儲存secret,需使用以下指令

vault secrets enable -path=kv kv

也可以指定要創建的 secret 的版本

vault secrets enable -version=2 -path=kv kv

再查看一下目前可以使用的secret

vault secrets list

緊接著可以 put 資料到此secret看看

vault kv put kv/a hello=world

使用 get 取出設定的值

vault kv get kv/a

也可以列出目前 kv 底下的 key 有哪些

vault kv list kv

停用 kv 這個 secrets

vault secrets disable kv

會發現列表中已不存在 kv 這個 sercret

Vault Policy

檢查目前的 policy list

vault policy list

創建 policy, 我們可以先創建一個叫做 read-only.hcl 的 policy file 做練習。

read-only.hcl

path "/secret/foo" {
capabilities = ["read", "list"]
}

新增 policy

vault policy write <policy name> <policy file>

所以指令如下

vault policy write read-only read-only.hcl

可以再透過 list 查看到新的 policy

vault policy list

可以透過以下指令刪除 policy

valult policy delete sys/policy/<policy name>

我們可以將新增的 policy 新增至 userpass 做測試, 先啟用 userpass auth

vault auth enable userpass

assign policy 到 userpass auth

vault write auth/userpass/users/<username> password=<password> policies=<policy name>

policies 假如有多筆的話使用逗號區隔

接著透過登入以查看是否成功附加 policy 到該使用者

vault login -method=userpass username=<username>

接著會叫你輸入密碼

使用上面設定好的 password, 會發現登入成功且該 token 也擁有我們所附加的 policy

使用 vault 產生 aws secret

這邊我們會用到 aws secret engine , 不過首先我們首先需要設定 iam federationToken 權限

IAM Policy 權限如下:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "sts:GetFederationToken",
"Resource": "*"
}
]
}

創建好 IAM 後記得也要產生 AccessKey 跟 SecretKey。

緊接著我們要來啟用 aws secret enging, 官方教學如下:
https://developer.hashicorp.com/vault/docs/secrets/aws

  1. 啟用 aws secret enging
vault secrets enable -default-lease-ttl=15m -max-lease-ttl=15m aws

default-lease-ttl: 限制 token 產生出來的權限為 15 分鐘

預設 aws secret engine 所設定的 path 為 aws, 倘若需要自訂可以在設定 -path 參數

2. 設定要用來產生 AWS credential 的 IAM 資訊到 vault

vault write aws/config/root access_key=<access key> secret_key=<secret key> region=<aws region>

我們以教學網站為例,設定一個取得 s3 bucket 的 iam policy

s3-policy.json

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": "*"
}
]
}

3. vault 使用此 policy 創建一個為期 15 分鐘的 access key

vault write aws/roles/<role name> credential_type=federation_token policy_document=@s3-policy.json

參數說明:

credential_type: 指定使用 federation_token 方式,官方也有其他的方式可以使用

policy_document: policy 的資訊,這邊用我們上面所新增的 s3-policy.json, 倘若是字串的話可以使用

<<EOF
....

EOF

4. 產生該名角色的 credential

vault read aws/creds/<role name> ttl=15m

參數說明:

role_name: 上面第三步驟所設定的 role_name

ttl: 設定 credential 期限為 15 分鐘

接著我們可以使用 terraform 結合 vault aws/cred,不過我們基於安全考量不要使用 root 的 vault token, 這邊我們暫時創建一個有特定權限的 policy token。

aws-policy.hcl

path "aws/creds/<role name>" {
capabilities = ["read"]
}

這邊設定一個擁有 read aws/creds/<role name> 的 權限(policy)。

透過此 policy file 建立一個 vault policy

vault policy write aws-policy ./aws-policy.hcl

建立 policy 好後透過此 policy 建立一個為期 15 分鐘的 token

vault token create -field token -policy aws-policy -ttl 15m

接著透過新產生的 token 登入

vault login

此時登入後就僅有 aws-policy 以及 default 兩個 policy。

緊接著我們開始著手操作 terraform, 這邊不懂 terraform 的話改天會再寫一篇稍微說明 terraform

1.首先創建 providers.tf

provider "vault" {
// vault server ip 位置
address = "http://127.0.0.1:8200/"
}

// aws provider 設定
provider "aws" {
// aws 東京 region
region = "ap-northeast-1"

// vault federation 產生的 access key, secret key 等資訊
access_key = data.vault_generic_secret.aws_credential.data["access_key"]
secret_key = data.vault_generic_secret.aws_credential.data["secret_key"]
token = data.vault_generic_secret.aws_credential.data["security_token"]
}

data.tf

data "vault_generic_secret" "aws_credential" {
// vault 產生 credential 的 role name
path = "aws/creds/<role name>"
}

data "aws_s3_objects" "s3_object_list" {
bucket = "<bucket name>"
}

output s3Objectlist {
value = data.aws_s3_objects.s3_object_list.keys
}

執行 terraform init 安裝 terraform provider, 安裝好後可以執行 terraform plan, 緊接著就會印出在 data.tf 設定的 bucket name 資料出來。

這樣我們就可以做到 terraform 安全地使用 aws access_key, secret_key 了

--

--

Gary Ng
Gary Ng

Written by Gary Ng

軟體工程師、後端工程師

No responses yet