一 Kubernetes集群安全 1.1 安全機制 Kubernetes通過一系列機制來實現集群的安全控制,其中包括API Server的認證授權、準入控制機制及保護敏感信息的Secret機制等。集群的安全性主要有如下目標: 保證容器與其所在宿主機的隔離。 限制容器給基礎設施或其他容器帶來的干擾。 ...
一 Kubernetes集群安全
1.1 安全機制
Kubernetes通過一系列機制來實現集群的安全控制,其中包括API Server的認證授權、準入控制機制及保護敏感信息的Secret機制等。集群的安全性主要有如下目標:- 保證容器與其所在宿主機的隔離。
- 限制容器給基礎設施或其他容器帶來的干擾。
- 最小許可權原則—合理限制所有組件的許可權, 確保組件只執行它被授權的行為, 通過限制單個組件的能力來限制它的許可權範圍。
- 明確組件間邊界的劃分。
- 劃分普通用戶和管理員的角色。
- 在必要時允許將管理員許可權賦給普通用戶。
- 允許擁有Secret數據(Keys、 Certs、 Passwords) 的應用在集群中運行。
二 API Server認證管理
2.1 認證安全
Kubernetes集群中所有資源的訪問和變更都是通過Kubernetes API Server的RESTAPI來實現的,因此集群安全的關鍵點就在於如何識別並認證客戶端身份(Authentication),以及隨後訪問許可權的授權(Authorization)環節。 Kubernetes集群提供了3種級別的客戶端身份認證方式。- HTTPS證書認證:此方式最嚴格,基於CA根證書簽名的雙向數字證書認證方式。
- HTTP Token認證:通過一個Token來識別合法用戶。
- 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中認證大概包含下麵幾個步驟:
- HTTPS通信雙方的伺服器端向CA機構申請證書,CA機構是可信的第三方機構,它可以是一個公認的權威企業,也可以是企業自身。企業內部系統一般都用企業自身的認證系統。CA機構下髮根證書、服務端證書及私鑰給申請者。
- HTTPS通信雙方的客戶端向CA機構申請證書,CA機構下髮根證書、客戶端證書及私鑰給申請者。
- 客戶端向伺服器端發起請求,服務端下發服務端證書給客戶端。客戶端接收到證書後,通過私鑰解密證書,並利用伺服器端證書中的公鑰認證證書信息比較證書里的消息,例如,比較功能變數名稱和公鑰與伺服器剛剛發送的相關消息是否一致,如果一致,則客戶端認可這個伺服器的合法身份。
- 客戶端發送客戶端證書給伺服器端,服務端在接收到證書後,通過私鑰解密證書,獲得客戶端證書公鑰,並用該公鑰認證證書信息,確認客戶端是否合法。
- 客戶端通過隨機密鑰加密信息,併發送加密後的信息給服務端。在伺服器端和客戶端協商好加密方案後,客戶端會產生一個隨機的密鑰,客戶端通過協商好的加密方案加密該隨機密鑰,併發送該隨機密鑰到伺服器端。伺服器端接收這個密鑰後,雙方通信的所有內容都通過該隨機密鑰加密。
上述是雙向認證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”設置):- AlwaysDeny:表示拒絕所有請求,一般用於測試。
- AlwaysAllow:允許接收所有請求,如果集群不需要授權流程,則可以採用該策略,這也是Kubernetes的預設配置。
- ABAC(Attribute-BasedAccessControl):基於屬性的訪問控制,表示使用用戶配置的授權規則對用戶請求進行匹配和控制。
- Webhook:通過調用外部REST服務對用戶進行授權。
- RBAC:Role-BasedAccessControl,基於角色的訪問控制。
- Node:是一種專用模式,用於對kubelet發出的請求進行訪問控制。
四 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/*。