本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
Pod 安全性
Pod 規格包含各種不同的屬性,可強化或削弱您的整體安全狀態。身為 Kubernetes 從業人員,您的首要考量應該是防止容器中執行的程序逸出容器執行時間的隔離界限,並取得基礎主機的存取權。
Linux 功能
根據預設,在容器內執行的程序會在 【Linux】 根使用者的內容下執行。雖然容器內根的動作部分受限於容器執行時間指派給容器的一組 Linux 功能,但這些預設權限可能允許攻擊者提升其權限和/或存取繫結至主機的敏感資訊,包括 Secrets 和 ConfigMaps。以下是指派給容器的預設功能清單。如需每個功能的詳細資訊,請參閱 https://http://man7.org/linux/man-pages/man7/capabilities.7.html
CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SETGID, CAP_SETUID, CAP_SETFCAP, CAP_SETPCAP, CAP_SYS_CHROOT
預設會指派上述功能給 EC2 和 Fargate Pod。此外,Linux 功能只能從 Fargate Pod 捨棄。
以特殊權限執行的 Pod,會繼承與主機根相關聯的所有 Linux 功能。如果可能,應該避免這種情況。
節點授權
所有 Kubernetes 工作者節點都使用稱為 Node Authorization
讀取操作:
-
services
-
端點
-
節點
-
Pod
-
與綁定至 kubelet 節點的 Pod 相關的秘密、組態映射、持久性磁碟區宣告和持久性磁碟區
寫入操作:
-
節點和節點狀態 (啟用
NodeRestriction
許可外掛程式以限制 kubelet 修改自己的節點) -
Pod 和 Pod 狀態 (啟用
NodeRestriction
許可外掛程式以限制 kubelet 修改繫結至自身的 Pod) -
事件
驗證相關操作:
-
TLS 引導的 CertificateSigningRequest (CSR) API 讀取/寫入存取權
-
為委派的身分驗證/授權檢查建立 TokenReview 和 SubjectAccessReview 的能力
EKS 使用節點限制許可控制器
Pod 安全解決方案
Pod 安全政策 (PSP)
在過去,Pod 安全政策 (PSP)
遷移至新的 Pod 安全解決方案
由於 PSPs已從 Kubernetes v1.25 移除,叢集管理員和運算子必須取代這些安全控制。兩種解決方案可以滿足此需求:
-
Kubernetes 生態系統中的Policy-as-code(PAC) 解決方案
-
Kubernetes Pod 安全標準 (PSS)
PAC 和 PSS 解決方案都可以與 PSP 共存;它們可以在移除 PSP 之前用於叢集。這可簡化從 PSP 遷移時的採用。考慮從 PSP 遷移至 PSS 時,請參閱本文件
以下概述的 PAC 解決方案之一 Kyverno 在從 PSPs 遷移到其解決方案時,有部落格文章
Policy-as-code(PAC)
Policy-as-code(PAC) 解決方案提供護欄,透過規定和自動化控制來引導叢集使用者,並防止不必要的行為。PAC 使用 Kubernetes 動態許可控制器
有多種開放原始碼 PAC 解決方案可供 Kubernetes 使用。這些解決方案不屬於 Kubernetes 專案;它們來自 Kubernetes 生態系統。以下列出一些 PAC 解決方案。
如需 PAC 解決方案以及如何協助您選擇適合您需求的解決方案的詳細資訊,請參閱以下連結。
Pod 安全標準 (PSS) 和 Pod 安全許可 (PSA)
為了回應 PSP 棄用以及持續需要透過內建的 Kubernetes 解決方案立即控制 Pod 安全 out-of-the-box ,Kubernetes Auth Special Interest Group
根據 Kubernetes 文件,PSS「`定義三個不同的政策以廣泛涵蓋安全範圍。這些政策是累積的,範圍從高度寬鬆到高度限制。`"
這些政策的定義如下:
-
特殊權限:不受限制 (不安全) 政策,提供最廣泛的許可層級。此政策允許已知的權限提升。這是缺少政策。這適用於記錄代理程式、CNIs、儲存驅動程式等應用程式,以及其他需要特殊存取權限的應用程式。
-
基準:可避免已知權限提升的最小限制政策。允許預設 (最低指定) Pod 組態。基準政策禁止使用 hostNetwork、hostPID、hostIPC、hostPath、hostPort、無法新增 Linux 功能,以及其他幾項限制。
-
限制:嚴格限制政策,遵循目前的 Pod 強化最佳實務。此政策繼承自基準,並新增進一步的限制,例如無法以根或根群組身分執行。限制政策可能會影響應用程式運作的能力。它們主要以執行安全關鍵應用程式為目標。
這些政策會定義 Pod 執行的設定檔
若要實作 PSS 定義的控制項,PSA 會以三種模式運作:
-
強制執行:違反政策會導致 Pod 遭到拒絕。
-
稽核:政策違規將觸發將稽核註釋新增至稽核日誌中記錄的事件,但在其他情況下是允許的。
-
警告:違反政策將觸發面向使用者的警告,但在其他情況下是允許的。
這些模式和設定檔 (限制) 層級是在 Kubernetes 命名空間層級使用標籤設定,如下列範例所示。
apiVersion: v1 kind: Namespace metadata: name: policy-test labels: pod-security.kubernetes.io/enforce: restricted
獨立使用時,這些操作模式會有不同的回應,進而產生不同的使用者體驗。如果個別 PodSpecs 違反設定的限制層級,強制執行模式將防止建立 Pod。 podSpecs 不過,在此模式中,即使其中的 podSpec 違反套用的 PSS,也不會阻止建立 Pod 的非 Pod Kubernetes 物件,例如部署。在此情況下,部署將套用,而 Pod (s) 將無法套用。
這是一個困難的使用者體驗,因為沒有立即指出成功套用的部署物件是失敗的 Pod 建立。違規的 podSpecs 不會建立 Pod。使用 檢查部署資源kubectl get deploy <DEPLOYMENT_NAME> -oyaml
會公開來自失敗 Pod (s) .status.conditions
元素的訊息,如下所示。
... status: conditions: - lastTransitionTime: "2022-01-20T01:02:08Z" lastUpdateTime: "2022-01-20T01:02:08Z" message: 'pods "test-688f68dc87-tw587" is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")' reason: FailedCreate status: "True" type: ReplicaFailure ...
在稽核和警告模式中,Pod 限制不會防止建立和啟動違反 Pod。不過,在這些模式下,當 Pod 以及建立 Pod 的物件包含違規的 podSpecs 時,會分別觸發 API 伺服器稽核日誌事件和 API 伺服器用戶端警告上的稽核註釋,例如 kubectl。警告kubectl
訊息如下所示。
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") deployment.apps/test created
引進 PSS 時,PSA 稽核和警告模式非常有用,而不會對叢集操作造成負面影響。
PSA 操作模式並非互斥,可以累積方式使用。如下所示,您可以在單一命名空間中設定多個模式。
apiVersion: v1 kind: Namespace metadata: name: policy-test labels: pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/warn: restricted
在上述範例中,套用部署時會提供易於使用的警告和稽核註釋,而強制執行違規也會在 Pod 層級提供。事實上,多個 PSA 標籤可以使用不同的設定檔層級,如下所示。
apiVersion: v1 kind: Namespace metadata: name: policy-test labels: pod-security.kubernetes.io/enforce: baseline pod-security.kubernetes.io/warn: restricted
在上述範例中,PSA 設定為允許建立符合基準設定檔層級的所有 Pod,然後在違反限制設定檔層級的 Pod (以及建立 Pod 的物件) 上發出警告。這是一個有用的方法,用於判斷從基準變更為受限設定檔時可能的影響。
現有 Pod
如果修改具有現有 Pod 的命名空間以使用更嚴格的 PSS 設定檔,則稽核和警告模式會產生適當的訊息;不過,強制模式不會刪除 Pod。警告訊息如下所示。
Warning: existing pods in namespace "policy-test" violate the new PodSecurity enforce level "restricted:latest" Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile namespace/policy-test configured
豁免
PSA 使用豁免來排除對原本已套用的 Pod 強制執行違規。這些豁免列於下方。
-
使用者名稱:忽略具有豁免身分驗證 (或模擬) 使用者名稱之使用者的請求。
-
RuntimeClassNames:會忽略指定豁免執行時間類別名稱的 Pod 和工作負載資源。
-
命名空間:忽略豁免命名空間中的 Pod 和工作負載資源。
這些豁免會在 PSA 許可控制器組態
在驗證 Webhook 實作中,可以在 Kubernetes ConfigMap
apiVersion: v1 kind: ConfigMap metadata: name: pod-security-webhook namespace: pod-security-webhook data: podsecurityconfiguration.yaml: | apiVersion: pod-security.admission.config.k8s.io/v1 kind: PodSecurityConfiguration defaults: enforce: "restricted" enforce-version: "latest" audit: "restricted" audit-version: "latest" warn: "restricted" warn-version: "latest" exemptions: # Array of authenticated usernames to exempt. usernames: [] # Array of runtime class names to exempt. runtimeClasses: [] # Array of namespaces to exempt. namespaces: ["kube-system","policy-test1"]
如上述 ConfigMap YAML 所示,整個叢集的預設 PSS 層級已設定為限制所有 PSA 模式、稽核、強制執行和警告。這會影響所有命名空間,但不包括豁免的命名空間:namespaces: ["kube-system","policy-test1"]
。此外,在如下所示的 ValidatingWebhookConfiguration 資源中,pod-security-webhook 命名空間也會從設定的 PSS 中排除。
... webhooks: # Audit annotations will be prefixed with this name - name: "pod-security-webhook.kubernetes.io" # Fail-closed admission webhooks can present operational challenges. # You may want to consider using a failure policy of Ignore, but should # consider the security tradeoffs. failurePolicy: Fail namespaceSelector: # Exempt the webhook itself to avoid a circular dependency. matchExpressions: - key: kubernetes.io/metadata.name operator: NotIn values: ["pod-security-webhook"] ...
重要
Pod 安全許可在 Kubernetes 1.25 版中進入穩定狀態。如果您想要在預設啟用 Pod 安全許可功能之前使用此功能,您需要安裝動態許可控制器 (變動 Webhook)。您可以在此處
在policy-as-code和 Pod 安全標準之間進行選擇
Pod 安全標準 (PSS) 旨在取代 Pod 安全政策 (PSP),方法是提供內建於 Kubernetes 且不需要 Kubernetes 生態系統解決方案的解決方案。也就是說,policy-as-code(PAC) 解決方案更加靈活。
下列 Pros 和 Cons 清單旨在協助您更明智地決定 Pod 安全解決方案。
Policy-as-code(與 Pod 安全標準相比)
專業人員:
-
更靈活、更精細 (視需要縮減至資源的屬性)
-
不僅專注於 Pod,還可以用於不同的資源和動作
-
不僅適用於命名空間層級
-
比 Pod 安全標準更成熟
-
決策可以根據 API 伺服器請求承載中的任何內容,以及現有的叢集資源和外部資料 (取決於解決方案)
-
支援在驗證之前變更 API 伺服器請求 (取決於解決方案)
-
可以產生互補政策和 Kubernetes 資源 (取決於解決方案 - 從 Pod 政策中,Kyverno 可以自動產生
高階控制器的政策,例如部署。 Kyverno 也可以使用產生規則 產生額外的 Kubernetes 資源「建立新資源時或更新來源時`」。) -
在呼叫 Kubernetes API 伺服器 (依解決方案而定) 之前,可用來向左移動至 CICD 管道
-
可用於實作不一定與安全相關的行為,例如最佳實務、組織標準等。
-
可用於非 Kubernetes 使用案例 (取決於解決方案)
-
由於靈活性,使用者體驗可以根據使用者的需求進行調整
Cons:
-
未內建於 Kubernetes
-
更複雜的學習、設定和支援
-
政策撰寫可能需要新的skills/languages/capabilities
Pod 安全許可 (與policy-as-code相比)
專業人員:
-
內建於 Kubernetes
-
設定更簡單
-
沒有要使用的新語言或編寫的政策
-
如果叢集預設許可層級設定為特殊權限,則可以使用命名空間標籤將命名空間選擇為 Pod 安全性設定檔。
Cons:
-
不像policy-as-code一樣靈活或精細
-
只有 3 個層級的限制
-
主要專注於 Pod
Summary
如果您目前沒有 PSP 以外的 Pod 安全解決方案,且所需的 Pod 安全狀態符合 Pod 安全標準 (PSS) 中定義的模型,則更簡單的路徑可能是採用 PSS,而不是policy-as-code解決方案。不過,如果您的 Pod 安全狀態不符合 PSS 模型,或者您設想新增超出 PSS 定義的其他控制項,則policy-as-code解決方案似乎更合適。
建議
使用多個 Pod 安全許可 (PSA) 模式,以獲得更好的使用者體驗
如前所述,PSA 強制執行模式可防止套用具有 PSS 違規的 Pod,但不會停止更高層級的控制器,例如部署。事實上,部署將成功套用,而不會指出 Pod 無法套用。雖然您可以使用 kubectl 來檢查部署物件,並從 PSA 探索失敗的 Pod 訊息,但使用者體驗可能會更好。為了改善使用者體驗,應使用多種 PSA 模式 (稽核、強制執行、警告)。
apiVersion: v1 kind: Namespace metadata: name: policy-test labels: pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/enforce: restricted pod-security.kubernetes.io/warn: restricted
在上述範例中,在定義強制執行模式的情況下,當嘗試將個別 podSpec 中具有 PSS 違規的部署資訊清單套用至 Kubernetes API 伺服器時,部署將成功套用,但 Pod 不會套用。此外,由於稽核和警告模式也已啟用,API 伺服器用戶端會收到警告訊息,API 伺服器稽核日誌事件也會以訊息標註。
限制可做為特殊權限執行的容器
如前所述,執行為特殊權限的容器會繼承指派給主機根目錄的所有 Linux 功能。容器很少需要這些類型的權限才能正常運作。有多種方法可用來限制容器的許可和功能。
重要
Fargate 是一種啟動類型,可讓您執行「無伺服器」容器 (在 AWS 管理的基礎設施上執行 Pod 的容器)。使用 Fargate,您無法執行特權容器或將 Pod 設定為使用 hostNetwork 或 hostPort。
請勿在容器中以根目錄執行程序
根據預設,所有容器都會以根身分執行。如果攻擊者能夠利用應用程式中的漏洞,並取得執行中容器的 shell 存取,則這可能有問題。您可以用各種方式降低此風險。首先,從容器映像中移除 Shell。其次,將 USER 指令新增至您的 Dockerfile,或以非根使用者身分在 Pod 中執行容器。Kubernetes podSpec 包含一組欄位,位於 下spec.securityContext
,可讓您指定要在其中執行應用程式的使用者和/或群組。這些欄位runAsGroup
分別為 runAsUser
和 。
若要在 Kubernetes podSpec 中強制使用 spec.securityContext
及其相關聯的元素,可以將policy-as-code或 Pod 安全標準新增至叢集。這些解決方案可讓您撰寫和/或使用可驗證傳入 Kubernetes API 伺服器請求承載的政策或設定檔,然後再保留到 等。此外,policy-as-code解決方案可以改變傳入請求,在某些情況下,會產生新的請求。
切勿在 Docker 中執行 Docker 或在容器中掛載通訊端
雖然這可讓您在 Docker 容器中建置/執行映像,但您基本上會放棄節點對容器中執行程序的完整控制。如果您需要在 Kubernetes 上建置容器映像,請改用 Kaniko
注意
用於 CICD 處理的 Kubernetes 叢集,例如建置容器映像,應與執行更廣泛工作負載的叢集隔離。
限制 hostPath 的使用,或如果需要 hostPath 限制可使用的字首,並將磁碟區設定為唯讀
hostPath
是將目錄從主機直接掛載到容器的磁碟區。在極少數情況下,Pod 會需要這種類型的存取,但如果他們這麼做,您需要注意風險。根據預設,以根身分執行的 Pod 將具有 hostPath 公開之檔案系統的寫入存取權。這可能會允許攻擊者修改 kubelet 設定、建立未由 hostPath 直接公開的目錄或檔案的符號連結,例如 /etc/shadow、安裝 SSH 金鑰、掛載至主機的讀取秘密,以及其他惡意物件。若要降低 hostPath 的風險,請將 設定為 spec.containers.volumeMounts
readOnly
,例如:
volumeMounts: - name: hostPath-volume readOnly: true mountPath: /host-path
您也應該使用policy-as-code解決方案來限制可供磁碟hostPath
區使用的目錄,或完全防止hostPath
使用。您可以使用 Pod 安全標準基準或受限制政策來防止使用 hostPath
。
如需特殊權限提升危險的進一步資訊,請參閱 Seth Art 的部落格錯誤 Pod:Kubernetes Pod 特殊權限提升
設定每個容器的請求和限制,以避免資源爭用和 DoS 攻擊
沒有請求或限制的 Pod 理論上可以使用主機上所有可用的資源。當其他 Pod 排程到節點時,節點可能會遇到 CPU 或記憶體壓力,這可能會導致 Kubelet 從節點終止或移出 Pod。雖然您無法防止這種情況一起發生,但設定請求和限制將有助於最大限度地減少資源爭用,並降低因寫入不良的應用程式消耗過多資源的風險。
podSpec
可讓您指定 CPU 和記憶體的請求和限制。CPU 被視為可壓縮資源,因為它可能會過度訂閱。記憶體無法壓縮,即無法在多個容器之間共用。
當您指定 CPU 或記憶體的請求時,基本上就是指定容器保證取得的記憶體量。Kubernetes 會彙總 Pod 中所有容器的請求,以決定要排程 Pod 的節點。如果容器超過請求的記憶體數量,如果節點上有記憶體壓力,則可能會終止。
限制是允許容器使用並直接對應至為容器建立之 cgroup memory.limit_in_bytes
值的 CPU 和記憶體資源數量上限。超過記憶體限制的容器將會終止 OOM。如果容器超過其 CPU 限制,則會對其進行調節。
注意
使用容器時resources.limits
,強烈建議容器資源使用量 (即資源足跡) 根據負載測試以資料驅動且準確。如果沒有準確且受信任的資源使用量,resources.limits
可以填充容器。例如, resources.limits.memory
可能比可觀測的最大值高出 20-30%,以考量潛在的記憶體資源限制不正確。
Kubernetes 使用三種服務品質 (QoS) 類別來排定節點上執行工作負載的優先順序。其中包含:
-
保證
-
爆量
-
盡最大努力
如果未設定限制和請求,Pod 會設定為盡力 (最低優先順序)。當記憶體不足時,最努力的 Pod 是第一個被刪除的 Pod。如果 Pod 內的所有容器都設定了限制,或者如果請求和限制設定為相同的值但不等於 0,則 Pod 會設定為保證 (最高優先順序)。除非保證的 Pod 超過其設定的記憶體限制,否則不會被終止。如果限制和請求設定了不同的值,不等於 0,或 Pod 中的一個容器設定了限制,而其他容器未針對不同的資源設定限制,則 Pod 會設定為爆量 (中等優先順序)。這些 Pod 有一些資源保證,但一旦超過其請求的記憶體,就會遭到刪除。
重要
請求不會影響容器 cgroup memory_limit_in_bytes
的值;cgroup 限制會設定為主機上可用的記憶體量。不過,如果將請求值設定為過低,可能會導致 Pod 在節點經歷記憶體壓力時成為 kubelet 終止的目標。
類別 | 優先順序 | 條件 | 刪除條件 |
---|---|---|---|
保證 |
最高 |
limit = 請求 != 0 |
僅超過記憶體限制 |
爆量 |
中型 |
限制 != 請求 != 0 |
如果超過請求記憶體,則可以終止 |
盡最大努力 |
最低 |
限制和請求未設定 |
首先在記憶體不足時遭到刪除 |
如需資源 QoS 的詳細資訊,請參閱 Kubernetes 文件
您可以在命名空間上設定資源配額
Policy-as-code解決方案可用來強制執行請求和限制。 或 甚至在建立命名空間時建立資源配額和限制範圍。
不允許特殊權限呈報
特殊權限提升允許程序變更其執行所在的安全內容。Sudo 是很好的範例,因為 是具有 SUID 或 SGID 位元的二進位檔。特殊權限呈報基本上是使用者執行具有其他使用者或群組許可的檔案的一種方式。您可以在 securityContext.allowPrivilegeEscalation
中實作設定為 allowPrivilegeEscalation
false
或 policy-as-code變更政策,以防止容器使用特殊權限升級podSpec
。如果偵測到不正確的設定,Policy-as-code政策也可以用來防止 API 伺服器請求成功。Pod 安全標準也可以用來防止 Pod 使用權限提升。
停用 ServiceAccount 字符掛載
對於不需要存取 Kubernetes API 的 Pod,您可以停用 ServiceAccount 字符在 Pod 規格上的自動掛載,或使用特定 ServiceAccount 的所有 Pod。
apiVersion: v1 kind: Pod metadata: name: pod-no-automount spec: automountServiceAccountToken: false
apiVersion: v1 kind: ServiceAccount metadata: name: sa-no-automount automountServiceAccountToken: false
停用服務探索
對於不需要查詢或呼叫叢集內服務的 Pod,您可以減少提供給 Pod 的資訊量。您可以將 Pod 的 DNS 政策設定為不使用 CoreDNS,且不得將 Pod 命名空間中的服務公開為環境變數。如需服務連結的詳細資訊,請參閱環境變數上的 Kubernetes 文件
apiVersion: v1 kind: Pod metadata: name: pod-no-service-info spec: dnsPolicy: Default # "Default" is not the true default value enableServiceLinks: false
使用唯讀根檔案系統設定映像
使用唯讀根檔案系統設定映像,可防止攻擊者覆寫應用程式使用的檔案系統上的二進位檔案。如果您的應用程式必須寫入檔案系統,請考慮寫入暫存目錄或連接並掛載磁碟區。您可以透過設定 Pod 的 SecurityContext 來強制執行此操作,如下所示:
... securityContext: readOnlyRootFilesystem: true ...
Policy-as-code和 Pod 安全標準可用來強制執行此行為。
根據 Kubernetes 中的 Windows 容器securityContext.readOnlyRootFilesystem
無法在 Windows 上執行true
的容器設定為 ,因為需要寫入存取權,登錄檔和系統程序才能在容器內執行。
工具和資源
-
open-policy-agent/gatekeeper-library:OPA Gatekeeper 政策程式
庫 OPA/Gatekeeper 政策程式庫,可用來取代 PSPs。 -
EKS 的常見 OPA 和 Kyverno 政策
集合。 -
Pod 安全政策 Migrator
將 PSPs 轉換為 OPA/Gatekeeper、KubeWarden 或 Kyverno 政策的工具 -
NeuVector by SUSE
開放原始碼、零信任容器安全平台,提供程序和檔案系統政策以及許可控制規則。