Kubernetes 中的名稱空間隔離是安全的重要環節,透過 Open Policy Agent(OPA)可以有效限制非管理員使用者存取關鍵名稱空間,例如 kube-system。OPA 提供了根據 Rego 語言的策略定義,可以根據使用者群組和請求的名稱空間進行精細的存取控制。此外,Kubernetes 授權 Webhook 能夠根據已認證主體資訊控制 API 伺服器的存取請求,但其在動態准入控制器中存在資訊不可用的限制。PolicyReport 提供了標準化的 PaC 報告格式,可以透過 kubectl 檢視 Kyverno 等工具產生的報告,協助驗證 PaC 方案的有效性。OPA 與 Kubernetes 的整合需要組態動態准入控制,並設定 Webhook 超時和失敗策略以維護叢集穩定性。自動化安裝指令碼可以簡化 OPA 的佈署流程,透過範本和變數定義,自動生成 Namespace 組態和 TLS 證書,減少人為錯誤並提高效率。

Kubernetes中的Policy as Code(PaC)與授權管理

Admin Namespaces的存取控制

在Kubernetes中,對於特定名稱空間(namespaces)的存取控制是安全管理的關鍵部分。以下是一個使用Open Policy Agent(OPA)實作的範例,展示瞭如何限制非管理員使用者存取特定的管理名稱空間:

# 定義需要受保護的管理員名稱空間
admin_nss := ["kube-system", "admin", "opa"]

# 非管理員使用者禁止存取管理員名稱空間的規則
deny[reason] {
    input.spec.resourceAttributes.namespace in admin_nss
    not "admin" in input.spec.groups
    reason := "非管理員使用者禁止存取管理員名稱空間。"
}

# 生成SubjectAccessReview決策
decision = {
    "apiVersion": "v1",
    "kind": "SubjectAccessReview",
    "status": {
        "allowed": count(deny) == 0,
        "deny": count(deny) > 0,
        "reason": concat(" | ", deny),
    },
}

內容解密:

  1. admin_nss定義:這裡定義了一個包含特定管理名稱空間的陣列,例如kube-systemadminopa
  2. deny規則:這條規則檢查請求的名稱空間是否在admin_nss中,以及發起請求的使用者是否不屬於admin群組。如果兩者皆符合,則拒絕該請求並提供相應的原因。
  3. decision生成:根據deny規則的結果,生成一個SubjectAccessReview物件,決定是否允許該請求。

Kubernetes授權(AuthZ)Webhook的限制

Kubernetes的授權Webhook用於根據已認證的主體資訊允許或拒絕對Kubernetes API伺服器的存取請求。然而,這些資訊在動態准入控制器處理過程中是不可用的,除非以非授權的方式新增到輸入請求中。

內容解密:

  1. 授權Webhook的功能:授權Webhook根據認證資訊來控制對Kubernetes API的存取。
  2. 動態准入控制器的限制:動態准入控制器無法直接用於授權檢查,因為相關的認證資訊不可用。
  3. AWS EKS的簡化存取管理控制:AWS在2023年12月推出了根據Kubernetes授權功能的簡化EKS存取管理控制。

PaC報告的實作與應用

不同的PaC解決方案提供不同的報告和日誌記錄機制。Kubernetes Policy Working Group定義了一個名為PolicyReport的開放格式,用於標準化PaC報告。

檢視PolicyReport CRD的定義

$ kubectl get crd policyreports.wgpolicyk8s.io -oyaml

列出叢集中的API資源

$ kubectl api-resources | grep pod

檢視特定資源的API說明

$ kubectl explain pod.spec.containers.name

PolicyReport的使用範例

以下是一個由Kyverno產生的Namespace-scoped PolicyReport範例:

# 列出kyverno名稱空間中的PolicyReports
$ kubectl -n kyverno get policyreports.wgpolicyk8s.io

# 檢視特定的PolicyReport詳細資訊
$ kubectl -n kyverno get policyreports.wgpolicyk8s.io cpol-example -o yaml

內容解密:

  1. PolicyReport結構:展示了Kyverno產生的PolicyReport結構,包括透過、失敗、警告等檢查結果。
  2. PolicyReport的作用:作為人類可讀和機器可讀的工件,用於驗證PaC解決方案的有效性,並滿足內外部監管要求。

圖表說明:Kubernetes PaC架構圖

  graph LR;
    A[Kubernetes API Server] -->|Admission Review|> B[Dynamic Admission Controller];
    B -->|Validate/Mutate|> C[Policy Engine];
    C -->|Policy Decision|> D[Allow/Deny];
    D -->|Response|> A;

圖表翻譯: 此圖示展示了Kubernetes中動態准入控制的工作流程,包括API Server接收請求、准入控制器處理請求、策略引擎進行驗證或修改,最終傳回允許或拒絕的決定。

OPA與Kubernetes的整合應用

在前面的章節中,我們探討了Policy as Code(PaC)的基本概念,並在第2章中介紹了Open Policy Agent(OPA)。本章將探討OPA在Kubernetes環境中的應用,包括安裝、元件介紹,以及如何使用OPA進行Kubernetes特定的政策管理。

OPA簡介

OPA是一種領域無關的PaC解決方案,能夠評估Rego政策並對提交的資料進行驗證。作為一個成熟的開源專案,OPA擁有活躍的開發者和使用者社群。相關資源包括:

  • GitHub專案
  • 官方網站
  • Slack社群
  • CNCF頁面

本章的範例將在文中提供,或可在配套的GitHub儲存函式庫中找到。

OPA安裝

在Kubernetes中安裝OPA,需要組態動態准入控制(dynamic admission control)。Kubernetes的API伺服器在啟動時會載入准入控制器,其中包括變更准入Webhook(mutating admission webhook)和驗證准入Webhook(validating admission webhook)。這些Webhook允許我們將OPA組態為准入控制服務,而無需在API伺服器啟動時以自定義設定載入。

圖5-1:OPA-Kubernetes安裝架構

  graph LR
    A[Kubernetes API Server] -->|Dynamic Admission Control|> B[OPA Service]
    B --> C[OPA Server]
    C --> D[kube-mgmt Sidecar]

圖表翻譯: 此圖示展示了OPA在Kubernetes叢集中的安裝架構。Kubernetes API伺服器透過動態准入控制呼叫OPA服務,後者與OPA伺服器和kube-mgmt sidecar容器互動。

驗證准入Webhook組態

要正確安裝OPA,需要組態Webhook組態以滿足所需的准入控制型別。以下範例展示瞭如何組態ValidatingWebhookConfiguration資源,以便API伺服器能夠呼叫OPA服務來驗證傳入請求。

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: opa-validating-webhook
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    service:
      name: opa
      namespace: opa
      port: 443
  failurePolicy: Fail
  matchPolicy: Equivalent
  name: validating-webhook.openpolicyagent.org
  namespaceSelector:
    matchExpressions:
    - key: openpolicyagent.org/webhook
      operator: NotIn
      values:
      - ignore
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: ["*"]
    apiVersions: ["v1"]
    resources: ["pods","deployments","services"]
    scope: '*'
  sideEffects: None
  timeoutSeconds: 10

內容解密:

此YAML組態定義了一個ValidatingWebhookConfiguration資源,用於設定API伺服器呼叫OPA服務進行驗證。主要組態包括:

  • failurePolicy: Fail:當Webhook呼叫失敗或超時時,阻止變更。
  • namespaceSelector:排除標有openpolicyagent.org/webhook=ignore的Namespace。
  • rules:指定需要驗證的操作(CREATE和UPDATE)、資源型別(pods、deployments、services)等。
  • timeoutSeconds: 10:設定Webhook呼叫的超時時間為10秒。

安裝與組態重點

  1. 動態准入控制:透過變更和驗證准入Webhook實作對叢集資源的動態控制。
  2. Webhook超時與失敗策略:合理組態timeoutSecondsfailurePolicy,以確保叢集的穩定性。
  3. Namespace選擇器:使用namespaceSelector排除系統Namespace(如kube-system),避免影響叢集核心元件。

隨著Kubernetes叢集規模的擴大和複雜度的增加,使用OPA進行統一的政策管理變得尤為重要。未來可以進一步探索OPA在多叢集環境下的應用,以及如何與其他PaC工具進行整合,以實作更全面的安全性和合規性管理。

自動化安裝與管理 Open Policy Agent (OPA)

在前一章中,我們學習瞭如何手動安裝和組態 OPA 以及驗證 Webhook。本章將重點介紹如何使用自動化指令碼簡化 OPA 的安裝和組態過程,以減少人為錯誤並提高效率。

自動化安裝指令碼解析

自動化安裝指令碼 up.sh 是一個 Bash 指令碼,用於簡化 OPA 的安裝過程。以下是該指令碼的關鍵部分:

#!/usr/bin/env bash

# 錯誤處理
set -e
trap 'catch $? $LINENO' ERR

catch() {
  if [ "$1" != "0" ]; then
    echo "Error $1 occurred on $2"
  fi
}

OWNER="jimmy"
ENV="dev"
BILLING="lob-cc"
KUBECTL="kubectl"
CA_BUNDLE=""
CONFIGS_DIRECTORY="generated/configs"
SECRETS_DIRECTORY="generated/secrets"
TEMPLATES_DIRECTORY="templates"
POLICY_CM_DIRECTORY="../policy-configmaps/deploy"

# 檢查範本目錄是否存在
if [ ! -d "$TEMPLATES_DIRECTORY" ]; then
  echo "$TEMPLATES_DIRECTORY not found, install aborted"
  exit 99
fi

# 建立必要的目錄
if [ ! -d "$CONFIGS_DIRECTORY" ]; then
  mkdir -p $CONFIGS_DIRECTORY
fi

if [ ! -d "$SECRETS_DIRECTORY" ]; then
  mkdir -p $SECRETS_DIRECTORY
fi

# 清除之前的組態和金鑰
rm -f $CONFIGS_DIRECTORY/*
rm -f $SECRETS_DIRECTORY/*

# 使用範本生成 Namespace 組態檔案
cat $TEMPLATES_DIRECTORY/ns-template.yaml | sed -e "s/__OWNER_VALUE__/${OWNER}/g" \
  | sed -e "s/__ENV_VALUE__/${ENV}/g" \
  | sed -e "s/__BILLING_VALUE__/${BILLING}/g" \
  > "$CONFIGS_DIRECTORY/ns.yaml"

# 應用 Namespace 組態
${KUBECTL} apply -f $CONFIGS_DIRECTORY/ns.yaml

內容解密:

  1. 錯誤處理機制:指令碼使用 set -etrap 命令來捕捉和處理錯誤,確保在發生錯誤時能夠正確離開並顯示錯誤資訊。
  2. 變數定義:定義了多個變數,如 OWNERENVBILLING 等,用於自定義安裝組態。
  3. 目錄檢查與建立:檢查必要的目錄是否存在,如果不存在則建立它們,以確保安裝過程順利進行。
  4. 範本處理:使用 sed 命令將範本檔案 ns-template.yaml 中的佔位符替換為實際值,生成最終的 Namespace 組態檔案。

生成 TLS 證書和金鑰

接下來,指令碼生成 TLS 證書和金鑰,以便 OPA 可以使用自簽名證書執行:

# 生成 TLS 證書和金鑰
openssl genrsa -out $SECRETS_DIRECTORY/opa-ca.key 2048
openssl req -x509 -new -nodes -sha256 -key $SECRETS_DIRECTORY/opa-ca.key \
  -days 100000 -out $SECRETS_DIRECTORY/opa-ca.crt -subj /CN=admission_ca 2>&1
openssl genrsa -out $SECRETS_DIRECTORY/opa-server.key 2048
openssl req -new -key $SECRETS_DIRECTORY/opa-server.key -sha256 -out \
  $SECRETS_DIRECTORY/opa-server.csr -subj /CN=opa.opa.svc -config \
  $TEMPLATES_DIRECTORY/opa-server.conf 2>&1
openssl x509 -req -in $SECRETS_DIRECTORY/opa-server.csr -sha256 -CA \
  $SECRETS_DIRECTORY/opa-ca.crt -CAkey $SECRETS_DIRECTORY/opa-ca.key \
  -CAcreateserial -out $SECRETS_DIRECTORY/opa-server.crt -days 100000 \
  -extensions v3_ext -extfile $TEMPLATES_DIRECTORY/opa-server.conf

# 建立 TLS Secret
echo "Trying to delete \"opa-server\" secret..."
${KUBECTL} -n opa delete secret opa-server --ignore-not-found 2>&1
${KUBECTL} -n opa create secret tls opa-server \
  --cert=$SECRETS_DIRECTORY/opa-server.crt \
  --key=$SECRETS_DIRECTORY/opa-server.key

內容解密:

  1. 生成 CA 私鑰和證書:使用 OpenSSL 生成 CA 私鑰和自簽名證書。
  2. 生成伺服器私鑰和 CSR:為 OPA 伺服器生成私鑰和證書籤名請求(CSR)。
  3. 簽署伺服器證書:使用 CA 證書和私鑰簽署 OPA 伺服器的 CSR,生成伺服器證書。
  4. 建立 Kubernetes Secret:將生成的 TLS 證書和私鑰儲存為 Kubernetes Secret,供 OPA 使用。

自動化安裝的優勢

透過使用自動化指令碼,可以簡化 OPA 的安裝和組態過程,降低人為錯誤的風險,並提高佈署效率。此外,自動化指令碼還可以輕鬆地重複使用和擴充套件,以適應不同的環境和需求。

未來,我們可以進一步最佳化自動化指令碼,例如增加更多的錯誤處理機制、支援更多的自定義選項等,以提高指令碼的魯棒性和靈活性。此外,還可以探索將自動化指令碼整合到 CI/CD 管道中,以實作更高效的持續整合和持續佈署。

  graph LR;
    A[開始安裝] --> B[檢查範本目錄];
    B -->|存在| C[建立必要目錄];
    B -->|不存在| D[離開安裝];
    C --> E[生成Namespace組態];
    E --> F[應用Namespace組態];
    F --> G[生成TLS證書和金鑰];
    G --> H[建立TLS Secret];
    H --> I[完成安裝];

圖表翻譯: 此圖表展示了 OPA 自動化安裝的主要步驟。首先,檢查範本目錄是否存在。如果存在,則建立必要的目錄並繼續安裝過程;如果不存在,則離開安裝。接下來,生成 Namespace 組態檔案並應用到 Kubernetes 叢集中。然後,生成 TLS 證書和金鑰,並建立 TLS Secret。最後,完成 OPA 的安裝。