Kubernetes 安全性仰賴穩固的驗證與授權機制。本文解析多種驗證方法,包含 X.509 憑證的建立與核准流程、靜態權杖及基本驗證的簡易性、引導權杖的動態管理、服務帳戶的自動化特性,以及 Webhook 的外部整合能力。同時,文章探討 RBAC、ABAC 和 Node 等授權模式,並說明 Admission Controllers 如何強化叢集安全。最後,介紹 Open Policy Agent (OPA) 作為原則引擎,如何實作更精細的存取控制,並提供 Rego 語言範例說明如何限制特定 Pod 的建立。

Kubernetes 身份驗證機制詳解

Kubernetes 提供了多種身份驗證機制,以確保叢集的安全性和可靠性。本文將探討 Kubernetes 中的各種身份驗證方法,包括 X.509 使用者端憑證、靜態權杖、基本身份驗證、引導權杖、服務帳戶權杖和 Webhook 權杖。

X.509 使用者端憑證

X.509 使用者端憑證是一種使用公開金鑰基礎設施(PKI)進行身份驗證的方法。使用者端憑證用於驗證使用者或服務的身分。在 Kubernetes 中,可以使用 kube-apiserver--client-ca-file 引數指定受信任的 CA 憑證。

建立憑證簽署請求(CSR)

要使用 X.509 使用者端憑證,首先需要建立一個憑證簽署請求(CSR)。可以使用 OpenSSL 工具建立 CSR:

openssl req -new -newkey rsa:2048 -nodes -keyout new.key -out new.csr -subj "/CN=newuser"

建立 Kubernetes 憑證簽署請求

接下來,需要建立一個 Kubernetes 憑證簽署請求 YAML 檔案:

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: mycsr
spec:
  request: ${BASE64_CSR}
  usages:
  - digital signature
  - key encipherment
  - server auth
  - client auth

將 CSR 的 base64 編碼值替換到 request 欄位中,並套用 YAML 檔案:

export BASE64_CSR=$(cat ./new.csr | base64 | tr -d '\n')
cat csr.yaml | envsubst | kubectl apply -f -

核准憑證簽署請求

建立 CSR 後,需要由叢集管理員核准:

kubectl certificate approve mycsr

匯出 CRT

核准後,可以匯出 CRT 檔案:

kubectl get csr mycsr -o jsonpath='{.status.certificate}' | base64 --decode > new.crt

靜態權杖

靜態權杖是一種簡單的身份驗證方法,使用一個靜態檔案儲存權杖資訊。然而,這種方法不建議在生產環境中使用,因為權杖無法變更,除非重新啟動 API 伺服器。

基本身份驗證

基本身份驗證是另一種簡單的身份驗證方法,使用使用者名稱和密碼進行驗證。同樣地,這種方法也不建議在生產環境中使用。

引導權杖

引導權杖是 Kubernetes 的預設身份驗證方法。它們是動態管理的,並儲存在 kube-system 名稱空間中的 Secret 中。

啟用引導權杖

要啟用引導權杖,需要在 API 伺服器中設定 --enable-bootstrap-token-auth 引數,並在控制器管理器中啟用 tokencleaner

服務帳戶權杖

服務帳戶權杖是一種自動啟用的身份驗證方法,用於驗證服務帳戶的身分。服務帳戶與 Pod 相關聯,並包含一個簽署的權杖。

建立服務帳戶

可以使用以下命令建立服務帳戶:

kubectl create serviceaccount test

檢視服務帳戶 Secret

可以使用以下命令檢視服務帳戶的 Secret:

kubectl get secret test-token-sdq2d -o yaml

Webhook 權杖

Webhook 權杖允許 Kubernetes 使用外部的 REST API 進行身份驗證。可以透過設定 --authorization-webhook-config-file 引數來啟用 Webhook 身份驗證。

Webhook 設定範例

以下是一個 Webhook 設定範例:

clusters:
- name: name-of-remote-authn-service
  cluster:
    certificate-authority: /path/to/ca.pem
    server: https://authn.example.com/authenticate

Kubernetes 驗證機制深入解析

Kubernetes 的驗證機制是確保叢集安全性的重要組成部分。除了傳統的使用者名稱和密碼驗證外,Kubernetes 還支援多種驗證方式,包括遠端服務驗證、驗證代理和使用者模擬等。

驗證代理(Authentication Proxy)

驗證代理是一種允許 kube-apiserver 使用 X-Remote 請求標頭來識別使用者的方法。要啟用此方法,需要在 API 伺服器中新增以下引數:

  • --requestheader-username-headers=X-Remote-User
  • --requestheader-group-headers=X-Remote-Group
  • --requestheader-extra-headers-prefix=X-Remote-Extra-

每個請求都需要包含以下標頭來識別使用者:

  • X-Remote-User: foo
  • X-Remote-Group: bar
  • X-Remote-Extra-Scopes: profile

API 代理使用 CA 來驗證請求。

程式碼範例:驗證代理設定

kube-apiserver --requestheader-username-headers=X-Remote-User \
               --requestheader-group-headers=X-Remote-Group \
               --requestheader-extra-headers-prefix=X-Remote-Extra-

內容解密:

此設定啟用了驗證代理功能,並指定了用於識別使用者的請求標頭。其中,X-Remote-User 用於指定使用者名稱,X-Remote-Group 用於指定使用者群組,X-Remote-Extra-Scopes 用於指定額外的範圍資訊。

使用者模擬(User Impersonation)

叢集管理員和開發人員可以使用使用者模擬來除錯新使用者的驗證和授權策略。要使用使用者模擬,使用者必須被授予模擬特權。API 伺服器使用以下標頭來模擬使用者:

  • Impersonate-User
  • Impersonate-Group
  • Impersonate-Extra-*

一旦 API 伺服器收到模擬標頭,就會驗證使用者是否已透過驗證並具有模擬特權。如果是,則請求將以模擬使用者的身份執行。

程式碼範例:使用 kubectl 進行使用者模擬

kubectl apply -f pod.yaml --as=dev-user --as-group=system:dev

內容解密:

此命令使用 kubectl 進行使用者模擬,將請求以 dev-user 使用者的身份執行,並隸屬於 system:dev 群組。其中,--as 引數用於指定模擬使用者,--as-group 引數用於指定模擬使用者的群組。

Kubernetes 授權機制

Kubernetes 的授權機制決定了請求是否被允許或拒絕。一旦請求的來源被識別出來,活躍的授權模組就會評估請求的屬性,以決定是否允許或拒絕請求。

請求屬性(Request Attributes)

授權模組會解析請求中的一組屬性,以決定是否允許或拒絕請求。這些屬性包括:

  • 使用者(User):請求的發起者。
  • 群組(Group):使用者所屬的群組。
  • API:請求的目的地。
  • 請求動詞(Request Verb):請求的型別,例如 GET、CREATE、PATCH、DELETE 等。
  • 資源(Resource):被存取的資源的 ID 或名稱。
  • 名稱空間(Namespace):資源所屬的名稱空間。
  • 請求路徑(Request Path):如果請求是針對非資源端點,則使用路徑來檢查使用者是否被允許存取該端點。

授權模式(Authorization Modes)

Kubernetes 提供了多種授權模式,包括 Node、ABAC 和 RBAC 等。

Node 授權模式

Node 授權模式授予 kubelet 存取服務、端點、節點、Pod、秘密和持久性儲存區的許可權。kubelet 被識別為 system:nodes 群組的一部分,使用者名稱為 system:node:<name>

ABAC 授權模式

ABAC 授權模式透過驗證策略與請求屬性的比對來允許請求。ABAC 可以透過在 API 伺服器中使用 --authorization-policy-file=<path>--authorization-mode=ABAC 來啟用。

程式碼範例:ABAC 策略
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy", "spec": {"user": "kubelet", "namespace": "*",
"resource": "pods", "readonly": true}}
內容解密:

此策略允許 kubelet 讀取任何 Pod。其中,apiVersion 指定了策略的 API 版本,kind 指定了策略的型別,spec 指定了策略的詳細內容,包括使用者、名稱空間、資源和讀取許可權等。

RBAC 授權模式

RBAC 授權模式使用角色和角色繫結來規範對資源的存取。RBAC 從 v1.8 版本開始在許多叢集中預設啟用。要啟用 RBAC,需要在 API 伺服器中使用 --authorization-mode=RBAC

程式碼範例:Role 和 RoleBinding
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  namespace: default
  name: deployment-manager
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: binding
  namespace: default
subjects:
- kind: User
  name: employee
內容解密:

此範例定義了一個 Role 和一個 RoleBinding,用於授予 employee 使用者在 default 名稱空間中建立和修改 Pod 的許可權。其中,Role 指定了允許的操作,RoleBinding 將 Role 繫結到指定的使用者。

Kubernetes 授權機制深度解析

Kubernetes 的授權機制是確保叢集安全性的關鍵組成部分。本篇文章將探討 Kubernetes 中的 RoleBinding、Webhook 授權模式以及 Admission Controllers,幫助讀者全面理解 Kubernetes 的授權流程。

RoleBinding 與許可權控制

在 Kubernetes 中,RoleBinding 是用於將角色(Role)繫結到使用者或服務帳戶(ServiceAccount)的重要機制。以下是一個 RoleBinding 的範例:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployment-manager-binding
roleRef:
  kind: Role
  name: deployment-manager
subjects:
- kind: User
  name: employee
  apiGroup: rbac.authorization.k8s.io

內容解密:

  1. apiVersionkind 定義了該物件的 API 版本和型別。
  2. metadata 包含了 RoleBinding 的名稱。
  3. roleRef 指定了要繫結的角色名稱和種類別。
  4. subjects 列出了該 RoleBinding 所繫結的使用者或服務帳戶。

當套用這個 RoleBinding 後,使用 employee-context 上下文執行 kubectl get pods 可以成功列出 Pod,但嘗試列出 Deployments 時會收到 Forbidden 錯誤,因為該 Role 沒有被授權存取 Deployments 資源。

$ kubectl --context=employee-context get pods
NAME READY STATUS RESTARTS AGE
hello-node-677b9cfc6b-xks5f 1/1 Running 0 12m

$ kubectl --context=employee-context get deployments
Error from server (Forbidden): deployments.apps is forbidden: User "employee" cannot list resource "deployments" in API group "apps" in the namespace "default"

這顯示了 RoleBinding 如何精細控制使用者對 Kubernetes 資源的存取許可權。

Webhook 授權模式

Webhook 是一種遠端授權機制,允許 Kubernetes 將授權請求傳送到外部服務進行驗證。要啟用 Webhook 授權模式,需要使用 --authorization-webhook-config-file 標誌指定設定檔。

以下是一個 Webhook 設定檔的範例:

clusters:
- name: authz_service
  cluster:
    certificate-authority: ca.pem
    server: https://authz.remote/

內容解密:

  1. clusters 定義了遠端授權服務的叢集資訊。
  2. name 指定了叢集的名稱。
  3. certificate-authority 指定了用於驗證遠端服務憑證的 CA 憑證。
  4. server 指定了遠端授權服務的 URL。

Webhook 授權模式提供了一種靈活的方式來整合外部授權系統與 Kubernetes。

Admission Controllers

Admission Controllers 是 Kubernetes 中的一種機制,用於在請求被認證和授權後攔截請求並進行驗證或修改。以下是一些重要的 Admission Controllers:

  1. AlwaysPullImages:強制每次建立 Pod 時都提取映像檔,確保使用最新的映像檔並防止未授權的使用者存取私有映像檔。
  2. EventRateLimit:限制事件請求的速率,防止拒絕服務攻擊(DoS)。
  3. LimitRanger:確保 Pod 不會超出指定的資源限制,防止資源濫用。
  4. NodeRestriction:限制 kubelet 可以修改的節點和 Pod,防止 kubelet 修改其他節點上的資源。
  5. PodSecurityPolicy:根據安全敏感組態檢查 Pod 是否允許建立或修改,增強叢集的安全性。

這些 Admission Controllers 可以透過 --enable-admission-plugins--disable-admission-plugins 標誌進行啟用或停用。

Kubernetes 中的認證、授權與准入控制深入解析

深入理解 OPA 與其在 Kubernetes 中的應用

在前面的章節中,我們詳細探討了 Kubernetes 中的認證與授權機制。本文將重點介紹 Open Policy Agent(OPA),一個強大的開放原始碼原則引擎,能夠在 Kubernetes 環境中實作細粒度的存取控制。

為什麼需要 OPA?

在 Kubernetes 環境中,隨著叢集規模的擴大和複雜度的增加,傳統的認證和授權機制可能無法滿足日益增長的安全需求。OPA 的出現正是為瞭解決這一問題,它允許管理員定義和執行複雜的安全原則,從而實作更精細的存取控制。

OPA 的工作原理

OPA 作為一個獨立的服務佈署在 Kubernetes 叢集中。當微服務需要進行授權決策時,它會向 OPA 傳送請求,詢問是否允許該請求。OPA 根據預先定義的原則和叢集的當前狀態做出決定,並將結果傳回給微服務。

在 Kubernetes 中,OPA 通常被用作驗證 Webhook,以實作對資源操作的細粒度控制。

OPA 的核心元件

  1. 叢集資訊:OPA 需要了解叢集的當前狀態,包括叢集中的物件和資源。
  2. 輸入查詢:OPA 接收來自 Kubernetes API 的請求引數,並根據這些引數進行決策。
  3. 原則:使用 Rego 語言定義的原則是 OPA 做出決策的核心。這些原則定義瞭如何解析叢集資訊和輸入查詢,以傳回最終的決策結果。

使用 OPA 限制 Pod 建立

以下是一個使用 OPA 限制建立使用 busybox 映像的 Pod 的範例:

package kubernetes.admission

import data.kubernetes.namespaces

operations = {"CREATE", "UPDATE"}

deny[msg] {
    input.request.kind.kind == "Pod"
    operations[input.request.operation]
    image := input.request.object.spec.containers[_].image
    image == "busybox"
    msg := sprintf("不允許使用映像 %q", [image])
}

此原則檢查建立或更新 Pod 的請求,如果請求中包含 busybox 映像,則拒絕該請求並傳回錯誤訊息。

要套用此原則,首先需要建立一個 ConfigMap:

kubectl create configmap pod-blacklist --from-file=pod-blacklist.rego

然後,kube-mgmt 會將 ConfigMap 中的原則載入到 OPA 容器中。當嘗試建立使用 busybox 映像的 Pod 時,OPA 將拒絕該請求:

$ cat busybox.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - name: sec-ctx-demo
    image: busybox
    command: [ "sh", "-c", "sleep 1h" ]

錯誤訊息如下:

admission webhook "validating-webhook.openpolicyagent.org" denied the request: 不允許使用映像 "busybox"
重點回顧
  1. OPA 的角色:OPA 是一個開放原始碼原則引擎,用於在 Kubernetes 中實作細粒度的存取控制。
  2. OPA 的工作原理:OPA 作為一個獨立服務佈署,並根據預先定義的原則和叢集狀態做出授權決策。
  3. 使用 OPA 的好處:能夠實作比傳統認證和授權機制更精細的存取控制。

練習與思考

  1. 如何在 Kubernetes 叢集中佈署 OPA?
  2. 編寫一個 Rego 原則,以限制使用特定標籤的 Pod 建立。
  3. 分析 OPA 在生產環境中的應用場景。

進一步閱讀