1. 程式人生 > >033.Kubernetes叢集安全-API Server認證及授權

033.Kubernetes叢集安全-API Server認證及授權

一 Kubernetes叢集安全

1.1 安全機制

Kubernetes通過一系列機制來實現叢集的安全控制,其中包括API Server的認證授權、准入控制機制及保護敏感資訊的Secret機制等。叢集的安全性主要有如下目標:
  1. 保證容器與其所在宿主機的隔離。
  2. 限制容器給基礎設施或其他容器帶來的干擾。
  3. 最小許可權原則—合理限制所有元件的許可權, 確保元件只執行它被授權的行為, 通過限制單個元件的能力來限制它的許可權範圍。
  4. 明確元件間邊界的劃分。
  5. 劃分普通使用者和管理員的角色。
  6. 在必要時允許將管理員許可權賦給普通使用者。
  7. 允許擁有Secret資料(Keys、 Certs、 Passwords) 的應用在叢集中執行。

二 API Server認證管理

2.1 認證安全

Kubernetes叢集中所有資源的訪問和變更都是通過Kubernetes API Server的RESTAPI來實現的,因此叢集安全的關鍵點就在於如何識別並認證客戶端身份(Authentication),以及隨後訪問許可權的授權(Authorization)環節。 Kubernetes叢集提供了3種級別的客戶端身份認證方式。
  1. HTTPS證書認證:此方式最嚴格,基於CA根證書籤名的雙向數字證書認證方式。
  2. HTTP Token認證:通過一個Token來識別合法使用者。
  3. HTTP Base認證:通過使用者名稱+密碼的方式認證。

2.2 HTTPS認證原理

此方式需要有一個CA證書,CA是PKI系統中通訊雙方都信任的實體,被稱為可信第三方(TrustedThirdParty,TTP)。CA作為可信第三方的重要條件之一就是CA的行為具有非否認性。作為第三方而不是簡單的上級,就必須能讓信任者有追究自己責任的能力。 CA通過證書證實他人的公鑰資訊,證書上有CA的簽名。使用者如果因為信任證書而有了損失,則證書可以作為有效的證據用於追究CA的法律責任。正是因為CA承擔責任的承諾,所以CA也被稱為可信第三方。 在很多情況下,CA與使用者是相互獨立的實體,CA作為服務提供方,有可能因為服務質量問題(例如,釋出的公鑰資料有錯誤)而給使用者帶來損失。在證書中綁定了公鑰資料和相應私鑰擁有者的身份資訊,並帶有CA的數字簽名;在證書中也包含了CA的名稱,以便於依賴方找到CA的公鑰,驗證證書上的數字簽名。 CA認證涉及諸多概念,比如根證書、自簽名證書、金鑰、私鑰、加密演算法及HTTPS等。 如下大致為SSL協議的流程,在Kubernetes CA中認證大概包含下面幾個步驟:

  1. HTTPS通訊雙方的伺服器端向CA機構申請證書,CA機構是可信的第三方機構,它可以是一個公認的權威企業,也可以是企業自身。企業內部系統一般都用企業自身的認證系統。CA機構下發根證書、服務端證書及私鑰給申請者。
  2. HTTPS通訊雙方的客戶端向CA機構申請證書,CA機構下發根證書、客戶端證書及私鑰給申請者。
  3. 客戶端向伺服器端發起請求,服務端下發服務端證書給客戶端。客戶端接收到證書後,通過私鑰解密證書,並利用伺服器端證書中的公鑰認證證書資訊比較證書裡的訊息,例如,比較域名和公鑰與伺服器剛剛傳送的相關訊息是否一致,如果一致,則客戶端認可這個伺服器的合法身份。
  4. 客戶端傳送客戶端證書給伺服器端,服務端在接收到證書後,通過私鑰解密證書,獲得客戶端證書公鑰,並用該公鑰認證證書資訊,確認客戶端是否合法。
  5. 客戶端通過隨機金鑰加密資訊,併發送加密後的資訊給服務端。在伺服器端和客戶端協商好加密方案後,客戶端會產生一個隨機的金鑰,客戶端通過協商好的加密方案加密該隨機金鑰,併發送該隨機金鑰到伺服器端。伺服器端接收這個金鑰後,雙方通訊的所有內容都通過該隨機金鑰加密。

上述是雙向認證SSL協議的具體通訊過程,這種情況要求伺服器和使用者雙方都有證書。單向認證SSL協議則不需要客戶端擁有CA證書,對於上面的步驟,只需將伺服器端驗證客戶證書的過程去掉,之後協商對稱密碼方案和對稱通話金鑰時,伺服器傳送給客戶的密碼沒被加密即可。

2.3 HTTP Token認證原理

HTTP Token的認證是用一個很長的特殊編碼方式的並且難以被模仿的字串—Token來表明客戶身份的一種方式。在通常情況下,Token是一個很複雜的字串,比如我們用私鑰簽名一個字串後的資料就可以被當作一個Token。此外,每個Token對應一個使用者名稱,儲存在API Server能訪問的一個檔案中。當客戶端發起API呼叫請求時,需要在HTTP Header裡放入Token,這樣一來,API Server就能識別合法使用者和非法使用者了。

2.4 HTTP Base認證原理

通常,HTTP是無狀態的,瀏覽器和Web伺服器之間可以通過Cookie來進行身份識別。桌面應用程式(比如新浪桌面客戶端、SkyDrive客戶端、命令列程式)一般不會使用Cookie,若需要與Web伺服器之間通訊並且進行認證。則需要使用HTTP Base認證,這種認證方式是把“使用者名稱+冒號+密碼”用BASE64演算法進行編碼後的字串放在HTTP Request中的Header Authorization域裡傳送給服務端,服務端在收到後進行解碼,獲取使用者名稱及密碼,然後進行使用者身份鑑權。

三 API Server授權管理

3.1 授權管理概述

當客戶端發起API Server呼叫時,API Server內部要先進行使用者認證,然後執行使用者授權流程,即通過授權策略來決定一個API呼叫是否合法。對合法使用者進行授權並且隨後在使用者訪問時進行鑑權,是許可權與安全系統的重要一環。 授權就是授予不同的使用者不同的訪問許可權。 API Server目前支援以下幾種授權策略(通過API Server的啟動引數“--authorization-mode”設定):
  1. AlwaysDeny:表示拒絕所有請求,一般用於測試。
  2. AlwaysAllow:允許接收所有請求,如果叢集不需要授權流程,則可以採用該策略,這也是Kubernetes的預設配置。
  3. ABAC(Attribute-BasedAccessControl):基於屬性的訪問控制,表示使用使用者配置的授權規則對使用者請求進行匹配和控制。
  4. Webhook:通過呼叫外部REST服務對使用者進行授權。
  5. RBAC:Role-BasedAccessControl,基於角色的訪問控制。
  6. Node:是一種專用模式,用於對kubelet發出的請求進行訪問控制。
API Server在接收到請求後,會讀取該請求中的資料,生成一個訪問策略物件,如果在該請求中不帶某些屬性(如Namespace),則這些屬性的值將根據屬性型別的不同,設定不同的預設值(例如,為字串型別的屬性設定一個空字串;為布林型別的屬性設定false;為數值型別的屬性設定0)。然後將這個訪問策略物件和授權策略檔案中的所有訪問策略物件逐條匹配,如果至少有一個策略物件被匹配,則該請求被鑑權通過,否則終止API呼叫流程,並返回客戶端的錯誤呼叫碼。

四 ABAC授權模式

4.1 ABAC授權策略

在API Server啟用ABAC模式時,需要指定授權策略檔案的路徑和名稱(--authorization-policy-file=SOME_FILENAME),授權策略檔案裡的每一行都以一個Map型別的JSON物件進行設定,這被稱為“訪問策略物件”。通過設定訪問策略物件中的apiVersion、kind、spec屬性來確定具體的授權策略。 其中,apiVersion當前版本為abac.authorization.kubernetes.io/v1beta1;kind被設定為Policy;spec指詳細的策略設定,包括主題屬性、資源屬性、非資源屬性這三個欄位。
  • 主體屬性
    • user(使用者名稱):字串型別,該字串型別的使用者名稱來源於Token檔案(--token-auth-file引數設定的檔案)或基本認證檔案中使用者名稱稱段的值。
    • group(使用者組):在被設定為“system:authenticated”時表示匹配所有已認證的請求,在被設定為“system:unauthenticated”時表示匹配所有未認證的請求。
  • 資源屬性
    • API Group(API組):字串型別,表明匹配哪些API Group,例如extensions或*(表示匹配所有API Group)。
    • namespace(名稱空間):字串型別,表明該策略允許訪問某個Namespace的資源,例如kube-system或*(表示匹配所有Namespace)。
    • resource(資源):字串型別,API資源物件,例如pods或*(表示匹配所有資源物件)。
  • 非資源屬性
    • nonResourcePath(非資源物件類路徑):非資源物件類的URL路徑,例如/version或/apis,*表示匹配所有非資源物件類的請求路徑,也可以設定為子路徑,/foo/*表示匹配所有/foo路徑下的所有子路徑。
    • readonly(只讀標識):布林型別,當它的值為true時,表明僅允許GET請求通過。

4.2 ABAC授權演算法

API Server進行ABAC授權的演算法為:在API Server收到請求之後,首先識別出請求攜帶的策略物件的屬性,然後根據在策略檔案中定義的策略對這些屬性進行逐條匹配,以判定是否允許授權。如果有至少一條匹配成功,那麼這個請求就通過了授權(不過還是可能在後續其他授權校驗中失敗)。 常見的策略配置如下:
  • 要允許所有認證使用者做某件事,可以寫一個策略,將group屬性設定為system:authenticated。
  • 要允許所有未認證使用者做某件事,可以把策略的group屬性設定為system:unauthenticated。
  • 要允許一個使用者做任何事,將策略的API Group、namespace、resource和nonResourcePath屬性設定為“*”即可。

4.3 使用kubectl授權機制

kubectl使用API Server的/api和/apis端點來獲取版本資訊。要驗證kubectlcreate/update命令傳送給伺服器的物件,kubectl需要向OpenAPI進行查詢,對應的URL路徑為/openapi/v2。 當使用ABAC授權模式時,下列特殊資源必須顯式地通過nonResourcePath屬性進行設定:
  • API版本協商過程中的/api、/api/*、/apis、和/apis/*。
  • 使用kubectlversion命令從伺服器獲取版本時的/version。
  • create/update操作過程中的/swaggerapi/*。
在使用kubectl操作時,如果需要檢視傳送到API Server的HTTP請求,則可以將日誌級別設定為8。

4.4 常見ABAC示例

更多ABAC參考:《附007.Kubernetes ABAC授權》。

五 RBAC授權模式

見《附006.Kubernetes RBAC授權