身份認證和存取控制包含兩部分準系統:認證和授權。認證即判斷使用者是否為能夠訪問叢集的合法使用者,授權負責管理指定使用者對資源的存取權限。
ACK叢集的認證和授權
Kubernetes使用X.509認證、Bearer Tokens、身分識別驗證代理或者OIDC認證等方式來對API請求進行身分識別驗證。關於ACK原生、訪問ACK叢集的兩種方式,請參見用戶端認證、服務賬戶令牌。
用戶端認證KubeConfig可以通過阿里雲控制台、ACK的OpenAPI介面等方式擷取。更多資訊,請參見擷取叢集KubeConfig介面。
Container Service Kubernetes 版授權包含RAM授權和RBAC授權兩部分。當您需要對叢集進行可見度、擴縮容、添加節點等操作時,需要進行自訂RAM授權策略。目前RAM主要支援RAM系統策略授權和RAM自訂策略授權兩種授權方式。當RAM使用者需要操作指定叢集內K8s資源時(例如,擷取叢集Pod和Node資訊),需要在Container Service管理主控台的授權管理頁面對指定RAM使用者進行資料平面資源的RBAC授權。更多資訊,請參見授權概述。
使用臨時KubeConfig和Apiserver認證
ACK預設返回的叢集訪問憑證KubeConfig中的認證有效期間是3年,若KubeConfig發生泄露,攻擊者可以直接獲得叢集Apiserver的存取權限。預設的ServiceAccount Token同樣是一種長期有效靜態憑據,如果泄露,攻擊者同樣可以獲得該ServiceAccount綁定的叢集存取權限,直到該ServiceAccount被刪除。
因此請您及時吊銷可能發生泄露的已下發KubeConfig憑證。具體操作,請參見吊銷叢集的KubeConfig憑證。關於ACK叢集的訪問憑證,請參見產生臨時的KubeConfig。
遵循許可權最小化原則訪問阿里雲資源
如果某個使用者需要訪問ACK叢集,無需為使用者指派訪問其他雲產品資源的許可權,保證使用者訪問雲產品資源許可權最小化。可以通過配置RAM和RBAC為該使用者授予訪問ACK叢集的許可權。
在建立RoleBindings和ClusterRoleBindings時使用最低存取權限
和授予訪問雲資源的許可權一樣,在建立
RoleBindings
和ClusterRoleBindings
時,同樣需要遵循許可權最小化原則。應該盡量避免在建立Role
和ClusterRole
時使用["*"]
,應該明確到具體的Verbs
。如果您不確定要分配哪些許可權,請考慮使用類似audit2rbac之類的工具,根據Kubernetes
審計日誌中觀察到的API調用自動產生角色和綁定。控制ACK叢集Endpoint的存取範圍
預設情況下,當您配置ACK叢集時,叢集的Apiserver Endpoint僅為內網訪問,即僅可以叢集和VPC內部訪問。關於建立出來的Service能夠實現公網訪問並控制Endpoint的存取範圍,請參見通過Annotation配置傳統型負載平衡CLB。
定期對叢集的存取權限進行審計
對叢集的存取權限可能會隨著時間的推移而改變。需要叢集的安全管理營運人員定期審核RAM配置以及為RAM使用者配置的RBAC許可權,來查看指定RAM使用者是否被分配了合適的許可權,或者使用開源工具來檢查綁定到特定服務賬戶、使用者或組的RBAC許可權,並及時收斂不符合需要的過大許可權配置。請參見kubectl-who-can和rbac-lookup。
Pods認證
在Kubernetes叢集中啟動並執行某些應用程式需要調用Kubernetes API的許可權才能正常運行。ACK CCM組件需要對Nodes資源進行增刪改查許可權。
Kubernetes Service Accounts
服務賬戶(Service Accounts)是一種特殊類型的對象,允許您將Kubernetes RBAC角色指派給Pod。K8s會為叢集中的每個命名空間自動建立一個預設服務賬戶。當您在不引用特定服務賬戶的情況下將Pod部署到命名空間時,該命名空間的預設服務賬戶將自動分配給Pod和Secret,即該服務賬戶的服務賬戶(JWT)令牌,將掛載到Pod作為一個卷位於/var/run/secrets/kubernetes.io/serviceaccount。解碼該目錄中的服務賬戶令牌將顯示以下中繼資料:
{ "iss": "kubernetes/serviceaccount", "kubernetes.io/serviceaccount/namespace": "default", "kubernetes.io/serviceaccount/secret.name": "default-token-vpc2x", "kubernetes.io/serviceaccount/service-account.name": "default", "kubernetes.io/serviceaccount/service-account.uid": "1d059c50-0818-4b15-905d-bbf05e1d****", "sub": "system:serviceaccount:default:default" }
預設服務賬戶對Kubernetes API具有以下許可權:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:discovery rules: - nonResourceURLs: - /api - /api/* - /apis - /apis/* - /healthz - /openapi - /openapi/* - /version - /version/ verbs: - get
此角色授予未經身分識別驗證和經過身分識別驗證的使用者讀取API資訊,並被視為可公開訪問的資訊安全角色。
當在Pod中啟動並執行應用程式調用Kubernetes API時,需要為Pod分配一個服務賬戶,明確授予其調用API的許可權。綁定到服務賬戶的Role或ClusterRole應僅限於應用程式運行所需的API資源和方法,遵循許可權最小化原則。要使用非預設服務賬戶,只需將Pod的
spec.serviceAccountName
欄位設定為您希望使用的服務賬戶。有關建立服務賬戶的其他資訊,請參見ServiceAccount permissions。部署服務賬戶令牌卷投影
您可以在Container ServiceACK中開啟服務賬戶令牌卷投影功能以降低在Pod中使用ServiceAccount遇到的安全性問題,此功能使得Kubelet支援基於Pod粒度的Token簽發,並且支援Token audience和到期時間的配置。當Token即將到期(到期時間的80%或者Token存在大於24小時),Kubelet支援對Token的自動重新整理。具體操作,請參見部署服務賬戶令牌卷投影。
限制節點對執行個體中繼資料API的訪問
ECS執行個體中繼資料概述包含了ECS執行個體在阿里雲系統中的資訊,您可以在運行中的執行個體內方便地查看執行個體中繼資料,並基於執行個體中繼資料配置或管理執行個體。執行個體中繼資料中能夠查詢到使用者使用的雲資源和使用者資料等敏感資訊,若不加限制地暴露給節點,在多租戶等情境下很容易被攻擊者利用。對於沒有出網需求的應用Pod,可以通過NetworkPolicy限制Pod對於meta-server的訪問。可以通過如下規則使用
podSelector
控制指定Pod對包括meta-server在內的所有出網訪問。apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-metadata-access namespace: example spec: podSelector: matchLabels: app: myapp policyTypes: - Egress egress: []
更多資訊,請參見在ACK叢集使用網路原則。
禁止Pod對Service Account令牌的自動掛載
可通過以下兩種方式取消Pod對Service Account令牌的自動掛載。
方式一:通過修改YAML將應用程式PodSpec欄位中的
automountServiceAccountToken
屬性設定為false
。apiVersion: v1 kind: Pod metadata: name: my-pod spec: serviceAccountName: build-robot automountServiceAccountToken: false ...
方式二:執行以下命令,patch命名空間中的預設服務賬戶,將
automountServiceAccountToken
屬性設定為false
。kubectl patch serviceaccount default -p $'automountServiceAccountToken: false'
為每個應用程式指派獨立的Service Account
每個應用程式都應該有自己專用的服務賬戶,便於不同應用之間的授權管理,實現應用維度細粒度許可權隔離。關於為應用程式指派獨立的服務賬戶,請參見為Pod佈建服務賬戶。
以非root使用者運行應用
預設情況下,容器以root身份運行。這允許容器中的進程對容器中的檔案進行任意的讀取和寫入,但以root身份運行容器並不是最佳安全實踐。作為替代方案,請考慮將
spec.securityContext.runAsUser
屬性添加到PodSpec
。runAsUser
的值為任意值。在以下樣本中,Pod中的所有進程都將在
runAsUser
欄位中指定的使用者ID下運行。apiVersion: v1 kind: Pod metadata: name: security-test spec: securityContext: runAsUser: 1000 runAsGroup: 3000 containers: - name: sec-test image: busybox command: [ "sh", "-c", "sleep 1h" ]
此時,對於容器中需要root許可權才能訪問的檔案,容器中的進程則無法訪問。如果您更新容器的
securityContext
,使其包含fsgroup=65534 [Nobody]
,將允許讀取容器中的檔案。spec: securityContext: fsGroup: 65534
遵循許可權最小化原則分配應用對雲上阿里雲資源的存取權限
避免為應用所在節點分配不必要的RAM許可權,遵循許可權最小化原則細粒度定製應用所需的RAM策略,避免在權限原則中出現
["*"]
等可能擴大存取權限的配置。
Authenticator Webhook認證
對於通過RAM SSO整合以及對Kubernetes RBAC授權管理有獨立營運經驗的使用者,推薦通過ack-ram-authenticator完成ACK託管叢集APIServer的Webhook認證,通過使用ack-ram-authenticator,可以實現如下優勢:
對於使用Authenticator KubeConfig的Apiserver請求,審計日誌會記錄SSO情境下企業IDP中的身份資訊,對扮演同一角色的不同IDP使用者的行為進行審計。
靈活可控的資料面RBAC授權體驗。
當刪除RAM使用者或角色時,可自動吊銷其已下發的Authenticator KubeConfig憑據許可權。