返回文章列表

Kubernetes叢集安全與存取控制強化

本文探討 Kubernetes 叢集的外部攻擊風險與防禦策略,涵蓋 Kubelet 安全強化、RBAC 授權機制、網路策略組態及安全稽核等關鍵導向。文章剖析錯誤組態帶來的風險,提供最佳實務與工具,有效降低叢集受攻擊機率,確保 Kubernetes 環境安全穩固。

資安 容器化

Kubernetes 叢集的安全性容易被輕忽,錯誤的組態可能導致嚴重攻擊。本文除了探討 Kubelet 的安全漏洞與防禦措施外,也深入解析 RBAC 授權機制,包含角色、角色繫結、叢集角色及叢集角色繫結的運用,並說明如何避免 cluster-admin 角色濫用、謹慎使用內建使用者和群組等注意事項。此外,文章也示範如何透過網路策略限制叢集內部流量,並介紹多種稽核 RBAC 設定的工具,如 kubectl auth can-i、Rakkess、kubectl-who-can 和 Rback,協助管理員有效控管叢集存取許可權,提升整體安全性。

Kubernetes 外部攻擊與存取控制

Kubernetes 叢集的安全性至關重要,因為錯誤的組態可能導致叢集被攻擊。本章節將探討 Kubernetes 外部攻擊的風險以及如何透過適當的存取控制來降低這些風險。

攻擊 Kubelet

Kubelet 是 Kubernetes 叢集中每個節點上執行的代理程式,負責管理容器執行時。因此,它是攻擊者的重要目標。Kubelet 有兩個相關的埠:10250/TCP 和 10255/TCP。

Kubelet 資訊洩露

在某些 Kubernetes 叢集中,Kubelet 可能會在 10255/TCP 埠上監聽,該埠提供了一個只讀的 Kubelet API 檢視。如果組態了這個埠,則可以在無需身份驗證或授權的情況下存取它。

curl http://[IP]:10255/pods/ | jq

上述命令可以傳回該主機上執行的所有容器的列表。攻擊者可以從輸出中取得有用的資訊,例如傳遞給 Pod 的命令列標誌。

利用組態錯誤的 Kubelet

如果 Kubelet 埠接受未經身份驗證的請求,則攻擊者可以執行命令在受影響的叢集節點上的任何 Pod 中。

curl https://[IP]:10250/run/[namespace]/[pod name]/[container name] -k -XPOST -d "cmd=[command]"

上述命令可以在指定的容器中執行指定的命令。攻擊者需要填寫正確的名稱空間、Pod 名稱、容器名稱和命令。

防止未經身份驗證的 Kubelet 存取

為了防止未經身份驗證的 Kubelet 存取,可以透過以下組態來停用只讀 Kubelet 埠並限制對讀寫 Kubelet 的存取:

authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 0s
    enabled: true
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 0s
    cacheUnauthorizedTTL: 0s

Kubernetes 存取控制機制

Kubernetes 提供了多種授權機制來控制使用者的許可權。最常用的機制是根據角色的存取控制(RBAC)。本章節將探討 RBAC 的原理和實踐。

Kubernetes 授權機制

Kubernetes 支援多種授權機制,包括 RBAC、ABAC 和 Webhook。當多個授權機制被組態時,使用者的許可權將是所有機制授予的許可權的總和。因此,通常建議為每個叢集組態單一的授權機制。

使用 RBAC 進行 Kubernetes 授權

RBAC 是 Kubernetes 中最常用的授權機制。透過定義角色和角色繫結,RBAC 可以精確控制使用者對 Kubernetes 資源的存取許可權。

RBAC 的重要性

正確組態 RBAC 可以防止使用者或應用程式過度取得許可權,從而降低攻擊者在獲得憑據後提升許可權的風險。因此,瞭解和正確使用 RBAC 是 Kubernetes 安全性的關鍵。

詳細內容解密:

  1. Kubernetes 多重授權機制的累加效應:當多個授權機制同時啟用時,使用者最終獲得的許可權是所有機制允許許可權的總和。這意味著,如果某個使用者透過某個機制獲得了某種資源的存取許可權,而透過另一個機制又獲得了另一種資源的存取許可權,那麼該使用者最終將同時擁有這兩種資源的存取許可權。

  2. RBAC 的核心概念:RBAC 主要涉及角色(Role)和角色繫結(RoleBinding)的概念。角色定義了一組對特定資源的操作許可權,而角色繫結則將這些角色授予特定的使用者或服務帳戶,從而賦予他們相應的操作許可權。

  3. 正確組態 RBAC 的重要性:正確組態 RBAC 可以有效地限制使用者或應用程式對 Kubernetes 資源的不必要存取,從而提高叢集的安全性。這對於防止內部威脅和降低因憑據洩露導致的安全風險具有重要意義。

  4. 實踐中的挑戰與解決方案:在實踐中,正確組態和管理 RBAC 可能面臨諸多挑戰,如角色定義不清晰、角色繫結不當等。為此,需要採用一些最佳實踐,如定期稽核 RBAC 組態、使用自動化工具監控 RBAC 變更等,以確保 RBAC 的有效性和安全性。

圖示說明:

此圖示說明瞭 Kubernetes 中 RBAC 對使用者請求的處理流程。當使用者發起請求時,系統會根據 RBAC 的組態進行授權檢查。如果請求被允許,則使用者可以存取相應的資源並執行操作;如果請求被拒絕,則系統會傳回錯誤並記錄日誌。

詳細內容解說:

  • 圖中每個節點代表了 Kubernetes 處理使用者請求的一個階段。
  • 從使用者請求到最終存取資源或傳回錯誤,這一流程體現了 RBAC 在 Kubernetes 安全機制中的核心作用。
  • 正確組態和使用 RBAC 可以有效地控制使用者對叢集資源的存取,從而提高叢集的安全性和穩定性。

Kubernetes 授權機制:深入理解 RBAC

Kubernetes 提供了多種使用者授權模式,包括 ABAC、Webhook、AlwaysAllow、AlwaysDeny 和 RBAC。其中,RBAC 是最常用且與叢集中的第三方軟體相容性最佳的授權機制。

RBAC 概述

Kubernetes RBAC 使用角色(Role)和叢集角色(ClusterRole)來定義主體(包括群組、使用者和服務帳戶)在叢集或名稱空間層級的許可權。RBAC 涉及四種物件型別:

  1. Role:定義在單一名稱空間中的許可權。
  2. RoleBinding:將角色或叢集角色與主體集合繫結。
  3. ClusterRole:定義叢集範圍或特定名稱空間的許可權。
  4. ClusterRoleBinding:將叢集角色與主體集合繫結。

這些物件可以透過三種方式結合使用:

  • Role → RoleBinding:在單一名稱空間中提供許可權。
  • ClusterRole → ClusterRoleBinding:在叢集層級提供許可權。
  • ClusterRole → RoleBinding:在單一名稱空間中提供許可權,通常用於建立可應用於多個名稱空間的許可權範本。

RBAC 的注意事項

在使用 RBAC 為 Kubernetes 主體分配許可權時,需要注意以下事項,以避免意外的許可權升級:

避免使用 cluster-admin 角色

Kubernetes 提供了一個名為 cluster-admin 的預設叢集角色,該角色具有對叢集的完全存取許可權。該角色的規則都是萬用字元,這意味著它不僅提供對目前叢集中所有物件的完全存取許可權,還會自動為未來建立的物件提供許可權。

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
rules:
- apiGroups:
  - '*'
  resources:
  - '*'
  verbs:
  - '*'
- nonResourceURLs:
  - '*'
  verbs:
  - '*'

謹慎使用內建使用者和群組

Kubernetes 提供兩個內建群組和一個內建使用者,它們在特定情況下用於 RBAC 決策。將許可權分配給這些主體時需要謹慎,因為它們可能會向未經授權的第三方提供存取許可權。

  • system:anonymous 使用者:當沒有提供使用者名稱時,預設使用該使用者帳戶進行 RBAC 決策。
  • system:unauthenticated 群組:未經身份驗證的請求將被授予該群組的許可權。
  • system:authenticated 群組:任何提供有效身份驗證憑證的使用者都將被授予該群組的許可權。

只讀存取可能存在風險

Kubernetes API 的只讀存取可能會允許使用者獲得叢集的其他存取許可權,甚至是叢集管理員許可權。這是因為 Kubernetes 將 Secret 儲存在 API 中,並會將其傳回給具有讀取(或列出)該物件型別存取許可權的使用者。

示範只讀存取風險

首先,建立一個名為 secretlist 的名稱空間:

kubectl create ns secretlist

然後,建立一個僅提供 Secret 列出許可權的叢集角色:

kubectl create clusterrole "secretlist" --verb=list --resource=secrets

Kubernetes 授權與 RBAC 的安全挑戰

在 Kubernetes 中,Role-Based Access Control(RBAC)是一種重要的安全機制,用於控制對叢集資源的存取許可權。然而,在實際操作中,仍存在一些安全挑戰需要被關注。

服務帳戶許可權的管理

當為預設服務帳戶(default service account)授予許可權時,該名稱空間中的所有 Pod 都將繼承這些許可權,除非明確指定使用不同的服務帳戶。這種情況下,如果未妥善管理許可權,可能會導致安全性問題。

例如,建立一個名為 secretlist 的 ClusterRole,並將其繫結到 secretlist 名稱空間中的預設服務帳戶:

kubectl create clusterrolebinding secretlist --clusterrole=secretlist --serviceaccount=secretlist:default

接著,在該名稱空間中執行一個 Pod,即可驗證其許可權:

kubectl -n secretlist run -it testpod --image=raesene/alpine-containertools /bin/bash

在 Pod 中,可以使用 kubectl 命令列出 kube-system 名稱空間中的 Secrets:

kubectl -n kube-system get secrets -o yaml

這將顯示所有 Secrets 的詳細資訊,包括服務帳戶 Token。這些 Token 可以用於身份驗證,從而存取叢集資源。

內容解密:

此範例展示瞭如何利用預設服務帳戶的許可權來存取叢集資源。攻擊者可以利用此漏洞取得敏感資訊,如服務帳戶 Token。

建立 Pod 的風險

允許使用者建立 Pod 可能會導致許可權提升的安全風險。攻擊者可以建立一個具有特殊組態的 Pod,以逃避容器的隔離限制,從而存取基礎主機。

例如,建立一個名為 noderootpod 的 Pod,其設定檔如下:

apiVersion: v1
kind: Pod
metadata:
  name: noderootpod
spec:
  hostNetwork: true
  hostPID: true
  hostIPC: true
  containers:
  - name: noderootpod
    image: busybox
    securityContext:
      privileged: true
    volumeMounts:
    - mountPath: /host
      name: noderoot
    command: ["/bin/sh", "-c", "--"]
    args: ["while true; do sleep 30; done;"]
  volumes:
  - name: noderoot
    hostPath:
      path: /

此 Pod 設定檔啟用了 hostNetworkhostPIDhostIPC,並掛載了主機的根檔案系統。攻擊者可以利用此 Pod 取得主機的 root 許可權。

內容解密:

此範例展示瞭如何建立一個具有特殊組態的 Pod,以逃避容器的隔離限制。攻擊者可以利用此漏洞取得主機的 root 許可權。

Kubernetes 許可權的暫時性

在 Kubernetes 中,某些資源的建立可能不會直接由使用者發起,而是由叢集中的控制器(Controller)執行。這意味著,使用者可能間接獲得某些資源的建立許可權。

例如,當使用者建立一個 Deployment 物件時,Deployment Controller 將建立一個 ReplicaSet 物件,然後 ReplicaSet 物件將建立 Pod。因此,使用者即使沒有明確獲得建立 Pod 的許可權,也可以間接獲得該許可權。

內容解密:

此範例展示了 Kubernetes 中許可權的暫時性質。使用者可能間接獲得某些資源的建立許可權,從而導致安全風險。

Kubernetes 許可權管理與稽核

Kubernetes 的許可權管理是確保叢集安全的重要環節。適當的許可權控制可以防止未授權的存取和潛在的安全風險。在本章中,我們將探討 Kubernetes 中的 Role-Based Access Control(RBAC)機制,並介紹一些有用的工具來稽核和管理許可權。

危險物件與許可權升級

在 Kubernetes 中,某些物件如果未被妥善管理,可能會導致安全風險。例如,具有建立 Pod 許可權的使用者可能會利用此許可權進行許可權升級。同樣地,建立 PersistentVolume 物件的使用者可能會獲得對主機檔案系統的特權存取。因此,限制對這些物件的管理許可權至關重要。

限制 PersistentVolume 物件的存取

PersistentVolume 物件不受 PodSecurityPolicies 的管轄,因此需要透過 RBAC 來限制存取。確保只有受信任的 Kubernetes 使用者能夠建立或管理這些物件。

稽核 RBAC

定期稽核 RBAC 設定是確保叢集安全的重要步驟。以下是一些用於稽核 RBAC 的方法和工具。

使用 kubectl 稽核許可權

kubectl auth can-i 命令可以用來檢查使用者或服務帳戶是否具有特定的操作許可權。例如:

kubectl auth can-i get pods

此命令會檢查目前的使用者是否能夠取得 Pod 資訊。若要檢查其他使用者或服務帳戶的許可權,可以使用 --as 引數:

kubectl auth can-i get pods --as=system:serviceaccount:kube-system:certificate-controller

此外,--list 引數可以用來列出特定使用者或服務帳戶在指定名稱空間中的所有許可權:

kubectl auth can-i --as=system:serviceaccount:default:default --list

使用外部工具稽核 RBAC

除了 kubectl,還有一些外部工具可以用於稽核 RBAC 設定。這些工具提供了不同的視角來檢視和分析 Kubernetes 中的 RBAC 資訊。

Rakkess

Rakkess 是一個用於視覺化顯示使用者或服務帳戶許可權的工具。它可以作為單一的二進位制檔案執行,無需額外的依賴項。使用 Rakkess 可以輕鬆地檢查目前使用者或其他使用者/服務帳戶的許可權。

rakkess --sa kube-system:certificate-controller
kubectl-who-can

kubectl-who-can 是另一個由 Aqua Security 提供的工具,用於找出具有特定許可權的主體。它同樣以靜態 Golang 二進位制檔案的形式提供,可以直接下載並執行。

kubectl-who-can get secrets

此命令會列出能夠取得 Secrets 資源的主體,包括名稱空間層級和叢集層級的許可權。

Rback

Rback 是一個用於視覺化 RBAC 許可權的工具。它會解析叢集中的 RBAC 物件,並建立圖形化的許可權檢視,有助於分析和理解複雜的 RBAC 設定。

網路硬體強化:Kubernetes 網路安全探討

Kubernetes 提供了一個關鍵能力——容器網路,讓工作負載在不同節點或網路中能夠輕易地相互通訊。預設情況下,Kubernetes 採用扁平化、無限制的環境,允許每個容器與其他容器通訊,這在安全上帶來了挑戰。

容器網路概述

在探討網路策略組態之前,瞭解容器網路的佈署方式至關重要。Kubernetes 叢集中有多組不同的 IP 位址,每組都有不同的角色來處理叢集流量。

節點 IP 位址

這些是分配給叢集中節點的位址,通常是虛擬機器或實體伺服器。可以透過 kubectl get nodes 命令並使用 -o wide 選項或自定義列來檢視節點的 IP 位址。

kubectl get nodes -o custom-columns=Address:status.addresses[*].address

Pod IP 位址

這些位址是在 Pod 啟動時分配給它們的。這些位址通常與節點 IP 位址所在的網路不同。Pod IP 位址的分配由叢集使用的容器網路介面(CNI)外掛(如 Calico 或 Cilium)管理。

kubectl -n kube-system get po -o custom-columns=IP:.status.podIP

值得注意的是,通常不會直接連線到 Pod IP 位址,因為這些位址與 Pod 一樣是暫時的。相反,會連線到服務位址。

服務 IP 位址

服務提供了一個固定的 IP 位址給在 Kubernetes 叢集中執行的應用程式。由於 Pod 是暫時的,可能會在節點之間移動,因此需要服務來提供穩定的 IP 位址。

kubectl get svc -o custom-columns=SVC-IP:.spec.clusterIP

限制 Kubernetes 叢集中的流量

要使用網路策略 API,必須確保所使用的 CNI 外掛支援它。大多數常見的 CNI 外掛都支援網路策略,但仍有一些(如 flannel)不支援。

網路策略在名稱空間層級運作,一旦有任何策略適用於給定名稱空間中的給定方向(入站或出站),所有流量都會被封鎖,除非它是明確允許的。這種方法通常被稱為白名單模型。

網路策略例項

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - 5978

內容解密:

此網路策略範例允許具有 role=db 標籤的 Pod 在以下條件下接收入站流量:

  • 來自 172.17.0.0/16 網段,但排除 172.17.1.0/24
  • 來自具有 project=myproject 標籤的名稱空間中的 Pod
  • 來自具有 role=frontend 標籤的 Pod,埠為 6379

同時,它允許這些 Pod 向 10.0.0.0/24 網段的 5978 埠發送出站流量。

圖表說明:Kubernetes 網路架構圖

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Kubernetes叢集安全與存取控制強化

package "Kubernetes Cluster" {
    package "Control Plane" {
        component [API Server] as api
        component [Controller Manager] as cm
        component [Scheduler] as sched
        database [etcd] as etcd
    }

    package "Worker Nodes" {
        component [Kubelet] as kubelet
        component [Kube-proxy] as proxy
        package "Pods" {
            component [Container 1] as c1
            component [Container 2] as c2
        }
    }
}

api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2

note right of api
  核心 API 入口
  所有操作經由此處
end note

@enduml

此圖示展示了 Kubernetes 網路架構中的不同元件及其相互關係。節點 IP 位址、Pod IP 位址和服務 IP 位址共同構成了叢集中的網路基礎設施,使得應用程式能夠順暢地通訊。