如果您最近參加了網路安全展會,您想必已經注意到幾乎每個展位都在宣傳「零信任(ZT)」概念。大多數安全防護公司似乎都秉持著相同的價值主張,即「採用零信任模式來保護應用安全」。零信任是一個廣泛的術語,涵蓋眾多使用案例。
零信任不是特性或功能,而是IT 安全防護領導者所奉行的理念。零信任假定是進出系統的所有流量均不可信,必須經過仔細檢查才可放行。由於網路攻擊的複雜性不斷加劇,因此各企業紛紛轉而採用零信任理念。基於邊界的防火牆已經無法再確保數位資源的安全。
在本系列文章的第一篇,我們將NGINX Plus 配置為外部負載平衡器,以便將TLS 流量路由和卸載到叢集節點。在本文中,我們將利用相同NGINX Plus 部署來實現零信任使用案例,從而改善混合應用的安全防護。
註:若要實現我們範例中的零信任使用案例,請先學習本系列文章的第一篇。請確保先完成第一篇的學習,再開始閱讀第二篇。
零信任使用案例1:OIDC 驗證
OIDC (OpenID Connect) 是OAuth 2.0 框架之上的驗證層。許多企業會選擇使用OIDC 來驗證數位身份,並為消費者應用啟用SSO(單一登入)。透過單一登入技術,使用者可透過IdP(身份驗證供應商)驗證其身份,從而使用一套使用者憑證存取多個應用程式。
除了在第一篇中配置的基本反向代理負載平衡以外,我還可以配置NGINX Plus 作為OIDC 中繼方,與IdP 交換ID 令牌並對其進行驗證。
我將使用IdP 來擴展第一篇中所述的架構,並將NGINX Plus 配置為身分感知代理。
NGINX Plus 的必備組件
在將NGINX Plus 配置為OIDC 身分感知代理之前:
1. 需要安裝njs。
$ s udo apt-get install nginx-plus-module-njs
2. 在nginx.conf 檔案頂部新增下列一行,將njs 模組載入到NGINX 配置中。
load_module modules/ngx_http_js_module.so;
3. 將OIDC GitHub 倉庫複製到選定目錄下
cd /home/ubuntu && git clone --branch R28 https://github.com/nginxinc/nginx-openid-connect.git
設定IdP
IdP 將管理和儲存數位身份,以防止攻擊者冒充用戶竊取敏感資訊。現有許多IdP 可供選擇:Okta、Ping Identity、Azure AD。在本例中,我們選擇了Okta 作為IdP。
如果您無法存取IdP,則可使用Okta 命令列介面(CLI)快速設定一個,並執行okta register 指令註冊一個新帳戶。
在成功建立帳戶後,我們將使用Okta CLI 將Okta 預先配置為IdP,建立Okta 中所說的應用程式整合。其他IdP 在定義應用整合時會用到不同的術語。例如,Azure AD 將其稱為應用程式註冊。 如果您使用的不是Okta,則可依照所使用IdP 的文件進行操作,然後跳到下一節(將NGINX 設定為OpenID Connect 中繼方)。
1. 執行okta login 指令,驗證Okta 開發人員帳號的Okta CLI。根據提示輸入Okta 網域名稱和API 令牌
$ okta login
Okta Org URL: https:// your-okta-domain
Okta API token: your-api-token
2. 建立應用整合
$ okta apps create --app-name=mywebapp --redirect-uri=https://<nginx-plus-hostname>:443/_codexch
其中
- –app-name定義應用程式名稱(此處為mywebapp)
- –redirect-uri定義將登入重新導向至NGINX Plus 的URL。應解析為第一篇文章中配置的NGINX Plus 的外部IP。我們使用443 端口,因為在第一篇文章中,NGINX Plus 上配置了TLS 終結。回想一下,我們在NGINX Plus 上設定TLS 時使用了自簽名憑證和金鑰。在生產環境中,建議使用Let’s Encrypt 等受信任憑證授權單位所頒發的憑證/金鑰。
步驟2 中的指令完成後,便可在${HOME}/.okta.env 中找到從應用整合產生的客戶端ID 和金鑰。
將NGINX 配置為OpenID Connect 中繼方
現在,我們已經完成IdP 的設置,可以開始將NGINX Plus 配置為OpenID Connect 中繼方了。登入NGINX Plus 實例後,只需從主目錄執行設定腳本即可。
$ ./nginx-openid-connect/configure.sh -h <nginx-plus-hostname> -k request -i <YOURCLIENTID> -s <YOURCLIENTSECRET> –x https://dev-xxxxxxx.okta.com/.well -known/openid-configuration
其中
- -h定義NGINX Plus 的主機名
- -k定義NGINX 將如何檢索JWK 檔案以驗證JWT 簽章。 JWK 檔案可從傳送至IdP 的子請求中檢索出來
- -i定義從IdP 產生的客戶端ID
- -s定義從IdP 產生的客戶端金鑰
- -x定義OpenID 配置端點的URL。以Okta 為例,URL 使用您的Okta 組織網域名稱開頭,後面接著路徑URI /.well-known/openid-configuration
配置腳本將為NGINX Plus 產生OIDC 設定檔。我們需要將產生的設定檔複製到第一篇文章中所述的/etc/nginx/conf.d 目錄下。
$ sudo cp frontend.conf openid_connect.js openid_connect.server_conf openid_connect_configuration.conf /etc/nginx/conf.d/
預設情況下,frontend.conf 會以明文http 方式監聽8010 連接埠。我們需要將kube_lb.conf 合併到frontend.conf 中,以實現第一篇文章和本文介紹的兩個用例。產生的frontend.conf 應如下所示:https://gist.github.com/nginx-gists/af067326734063da6a4ff42146873262
最後,需要編輯openid_connect_configuration.conf 文件,並將客戶端金鑰修改為Okta IdP 產生的金鑰。
重新載入NGINX Plus,讓新配置生效。
$ nginx -s reload
測試環境
現在,我們可以測試環境的運作情況了。簡言之,我們設定了一個IdP,並將NGINX Plus 配置為身分感知代理,以便在使用者存取Kubernetes 叢集之前對其ID 令牌進行驗證。
若要測試環境,我們需要開啟瀏覽器,在網址列中輸入NGINX Plus 的主機名稱。您將被重新導向到IdP 登入頁面。
註:主機名稱應解析為NGINX Plus 設備的公共IP。
瀏覽器提示您進入IdP 登入頁面後,您就可以在透過使用者憑證驗證後存取Kubernetes pod。使用者憑證應由IdP 定義。
登入應用程式後,已通過驗證的使用者的ID 令牌將儲存在NGINX Plus 鍵值儲存中。
透過OIDC 啟用PKCE
在上一節中,我們學習如何將NGINX Plus 配置為OIDC 中繼方,以驗證嘗試連線到受保護Kubernetes 應用程式的使用者身分。但在少數情況下,攻擊者可以攔截從IdP 發出的代碼交換請求,劫持您的ID 令牌並入侵您的敏感應用程式。
PKCE 是OIDC 授權代碼流的擴展,可防止授權代碼被截獲和竊取。它增強了安全防護,攻擊者若要從IdP 換取ID 令牌,不僅需要提供授權代碼,還需提供代碼驗證程序。
在我們目前的設定中,在將使用者重新導向到IdP 登入頁面時,NGINX Plus 會傳送一個隨機產生的PKCE 程式碼驗證程式作為查詢參數。當使用授權代碼換取ID 令牌時,IdP 將使用此PKCE 代碼驗證程序進行額外驗證。
NGINX Plus 和IdP 均需啟用PKCE。要在NGINX Plus 上啟用PKCE 驗證,編輯openid_connect_configuration.conf 文件,並將$oidc_pkce_enable 修改為1,然後重新載入NGINX Plus。
根據您使用的 IdP,應該有一個複選框可用於啟用 PKCE。
測試環境
為了測試PKCE 是否正常運作,我們將開啟瀏覽器,再次輸入NGINX Plus 主機名稱。您會被重新導向到登入頁面,但這次URL 略有變化,增加了查詢參數:
- code_challenge_method —— 用來對明碼驗證程式進行雜湊處理的方法(很可能是SHA256)
- code_challenge —— 明碼驗證程式的雜湊值
NGINX Plus 將提供此明碼驗證程序和授權代碼以換取ID 令牌,然後對其進行驗證,並將它儲存在快取中。
利用第三方系統擴展OIDC
客戶可能需要將其OIDC 工作流程與已部署於生產環境的專有身分驗證/授權系統整合。例如,可能需要從外部Redis 快取或JFrog Artifactory 中收集與使用者相關的其他元資料。我們可以透過擴展上一節中的圖表來填補此空白。
除了使用NGINX Plus 進行令牌驗證以外,我還從JFrog Artifactory 拉取了回應數據,並在用戶通過身份驗證後將其傳輸給後端應用。
附註:此處,我使用JFrog Artifactory 作為第三方端點範例。從技術角度來說,我可以按需使用任何端點。
測試環境
為了測試環境的運作狀況,我將對NGINX OIDC 配置進行一些更新。您可從我們更新的GitHub 倉庫中拉取相關信息,作為更新NGINX 配置的參考。
更新1:新增njs 原始碼
第一個更新是使用njs 擴展NGINX Plus,並從我們的第三方系統中檢索回應資料。將KvOperations.js來源檔案加入/etc/nginx/njs 目錄中
更新2:frontend.conf
將第37-39 行新增至frontend.conf,這樣NGINX Plus 就會在使用者透過OIDC 進行驗證後向我們的第三方系統發起子請求。我們將此子請求的URI 設定為/kvtest。詳情請參閱下一項更新。
更新3:openid_connect.server_conf
我們將第35-48 行加入到openid_connect.server_conf,其中包含NGINX 中的兩個內部重定向:
- /kvtest;透過URI /kvtest的子請求進行內部重定向將在KvOperations.js 中發揮作用
- /auth;對URI /auth 的子請求的內部重定向將被代理到第三方端點。您可將第47行中的<artifactory-url>替換為自己的端點
更新4:openid_connect_configuration.conf
此更新為可選項,適用於向第三方端點傳遞動態變數。您可透過向NGINX Plus 鍵值儲存傳送POST 請求來動態更新變數。
$ curl -iX POST -d '{"admin", "<input-value>"}' http://localhost:9000/api/7/http/<keyval-zone-name>
我們在第102-104行定義/實例化新的鍵值儲存。更新完成後,便可測試最佳化後的OIDC 環境,具體方法是故障排除/驗證應用是否位於動態輸入值的接收端。
結語
本文介紹了一些在混合架構中使用NGINX 的零信任使用案例,主要圍繞著身分驗證展開探討。在本系列文章的下一篇,我將介紹更多零信任用例,包括:
- 其他身份驗證方法(SAML)
- 加密
- 授權和存取控制
- 監控/審計
文章來源:DevCentral