2019年8月6日 星期二

透過 dex 取得 kubernetes 認證 (1)

官網可以看到 kubernets 支援幾種認證方式,其中一種叫 OpenI
D Connect ,也就是 OIDC。而最常用在 kubernetes 裡作為 Identify Provider 的軟體是 dex。

OIDC 的架構裡,有好幾種角色,這邊沿用 OpenID 官網 的 FAQ 裡的定義,以便後續使用說明。

* IDP : Identify Provider,在這篇文章中指的是 dex
* RP : Relying Party, 也就是需要取得認證的 application,在這篇文章中會用 php/laravel 來實作這角色。
* SP : Service Provider,實際上提供身份驗證的來源,OpenID 官網 FAQ 沒有用 SP 這個縮寫,只有提到 Service Provider,這裡為了方便所以用 SP,在這篇文章使用的 Samba AD。

dex 本身有提供一個 example app (名稱就叫做 example-app) 當作 RP 的角色來使用,我一開始入門 dex 就是用  example-app ,這部分在 dex 官網有還算清楚的設定流程。大致上摸索一下,用 example-app 和 dex 完成整個 OIDC 認證流程應該不難。

用 go get github.com/dexidp/dex 抓下 dex project ,在 dex 目錄下,有幾個可能會改到的地方:

* cmd/example-app/ :這裡面是 example-app 的 source,如果要寫一個自己的 RP,用 example-app 會是一個不錯的起點,連我這種 golang 門外漢都可以稍做修改。
* examples/k8s/ :這裡面提供 deploy dex 到 kubernetes 的 sample yaml ,以及產生金鑰的 sample script,我都是用這邊的來產生金鑰及安裝 dex。
* web :dex 的登入頁面的 source,如果只是要修改畫面的話在這邊修改即可。
* Dockerfile :如果需要改 dex 的 source,可以在編譯後用這個產生 dex image ,然後放到 image registry 上,然後在 deploy dex 的 yaml 指定 registry 上的 image。

另外在 deploy dex 前有一些預備動作,dex 預設會以 nodeport 的方式提供服務,而最好有一個 FQDN 指向 dex ,所以需要在 DNS 那邊先設定好,假設叫 dex.example.com。


修改 examples/k8s/gencert.sh 這個產生金鑰的 sscript,把 DNS.1 指定為 dex.example.com,然後執行 script ,產生的金曜會放在相對路徑下的 ssl 裡。
然後將產生的金鑰放到 kubernets 的 secret 裡
kubectl create secret tls dex.example.com.tls --cert=ssl/cert.pem --key=ssl/key.pem

注意一下上面指令裡的 secret name,在設定 deploy dex 的 yaml 會用到。

接下來是設定 SP 相關的部分,我一開始對 ldap/AD 不熟,選擇用 github/gitlab 來當 SP,基本上照著官網去設定 github/gitlab 取得 client-id 和 client-secret ,然後一樣也是放到 kubenrets 的 secret 裡
kubectl create secret generic github-client --from-literal=client-id= --from-literal=client-secret=

如果用 LDAP ,那 client-id 和 client-secret 就是登入 LDAP 的帳號密碼。用 LDAP 比較麻煩的是設定 yaml 的時候,因為對 LDAP  不熟,為了從 LDAP 取出 group 並對應到 yaml 裡的設定,花了不少力氣。

然後開始修改 examples/k8s/dex.yaml ,主要修改幾個地方:

1. Deployment 裡的 secretName ,也就是前面提到的 dex.example.com.tls 這個名稱。

2. ConfigMap 的 config.yaml :
   * connectors 是設定有哪些 SP 及相關的參數。
   * staticClients 設定有哪些 RP 可以來取得認證。
   * enablePasswordDB,如果不需要,可以改成 false,以提高安全性。

其中 staticClients 的設定的內容,和 RP 如何取得認證有直接的關係,這部分後面會說明。
設定完之後,就可以 deploy dex 了
kubectl apply -f dex.yaml

預設 replicas 是 3,也就是會有三個 dex pods。
執行 example-app 的部分,主要帶入的幾個參數是
* --listen 也就是 example-app 會 listen 哪個 ip:port
* --issuer IdP 也就是 dex 的 ip:nodeport
* --client-id 在 staticClients 裡設定的 id
* --redirect-uri  在 staticClients 裡設定的 redirectURIs

用瀏覽器打開 example-app 所 listen 的 ip:port ,就可以開始 OIDC 的認證流程了。

這篇先寫到這邊,下一篇會開始用 PHP/Laravel 去實作一個 RP。

沒有留言: