2021 11 16 Ithome Cloud Summit Vault

各位好

關於這個 QRcode

每次上台前,我都會想要帶什麼樣的內容給觀眾,讓觀眾值得花 30 分鐘在底下聽。後來就習慣先發表一篇文章,把對觀眾有幫助的資源包成一包:

  • 首先是完整投影片:https://slides.com/chechiac…/terraform-introduction-a56697
  • 逐字講稿:(最後校稿中)
  • 然而只有本次演講內容,回去可能還是不太容易操作。所以這次附上使用 Terraform 一鍵部署 vault 的 Github Repository:https://github.com/…/southe…/chechia_net/vault/singleton
  • 如果不熟 Terraform,再附上 30 天手把手 Terraform 教學文章,只要願意花時間,全篇中文一個月帶你上手 Terraform。
    • IThome 鐵人賽好讀版:https://ithelp.ithome.com.tw/users/20120327/ironman/4057
    • Github Repository 完整版:https://github.com/…/terraform-30…/tree/main/lecture/zh
  • 如果遇到問題還是需要找人發問,所以再推薦兩個社群,可以來這邊發問,要找我本人也找得到。甚至只是加入潛水不講話,都可以被動吸收許多新知。

大家可以手機拍完這個就出去吃午餐了。 或是拍回家,然後傳給一個同事叫他花 30 天把 Terraform 跟 Vault 這些都學會。

總之希望對各位有幫助,讓國內技術力能持續進步成長。


回到本次演講。

本次演講有三個關鍵字

  • Kubernetes
  • Vault
  • Terraform 這個是隱藏的

請問平時工作會用到這三個技術之一的朋友,請舉個手,好讓我知道一下觀眾的分布,等等分享的內容會照比例做一些調整。

我們今天不會講太多 Kubernetes 的內容,重點放在 Vault,以及如何設定 Vault,所以 Terraform Infrastructure as Code 或是 configuration as Code 會在這邊跑出來。


關於我,我是哲嘉。我在 Maicoin 當 SRE。常出現的社群是 CNTUG 與 DevOpsTW。


我們今天談的更大的主題其實是 Key Management 私鑰管理,或是密碼管理。這是一個很大的題目,今天演講內容只是其中的一個實作案例。


舉個例子,一邊是 API Server,另一邊 Database,或是第三方服務

Database 來 Authenticate 合法的 Client 用戶端,可能是 username + password,或是 API Key + Secret,或是 Access Token,或是 Private Key,Client Certificate,都可以。

在跨不同平台或是介面的服務,我們常用的 Auth 方法。認 Key 不認人。


那中間這些 Key 要怎麼管理,就有很多學問 其中最基本的,是怎麼配置給 API Server 讓他使用 注意:讓 API Server 使用,隱含的意思是,其他人不管是其他微服務,或是開發工程師,閒雜人等都不能看到。


這邊我們假設 API Server 是在 Kubernetes 裡面跑,微服務架構,所以 API Server 可能是一個 Pod,我們 SRE 要為這組 Pod 配置密碼。

這邊列出的應該是 K8s 比較常見的幾種做法。

  • plain text,直接寫進 file 讓 Pod 去讀取
  • k8s secret 做 base64 encode
  • 安全一點的透過外部機制作加密解密
  • 或是寫在 API Server 的 memory 中

事實上如果沒有使用 K8s,使用 VM 或是公有雲 Container Service,應該都是類似的原理,大家都是 Linux base,secret 放進來看要放在 disk 或是 memory 裏面。


實際放到 K8s 大概會長長這些 yaml

最簡單,就直接把 secret 壓到 Pod env 裏面,

最簡單也最危險

  • 所有看得到 yaml 的人都明碼看見密碼
  • 所有能進到 file system

提外話

API Server 被從正面打穿,滲透到拿到這組密碼的機會多高?

  • 如果 API Server golang library 有在跟安全性更新
  • Kubernetes 用公有雲的 Kubernetes Service,有在更新
  • OS ami 跟 docker image 都有在更新
  • 然後有功能正常的防火牆

打掛蠻有可能的,但打穿服務到拿到密碼,是有難度的。

更多時候,至少在幣圈有被爆出來的資安事件,大多是是公司員工被釣魚信掉到,被植入惡意軟體在 local 電腦,然後他又看得到明碼的密碼,直接爆炸。

明碼糟糕的地方,大家都看得到,一開始就是 exposed 的狀態,風險不可控,也無從管制。


然後是 K8s secret,也是從 env 掛進去 Pod


放在 k8s secret,是 base64 的格式

看起來跟原先內容不一樣了,有人就跟我說,他們家的 k8s secret 有用 base64 加密。

encode 跟 encrypt


k8s secret 有什麼問題

  • 明碼 plain text 的問題,不該看到的人很容易就看到
  • 根本的問題還是 RBAC 懶得設定,大家都用 default role 進來

要用可以,先看 k8s secret 後面的儲存實作是什麼?

  • 是 k8s etcd
  • 透過 k8s API server 存取

etcd 跟 kube-api 一般來說是夠安全的。官方文件還建議

  • secret 要加密 encrypt
  • 增強 RBAC 控制,只有特定 role 才看得到 secret,,而不是每個人都用 default role 近來 k8s,然後進到 namespace 全部 secret 就看光光

RBAC 有設定好,有加密,是可以做到安全。當然還是沒有專門 key Management 工具,如 Vault 有額外管理上的優化功能。

加密範例可以看強者我朋友的文章


加密完可能長這樣,還要額外透過其他機制才能進行解密,拿到原始資料

  • 例如透過 k8s controller 解密
  • 或是透過 vault server
  • 或是透過公有雲的 Key Management Service 做解密

其他的 k8s secret 加密解決方案


今天我們使用 Vault,其中一個目的就是要坐中間這段 Safe Magic

  • 給這個 Pod secret
  • 然後只給這個 Pod Secret

當然 Key Management 其他還有一堆事情要處理

  • 密碼洩漏的話有沒有 revoke 機制

  • 能不能定時 Rotate 汰換密碼?

  • 改架構,底下的設定好不好耕著動態調整,還是要跟著 rename / mv k8s secret

  • 怎麼做稽核,怎麼檢查內容。我看不到 vault 幫我看一下內容對不對,這個很容易發生。

臆想頭就很痛


今天的目的很單純

  • 密碼的露出盡量小
  • 最好密碼是有期限的,逾期自動失效
  • 暴露了可以 revoke

Vault

有人用過?這邊簡介一下


在 CNCF 的 landscape 漱渝 Key Management,應該是裡面市佔最高的開源項目


重點就是保護與管理 secret


Vault 的核心概念,這個影片是 Hashicorp 官方介紹的影片,講得很好,大家自己回去看一下


這邊簡單 vault 101

現在有一台 vault server 已經設定好了,我們可以使用 vault client 連線

例如這邊

  • 使用 VAULT TOKEN 告訴 vault 你是什麼身份的用戶
  • 或是進行 login,Vault 會呸發一組臨時的 TOKEN 給你

拿著組 TOKEN 去問 Vault,請問我可以要 /user/mysql 這個路徑下的資料嗎?

Vault 檢查 TOKEN 的 role 與 permission,可以就回傳值 不行就 permission denied

Vault 就是金庫,真正重要的 key 存在裡面,使用這要來問 Vault,要先過 Vault 這關


Vault 實際存放 Secret Engine,這邊也跳過,大家先把他當 key / value 存放好了 XD


等等,這樣 vault Auth 有點怪

本來拿 username / password 去控制 Mysql 先在多一步,先拿到 VAULT TOKEN,再拿 TOKEN 去跟 Vault 拿 Mysql password,再去連 MySQL

咦這樣不是很怪?我如果 Vault token 暴露了,有心人士還是可以從 vault 拿到資料啊

這樣有比較安全嗎?還是只是花式被駭

對,只是做 token 交換的話,還是不夠,所以 Vault 有提供許多 Auth method

  • token 只是其中一種
  • 有很多認證方法不用 token 交換,但也能讓 vault 認得 k8s pod 與 api server

這是今天的重點之一,token / 密碼傳遞不安全,那就用其他手段 auth


以 AWS IAM auth 為例

如果今天是在 aws ec2 上跑,那可以透過 aws internal api 去取得身份認證資料,也就是 ec2 instance metadata

拿這個 metadata 去問 vault,vault 再透過 aws api 去確認,這個 ec2 instance 真的是合法的

然後依據 ec2 instance 身份,配發權限跟資料

  • api server ec2 就給 api server secret
  • frontend server ec2 就給 frontend secret

中間沒有多餘的密碼 / token 交換


來往的對話大概是這樣

  • AWS API 是可信的
  • Vault 自己維護是可信的
  • 服務透過三方交握去認證,認 runtime 環境的 metadata,不再是認 key 不認人

至於 api server ec2 近來 vault 後,應該有什麼樣的權限,在 vault 內部透過 policy 配置

  • 設定 path
  • 設定允許的 operation 例如 read write list delete … 等

runtime 動態調整


當然 Vault 還有提供很多更加安全的功能

  • 例如如何安全地存放 secret

Storage 這邊跳過


Secret + auth 搭配跳過


以及 dynamic secret,來解認 key 不認人的問題

例如 mysql 的靜態 username / password,透過 vault 設定可以變成動態的


回到 k8s,使用 token auth,然後把 VAULT TOKEN 放在 k8s secret 裏面,只有比較安全一點點

就是 VAULT TOKEN 可以快速 rotate 跟 revoke

這邊可以搭配其他 auth 方式來解決


剛剛不是讓 vault 去認 aws ec2?

在 k8s 中,可以讓 vault 去認 k8s cluster / service account


路徑圖長這樣

  • pod runtime 都會有 service account
  • 使用 service account 的 metadata 去問 vault
  • vault 去問 k8s,這個 service account 是真的假的
  • k8s 回答 vault,Pod 跟service account 是合法的
  • vault 再配權限給 Pod

auth detail 的文字描述,跟上面講的一樣


配合 k8s sidecar,可以把 vault 拿到的 key 寫到 memory mount 裏面

  • Pod init 時 init container 才去 invoke vault API
  • key 不會透過 k8s api 傳遞,也不會在 etcd 內出現
  • main container 透過 memory mount 存取 key
  • key 的 lifecycle 跟 pod 一樣, pod delete 掉這組 in-memory key 也自動清除

好處

  • 更少 expose,沒有過 kube-api 與 etcd
  • in-memory
  • vault 跟 pod 之間的 vault token 的 time-to-live 期限可以很短,幾十秒內,init 完即可拋棄的 token

壞處(?)

  • 每個 pod 起來會去打 vault api
    • 實務經驗上 loading 很低
    • 而且 vault server 可以做 HA 跟 horizontal scaling
  • 最大的成本,其實是 vault 設定
    • 讓 vault 認 k8s
    • 根據 service account 去配權限
    • 其他花俏功能都需要額外的設定
    • 系統複雜,保證配到你頭昏眼花

想像一下,這張圖里的

  • policy 跟為服務數量呈正比
  • secret path 也耕服務數量呈正比
  • auth k8s 數量也跟服務數量呈正相關
  • 用越久,內容隨時間增加
  • 改架構時更刺激

建議使用 vault 務必 搭配 Terraform 管理

  • infrastructure as code
  • configuration as code
  • policy as code

Terraform 非常適合管理複雜,但有常常需要細部調整的設定資料


其他功能,跳過


其他功能


secret debug 超麻煩

  • 內容正確性,valid key 還是 invalid key,還是根本是另一隻 key
  • 權限正確性,是不是這個 username / password 的權限是正確的
  • 跨團隊溝通更頭痛,不是可以貼在 slack 大家一起幫看的東西

terraform 可以幫助 vault 設定 debug

  • 至少跨環境復現問題很方邊

Vault 有 HA


Vault Performance 通常不是問題

  • 雖然 loading 隨 micro service 線性增加
  • 但本身可以是無狀態 server,可以 horizontal scale

注意一下 auto-retry

  • pod fail restart 又再 init 一次,如果一萬個 pod 一直 retry 可能真的會把 vault 打爆
  • backup limit 要注意
  • 使用 init container 的話,是 cache 在 Pod 層級,container fail restart 不會重新打 vault api

安全性

  • vault 有專業資安團隊把關
  • 不要怕 vault 被打穿,而是要怕同事被釣魚

結論


要不要 vault


qrcode 最後機會


有問題可以來社群找我


Maicoin 是間好公司 2014 服務上線到現在,在台灣已經邁入第八年。顧客數一直增加,我們也持續緩慢擴編。

覺得自己有能力,歡迎來挑戰,等等私下找我聊


謝謝


Q & A

Terraform vs Pulumi

  • 操作語言差異,有好有壞
  • vault 跟 terraform 的 hcl 是增強版 json,本質還是 json,有興趣可以去看我的文章
  • terraform 目前是站跟星星還是領先,未來繼續看

Kubernetes Service account token 要不要更新

  • 要,應該定期更新,官方文件有操作步驟

Vault / Terraform 實務上的工作負擔會很花時間跟人力嗎

  • 學習曲線比較奇怪,要花一點時間做中學
  • 學熟了之後就很好改,效率很高
  • 至少是屌打用 gui 改或是 client 直接下 cmd 拉
張哲嘉
張哲嘉
Site Reliability Engineer

我的研究領域包括網站可靠性工程、DevOps、Container和Kubernetes。