內容摘錄自影片介紹,要討論 Vault 的功能之前,先退一步回來看最一般的機敏資料的定義與管理方式
機敏資料主要分成 驗證(Authentication)
與 授權(Authorization)
,一者表明身份一者決定操作的權限,可能是 DB 的權限 / 第三方服務的 API Token / 用來加解密的對稱金鑰等等,這些資料可能被放在原始碼當中 / config 文件 / 環境變數 / 版本控制等等四散各地,之前 Github 有提出許多開發者都誤上傳機敏資料;
另一方面時間一久沒有人知道到底發出去哪些 key 又或是誰有在用,糟糕的是可能一組 key 有多個人使用
Vault 提出三個層級的解決方案1. 集中化管理
搭建 Vault Server 集中管理所有的機敏資料,在 Vault Server 中確保所有的機敏資料都是被加密儲存
,同時 Client 來跟 Server 要機敏資料時傳輸過程也是加密的
,安全性大幅提升;
且有 Vault 管理,可以定期 Rotate,並隨時查看目前的機敏資料使用狀況2.動態生成
透過動態生成方式,每一個 Client 來要即使權限需求相同,也動態生成不同的 key,如果有異常操作,就能很清楚是哪一個 Client 有問題,接著直接 revoke 掉就行了;
如果大家都共用一把 key,就查不出是誰也不能直接 revoke,造成安全上的漏洞3.Encrpyt as Service
API Server 設計時,我們常需要加解密資料,所以會需要金鑰與實作加解密演算法,但是一方面金鑰外流到 API Server 上多一層風險,再者如果加解密演算法有漏洞又是另一個風險;
所以 Vault Server 本身也提供加解密 API,讓金鑰與演算法的保障都留在 Vault Server 上,大幅降低風險。
架構上,Vault 拆成幾個模組增加相容性
- Authentication
基於人員的驗證,可以透過第三方的架構如 AWS/LDAP,或是K8S - Audit
將所有的操作都記錄下來,可以存放在 system logs 或是其他儲存方式 - Secret
機敏資料的型態,可能是 Key-Value,也可能是第三方服務如 Database / AWS 等 - Storage
機敏資料的儲放位置
以下教學將初步探索 Vault 功能為主,只適用於學習與測試環境使用!
下一篇實作篇,以 AWS 為主,動態 Launch API Server 時主動索取機敏資料,被配與動態 MongoDB 金鑰與 AWS Role
Vault 初探
Vault 官方教學 是一個互動式的教學,蠻簡單明瞭的,以下是整理的筆記,僅適用於學習,完全不建議用在正式環境!
先到 官方載點下載並安裝,設定好路徑之後可以安裝 auto complete $vault -autocomplete-install
,vault 會偵測 shell 安裝對應的插件
啟動測試環境的 Vault server
$ vault server -dev
接著會在 terminal 打印出 Root Token: 的字樣,此時 vault server 會跑在前景;
開啟另一個 terminal tab,將其輸出至環境變數等等會使用上 export VAULT_DEV_ROOT_TOKEN_ID="{替換 Root Token}"
,接著指定 vault server url $export VAULT_ADDR='http://127.0.0.1:8200'
;
透過 $ vault status
檢查是否指定正確
取得/新增/更新/刪除 secret
先前提到 Secret 有很多種,從最簡單的 key value 開始,Vault 通過以下指令設定
vault kv put secret/{path} {key}={vaule} {key2}={value2}
vault kv get -format=json secret/{path}
format 是選擇性回指定回傳格式vault kv delete secret/{path}
可以把 Vault Server 儲存密碼的方式想成 RESTful API Server,指定資源的路徑,採用最長匹配方式,secret
是預設的前綴,後面的path 用 / 分隔,接著的 kv 可以設定多組,put 同時代表新增與更新;
啟用 Secret 並設定 path
預設用 dev 啟動後 secret/
路徑會對應到 KV 儲存方式,可以透過 $vault secrets list
查看,接著如果我們想要自訂其他的 Secret,或是指定新的路徑儲放 KV,可以透過 $vault secrets enable -path={path} {secret engine}
例如 $vault secrets enable -path=kv kv
就能指定 kv/ 為新的 key-value 儲存路徑
接著下 $vault kv put kv/hello foo=bar
可以得到相同的結果,透過 $vault secrets list
可以看出來多了一組設定
如果不要用了,可以透過 $vault secrets disable {path}/
如 $vault secrets disable kv/
刪除,注意底下儲存的密碼也都會一並消失
啟動 AWS Secret Engine 取得動態 AccessKey / AccessSecret
先前提到 Vault 一大特色是支援多種 Secret,而且 Secret 可以是動態生成的,每一個 Client 來索取都能要到獨立的 Secret
透過 aws secret engine,可以指定 Role 與權限並給予動態 secret,首先讓我們啟動 secret $vault secrets enable -path=aws aws
,接著設定 aws 帳號
|
|
絕對不建議在生產環境如此使用,因為 shell command 會被記錄在 log 中
後續的操作,Vault 就會用這組帳密去管理 IAM
接著創建角色
|
|
這裡給予了 ec2 全部的權限
接著要產生 Secret 通過 $vault read aws/creds/my-role
,此時就會回傳一組新的 role,每次呼叫都會回傳獨立的 Secret (為什麼用 read 代表創建動作就不確定設計的原理了 :thinking_face),從 IAM Console 可以看到被創建的用戶
如果要 revoke 的話,通過 $vault lease revoke aws/creds/my-role/{lease id}
即可
剛剛想要查找有沒有指令可以條列出所有的 credentials,但看來是沒有這項指令,如果當初沒有記得 lease id 的話,就要去 IAM Console 手動刪除了
所有的指令可以從這邊看到 AWS Secret 文件,或是用 $vault path-help aws
查看,path-help 可以指定不同的路徑層次,例如 $vault path-help aws/config/lease
Authentication & Authorization
現在我們知道要如何建立與管理金鑰,但重點回到誰能來要金鑰以及權限劃分
,Authentication 部分 Vault 可以用 token / AppRule / Github / AWS IAM / LDAP 等等,Authorization 部分可以制定 Policy,限縮用戶能夠操作的 Secret 權限
Token
Token 驗證機制是 Vault 核心、不能被關閉的驗證功能,像我們一開始啟動 Vault Server 後會產生一個 root token,接著會用 root token 去制定 Policy,並產生多組 Token,文件提到如果設定完就應該 revoke root token
,最好是有 root token 時大家一起盯著螢幕操作後就 revoke,後續有需要可以在動態生成
- $vault operator init
- $vault operator generate-root
- 用 root token 生成其他 root token
在 Vault 中,Token 管理是階層化的,用母 Token 去生成的 Token 會自動變成子 Token,為了管理方便,如果母 Token 被 Revoke 那麼以下所有的子 Token 會全數被 Revoke
,如果希望 Token 不受母 Token 影響,可以用設定為 Orphan Token,跳脫階層獨立管理
除了 Root Token,其餘的 Token 都有 TTL,TTL 設定有幾個地方
- Vault Server 啟動時的 Config
- 透過 mount tuning 去更改
- 根據母 Token 的Policy
在有些長駐的程式中,需要長時間持有 Token 可以設定為 Periodic
,指定更新週期只要在這期間內去 renew 就能繼續使用 Token,同時可以指定 TTL 或是設為永不失效,等 TTL 到了會自動 revoke
Token 建立後會回傳 id / accessor / policy 等資訊,accessor
可以用來操作 token 相關的指令例如 renew / revoke / 反查 token id 等等,不太確定為什麼不直接用 token id 而是要多產生另一組 accessor 代號,但目前看到要條列出所有 token 只能透過列出 accessors 再去反查 token
以上的 Token 是指 Service Token
,也就是預設最常使用的 Token 形式;另外還有 Batch Token 用在 Vault 操作上,暫時沒有看到用處就先略過
接著實際操作看看
|
|
其他的部分,覺得透過 api 下指令比較方便,東西也比較全面,可以參考文件
|
|
設定 Policy
接著就是設定 Policy 部分,限制不同 Token 能夠操作 Secret 的權限,Vault 撰寫 policy 的格式是採用 hcl,也就是 HashiCorp 自己內部的 Config 描述語言,在路徑下建立檔案 my-policy.hcl
並貼上以下內容
|
|
上述文件的意思是這個 Policy 只能操作 secret/foo 的新&更新,其他的操作都一率被禁止,/data/
指的是預設 Key Value 的 Secret 路徑,如果是另外啟動的如 $vault secrets enable -path=kv kv
,則可以不用加 /data 變成 kv/foo
即可
接著實際操作
|
|
可以看到 token 的 policy 窩了自定義的 my-policy
接著開另一個 shell 登入
|
|
後來發現 $vault login 會影響所有的 shell,這點在測試要稍加留意
Vault Policy 設定可以很彈性,主要有幾項關鍵字
1. path
路徑選擇,可以用 *
代表以下所有路徑 / +
代表此路徑匹配任何字元等方式,如果有多組 path,Vault 採取最長匹配的原則
2. capabilities
權限選擇,有 [read, create, update, delete, list, sudo, deny]
,文件提到 Vault 沒有很仔細區分 create/update 的使用場景,所以要給就一起給;
sudo 指的是受 root 保護的權限 / deny 是禁止任何操作包含 sudo 也不行
3. allowed_parameters & denied_parameters & required_parameters
針對參數的設定,可以條列允許/不允許/必備的參數,如果沒有特別設定,則代表不受任何限制
4. min_wrapping_ttl & max_wrapping_ttl
產生子 Token 的最長與最短 TTL
以下是綜合範例
|
|
針對 secret/foo,在創建時只允許參數 foo / bar,其中 foo 的 value 不受限,但是 bar 只能是 zip 或是 zap
第二條是指 secret/bar 底下的任意路徑適用,包含 secret/bar/baz 和 secret/bar/baz/foo…. 等等,並且必須包含 bar, baz 這兩個參數
第三條是路徑會匹配如 secret/baz/foo/data-bar,且不允許 deny- 開頭的 key
多重 Policy 與衝突
在 Token 創建時可以同時綁定多組 Policy,不免讓人好奇如果兩組 Policy 對同一路徑產生衝突時的狀況,實測發現是 capacities 相同路徑下會給予最綜合的權限,而不是按照順序覆蓋之類的
可以用 $vault token capabilities {token} {path}
查詢
改變 Policy
當改變 Policy 時,原本已經建立好的 Token 不會動態套用,需要刪除重建,而新增/更新 Policy 的方式用 $ vault policy write {policy_name} my-policy.hcl
即可
統整
僅僅介紹基本功能就花了不少篇幅,涵蓋了基本的 Secrets / Auth 的功能介紹與操作
- 啟動 dev server,關掉資料則全部消失
|
|
- 登入與設定路徑
|
|
- Secret Engine 是與路徑匹配,secret/data 是預設 Key Store Secret Engine,可以另外開啟新的路徑
|
|
- 新增&更新/取得/刪除 Token
|
|
- Authentication
|
|
- Authorization
另外用 hcl 檔儲存 Policy,並匯入設定中
|
|
想不到初步介紹就花這麼大的篇幅,下一篇要實作結合 AWS 與搭配 API Server 的流程