隨著 Kubernetes 的不斷發展,其安全功能也在不斷增強。以下是一些值得關注的趨勢和發展:

  1. 零信任安全模型的普及,要求對每個請求進行身分驗證和授權,無論其來源
  2. 供應鏈安全的重要性增加,包括映像簽名和驗證
  3. 安全操作自動化,減少人為錯誤並提高回應速度
  4. 執行時安全技術的進步,提供更強的容器隔離
  5. 安全即程式碼的採用,將安全控制整合到 CI/CD 流程中

Kubernetes 安全是一個不斷發展的領域,需要持續學習和適應。透過實施本文中描述的最佳實踐,並關注新興的安全技術和威脅,你可以建立一個強大的安全基礎,保護你的 Kubernetes 環境和應用程式。

安全不是一次性的工作,而是一個持續的過程。它需要技術知識、組織承諾和文化意識的結合。透過將安全考慮納入 Kubernetes 佈署的每個階段,從設計到開發再到營運,你可以顯著降低安全風險,並建立一個更加可靠和安全的容器化環境。

記住,安全性和便利性往往需要權衡。找到適合你的組織和應用程式的平衡點是關鍵。不是所有的安全控制都適用於每種情況,重要的是根據你的風險評估和業務需求做出明智的決策。

透過全面的安全策略,從叢集設定到容器執行時保護,你可以充分利用 Kubernetes 的強大功能,同時保持適當的安全姿態,保護你的應用程式和資料免受不斷演變的威脅。

保護 Kubernetes 資源:設定與存取控制策略

Kubernetes 作為現代容器協調平台的核心,其安全性設定與存取控制機制對於維護系統整體安全至關重要。在建立 Kubernetes 叢集後,正確設定其元件並實施適當的存取限制是確保系統安全的關鍵步驟。

Kubernetes 元件設定的安全考量

設定 Kubernetes 元件時,必須特別注意安全性設定。這包括 API 伺服器、控制器管理器、排程器以及 kubelet 等核心元件的安全引數設定。玄貓在實際佈署中發現,許多安全漏洞往往源於預設設定的使用,而非針對特定環境進行安全強化。

例如,API 伺服器的認證機制、授權策略以及准入控制器的設定,都需要根據組織的安全需求進行客製化。控制器管理器和排程器的安全引數同樣需要謹慎設定,以防止潛在的安全風險。

關鍵元件安全設定重點

  • API 伺服器:設定強健的認證機制,如 OIDC 或 X.509 憑證
  • 控制器管理器:設定適當的資源限制和許可權範圍
  • kubelet:確保通訊加密並限制其許可權範圍
  • etcd:實施加密儲存和嚴格的存取控制

實施資源存取限制策略

限制對 Kubernetes 資源的存取是安全策略的核心部分。這涉及到設計和實施細粒度的存取控制機制,確保只有授權的使用者和應用程式能夠存取特定資源。

Kubernetes 提供了多層次的存取控制機制:

  1. 認證 (Authentication):確認使用者或服務的身份
  2. 授權 (Authorization):決定已認證的實體可以執行哪些操作
  3. 准入控制 (Admission Control):在資源建立或修改前進行額外的檢查和修改

實施 RBAC 的最佳實踐

根據角色的存取控制 (RBAC) 是 Kubernetes 中最常用的授權機制。玄貓建議遵循最小許可權原則,為每個使用者或服務帳號分配執行其工作所需的最小許可權集。

# 為開發團隊建立一個限制性的角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: developer
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

這個 YAML 定義了一個名為 “developer” 的 Role,限定在 “development” 名稱空間中。該角色允許使用者對核心資源(pods、services)和應用資源(deployments、replicasets)執行完整的 CRUD 操作。這種設定體現了最小許可權原則,只授予開發人員在其工作名稱空間中所需的確切許可權,而非整個叢集的存取權。

接下來,我們需要將此角色繫結到特定使用者或群組:

# 將角色繫結到開發團隊群組
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-binding
  namespace: development
subjects:
- kind: Group
  name: development-team
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: developer
  apiGroup: rbac.authorization.k8s.io

這個 RoleBinding 將前面定義的 “developer” 角色與名為 “development-team” 的群組關聯起來。這意味著屬於該群組的所有使用者都將獲得 developer 角色定義的許可權,但僅限於 development 名稱空間。這種方法使許可權管理更加模組化和可維護,特別是在團隊成員變動頻繁的環境中。

名稱空間隔離與資源保護

名稱空間是 Kubernetes 中邏輯隔離的基本單位,可用於分隔不同團隊、專案或環境的資源。透過結合網路策略和資源配額,可以強化名稱空間之間的隔離。

# 限制名稱空間間的網路流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-from-other-namespaces
  namespace: development
spec:
  podSelector: {}
  ingress:
  - from:
    - podSelector: {}

這個 NetworkPolicy 定義了一個嚴格的網路隔離策略,只允許 development 名稱空間內的 Pod 之間相互通訊,拒絕來自其他名稱空間的所有入站流量。podSelector: {} 表示選擇名稱空間中的所有 Pod,而 ingress 規則僅允許來自同一名稱空間中 Pod 的流量。這種設定在多租戶環境或需要嚴格隔離的場景中特別有用,可以防止跨名稱空間的未授權存取。

服務帳號的安全管理

服務帳號 (Service Accounts) 是 Kubernetes 中用於 Pod 身分驗證的機制。適當管理服務帳號對於保護應用工作負載至關重要。

# 建立限制性服務帳號
apiVersion: v1
kind: ServiceAccount
metadata:
  name: restricted-sa
  namespace: development
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: restricted-binding
  namespace: development
subjects:
- kind: ServiceAccount
  name: restricted-sa
  namespace: development
roleRef:
  kind: Role
  name: restricted-role
  apiGroup: rbac.authorization.k8s.io

這組 YAML 定義建立了一個名為 “restricted-sa” 的服務帳號,並透過 RBAC 為其分配了非常有限的許可權。該服務帳號只能讀取 ConfigMaps 和 Secrets,沒有寫入或修改許可權。這種最小許可權設計對於執行只需要讀取設定的應用程式特別適合,可以顯著減少潛在的安全風險。在實際佈署中,應該為每個應用程式建立專用的服務帳號,並根據其確切需求分配許可權。

保護應用工作負載的安全策略

除了控制對 Kubernetes 資源的存取外,保護應用工作負載本身免受攻擊也至關重要。這涉及到多層次的安全措施:

  1. 容器安全上下文:限制容器的許可權和能力
  2. Pod 安全策略:在叢集層級強制執行安全最佳實踐
  3. 網路策略:控制 Pod 之間以及與外部系統的通訊
  4. 資源限制:防止資源耗盡攻擊

容器安全上下文範例

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  containers:
  - name: secure-container
    image: nginx:latest
    securityContext:
      allowPrivilegeEscalation: false
      runAsNonRoot: true
      runAsUser: 1000
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE

這個 Pod 定義包含了多項安全強化措施。allowPrivilegeEscalation: false 防止容器取得比其父程式更多的許可權,這是防止許可權提升攻擊的關鍵。runAsNonRoot: truerunAsUser: 1000 確保容器以非 root 使用者執行,這是容器安全的基本實踐。

在 capabilities 部分,首先透過 drop: ["ALL"] 移除所有 Linux 能力,然後只增加 NET_BIND_SERVICE 能力,允許容器繫結到低於 1024 的連線埠(如 HTTP 的 80 連線埠)。這種精確控制遵循最小許可權原則,只授予應用程式所需的確切能力,大幅減少攻擊面。

實施 Pod 安全標準

Kubernetes 提供了 Pod 安全標準 (Pod Security Standards),定義了三種安全策略級別:Privileged(特權)、Baseline(基準)和 Restricted(受限)。在生產環境中,應盡可能使用 Restricted 策略。

# 在名稱空間層級實施受限安全策略
apiVersion: v1
kind: Namespace
metadata:
  name: restricted-ns
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

這個名稱空間定義使用 Kubernetes 1.23+ 引入的 Pod 安全准入控制器,透過標籤設定強制執行最嚴格的 “restricted” 安全標準。enforce 標籤會阻止不符合標準的 Pod 建立,audit 會記錄違規行為,而 warn 則會向使用者發出警告。這種方法在名稱空間層級實施安全策略,確保所有佈署到該名稱空間的工作負載都符合嚴格的安全標準,無需為每個 Pod 單獨設定安全上下文。

監控與稽核

除了預防性控制外,監控和稽核也是安全策略的重要組成部分。Kubernetes 稽核日誌可以記錄所有 API 請求,幫助檢測和調查潛在的安全事件。

# API 伺服器稽核策略設定
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
  resources:
  - group: ""
    resources: ["pods", "services", "configmaps"]
- level: Request
  resources:
  - group: ""
    resources: ["secrets"]
  - group: "rbac.authorization.k8s.io"
    resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
- level: None
  users: ["system:serviceaccount:kube-system:default"]
  resources:
  - group: ""
    resources: ["endpoints", "services", "services/status"]

這個稽核策略設定義了不同資源型別的稽核級別。對於一般資源如 pods 和 services,設定為 Metadata 級別,只記錄請求的中繼資料(如使用者、時間、資源)而不包含請求體。對於敏感資源如 secrets 和 RBAC 資源,設定為 Request 級別,記錄完整的請求內容,便於安全稽核。

同時,策略排除了對 kube-system 名稱空間中預設服務帳號的某些常規操作的稽核,以減少稽核日誌中的噪音。這種分層稽核策略在保持全面可見性的同時,最佳化了儲存和處理需求,特別適合大型生產環境。

安全最佳實踐總結

保護 Kubernetes 環境需要多層次的安全控制:

  1. 正確設定 Kubernetes 元件,確保基礎設施安全
  2. 實施嚴格的存取控制,遵循最小許可權原則
  3. 使用名稱空間隔離不同的應用和團隊
  4. 為服務帳號分配有限許可權,減少潛在攻擊面
  5. 強化容器和 Pod 安全設定,防止許可權提升和容器逃逸
  6. 實施網路策略,控制 Pod 間通訊
  7. 設定資源限制,防止資源耗盡攻擊
  8. 啟用稽核日誌,監控和調查可疑活動

在實施這些控制時,玄貓建議採用漸進式方法,從最關鍵的系統開始,逐步擴充套件到整個環境。同時,定期進行安全評估和滲透測試,確保控制措施有效運作。

安全不是一次性工作,而是持續的過程。隨著新威脅的出現和 Kubernetes 的演進,安全策略和控制措施也需要不斷更新和改進。透過正確設定 Kubernetes 元件並實施適當的存取控制,可以顯著提高環境的安全性,保護關鍵應用和資料免受潛在威脅。

確保 Kubernetes 叢集免於已知漏洞的威脅

在現代雲原生環境中,確保 Kubernetes 叢集不執行含有已知漏洞的程式碼是安全防護的關鍵環節。隨著容器化應用程式的普及,攻擊面也隨之擴大,使得漏洞管理變得更加複雜與至關重要。玄貓在多年的雲端安全實踐中發現,許多組織往往忽略了這一基本但極為重要的安全層面。

漏洞管理的挑戰與重要性

Kubernetes 環境中的漏洞管理面臨獨特挑戰。容器映像檔通常包含數百個軟體套件,每個套件都可能存在安全漏洞。更複雜的是,這些映像檔一旦佈署,往往長時間執行而不更新,使得已知漏洞的風險持續存在。

容器安全的特殊考量

容器環境與傳統環境的漏洞管理有顯著差異:

  1. 不可變基礎設施模式 - 容器通常遵循不可變基礎設施原則,意味著修補漏洞需要重建並重新佈署映像檔,而非直接更新執行中的容器
  2. 映像檔層級結構 - 容器映像檔的層級結構使得漏洞可能隱藏在底層,增加了檢測難度
  3. 供應鏈複雜性 - 容器通常依賴於多個來源的基礎映像檔和套件,形成複雜的供應鏈

建立全面的容器映像檔掃描策略

要有效管理 Kubernetes 環境中的漏洞,需要實施全面的映像檔掃描策略。

映像檔掃描的關鍵時機

玄貓建議在容器生命週期的多個階段進行掃描:

  1. 開發階段掃描 - 在開發過程中及早發現漏洞,降低後期修復成本
  2. CI/CD 管道整合 - 在持續整合流程中自動掃描映像檔,防止有漏洞的映像檔進入生產環境
  3. 映像檔倉函式庫掃描 - 定期掃描儲存在倉函式庫中的映像檔,識別新發現的漏洞
  4. 執行時掃描 - 持續監控生產環境中執行的容器,及時發現新出現的威脅

實作映像檔掃描的工具選擇

市場上有多種工具可用於容器映像檔掃描,每種工具都有其優勢和限制:

  1. Trivy - 輕量級、高效的開放原始碼掃描工具,支援多種映像檔格式
  2. Clair - CoreOS 開發的開放原始碼掃描工具,專為大規模佈署設計
  3. Anchore Engine - 提供深度分析和政策執行的開放原始碼解決方案
  4. Aqua Security - 商業解決方案,提供全面的容器安全功能
  5. Snyk - 專注於依賴項漏洞的掃描工具,與多種 CI/CD 工具整合良好

在 CI/CD 管道中整合漏洞掃描

將漏洞掃描整合到 CI/CD 管道是防止有漏洞的程式碼進入生產環境的有效方法。

使用 Trivy 在 CI/CD 管道中掃描映像檔

以下是在 GitLab CI/CD 管道中整合 Trivy 的範例:

stages:
  - build
  - scan
  - deploy

build_image:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

vulnerability_scan:
  stage: scan
  script:
    - docker pull aquasec/trivy:latest
    - docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy:latest image --severity HIGH,CRITICAL --exit-code 1 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  allow_failure: false

deploy_to_k8s:
  stage: deploy
  script:
    - kubectl set image deployment/myapp container=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  only:
    - master
  when: on_success

這個 GitLab CI/CD 設定案定義了三個階段:構建、掃描和佈署。在構建階段,它使用 Dockerfile 建立容器映像檔並推播到 GitLab 的容器倉函式庫。掃描階段使用 Trivy 檢查映像檔中的高風險和嚴重漏洞,如果發現這類別漏洞,管道會失敗(exit-code 1)。只有當掃描透過時,才會執行佈署階段,將映像檔佈署到 Kubernetes 叢集。allow_failure: false 確保掃描失敗時整個管道會停止,防止有漏洞的映像檔進入生產環境。

實施映像檔安全最佳實踐

除了掃描外,還應採用以下最佳實踐來減少容器映像檔中的漏洞:

使用精簡的基礎映像檔

選擇精簡的基礎映像檔可以顯著減少潛在漏洞的數量。例如,使用 Alpine Linux 而非完整的 Ubuntu 映像檔:

# 不推薦:使用完整的 Ubuntu 映像檔
FROM ubuntu:20.04

# 推薦:使用 Alpine 映像檔
FROM alpine:3.14

# 更好:使用特定語言的精簡映像檔
FROM python:3.9-alpine

這個 Dockerfile 範例展示了基礎映像檔選擇的最佳實踐。完整的 Ubuntu 映像檔包含許多不必要的套件,每個套件都可能引入漏洞。Alpine Linux 是一個極小的 Linux 發行版,基礎映像檔僅約 5MB,大減少了攻擊面。語言特定的精簡映像檔(如 python:3.9-alpine)則提供了必要的語言環境,同時保持最小的映像檔大小。選擇精簡映像檔不僅可以減少漏洞,還能提高容器啟動速度和減少資源消耗。

多階段構建減少依賴

使用多階段構建可以減少最終映像檔中的依賴項和潛在漏洞:

# 構建階段
FROM golang:1.17-alpine AS builder

WORKDIR /app
COPY . .
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .

# 最終階段
FROM alpine:3.14

RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

這個多階段 Dockerfile 展示瞭如何減少最終映像檔中的漏洞。第一階段使用 Go 環境編譯應用程式,包含所有構建工具和依賴項。第二階段僅從第一階段複製編譯好的二進位檔案到一個全新的 Alpine 映像檔中。這種方法有幾個優勢:1) 最終映像檔不包含構建工具和原始碼,減少了攻擊面;2) 映像檔體積顯著減小,通常可減少 90% 以上;3) 減少了依賴項,從而減少了潛在漏洞。CGO_ENABLED=0-installsuffix cgo 確保構建的是靜態二進位檔案,不依賴於系統函式庫。

定期更新基礎映像檔

定期更新基礎映像檔是減少漏洞的關鍵策略。可以透過自動化工具如 Renovate 或 Dependabot 來實作:

# renovate.json
{
  "extends": [
    "config:base"
  ],
  "dockerfile": {
    "enabled": true,
    "pinDigests": true
  },
  "dependencyDashboard": true,
  "automerge": false
}

這個 Renovate 設定案設定了自動監控和更新 Dockerfile 中的基礎映像檔。"dockerfile": { "enabled": true } 啟用了 Dockerfile 更新功能,"pinDigests": true 確保使用映像檔的確切雜湊值而非標籤,提高安全性和可重現性。"dependencyDashboard": true 建立一個依賴項更新儀錶板,方便團隊審查更新。"automerge": false 要求人工審查更新,避免自動合併可能導致的問題。定期更新基礎映像檔確保獲得最新的安全修補,但需要平衡更新頻率與穩定性需求。

在 Kubernetes 中實施執行時漏洞掃描

除了在 CI/CD 管道中掃描映像檔外,還應在 Kubernetes 叢集中實施執行時漏洞掃描。

使用 Trivy Operator 持續監控容器漏洞

Trivy Operator 是一個 Kubernetes Operator,可以持續掃描叢集中執行的容器映像檔:

# 安裝 Trivy Operator
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: trivy-operator
  namespace: trivy-system
spec:
  interval: 1h
  chart:
    spec:
      chart: trivy-operator
      version: '0.3.x'
      sourceRef:
        kind: HelmRepository
        name: aqua
        namespace: flux-system
  values:
    trivy:
      ignoreUnfixed: true
    operator:
      scan工作Timeout: 5m

這個 Helm Release 定義瞭如何使用 Flux CD 佈署 Trivy Operator 到 Kubernetes 叢集。Trivy Operator 會自動掃描叢集中的所有容器映像檔,並建立包含漏洞訊息的 Kubernetes 自定義資源。ignoreUnfixed: true 設定使 Trivy 忽略尚未有修復方案的漏洞,減少噪音。scan工作Timeout: 5m 設定掃描作業的超時間為 5 分鐘,避免掃描過程卡住。Trivy Operator 的優勢在於它能持續監控叢集中的所有容器,當發現新漏洞時自動更新掃描結果,無需手動干預。這為安全團隊提供了叢集漏洞狀態的實時檢視。

檢視漏洞掃描結果

佈署 Trivy Operator 後,可以使用以下命令檢視漏洞掃描結果:

# 檢視所有漏洞報告
kubectl get vulnerabilityreports --all-namespaces

# 檢視特定工作負載的詳細漏洞報告
kubectl describe vulnerabilityreport -n default deployment-myapp-6d5bc7b867-container

這些 kubectl 命令用於查詢 Trivy Operator 生成的漏洞報告。第一個命令列出所有名稱空間中的漏洞報告,提供叢集範圍的漏洞概覽。第二個命令顯示特定容器的詳細漏洞訊息,包括漏洞 ID、嚴重性、受影響的套件以及可用的修復版本。這些報告是 Kubernetes 自定義資源,遵循 Kubernetes 的宣告式模型,可以使用標準 Kubernetes 工具進行查詢和管理。安全團隊可以根據這些報告設定監控和警示,當發現嚴重漏洞時立即採取行動。

實施映像檔准入控制

為了防止有漏洞的映像檔佈署到叢集,可以實施映像檔准入控制。

使用 OPA Gatekeeper 實施映像檔安全策略

OPA Gatekeeper 是一個強大的策略引擎,可用於實施映像檔安全策略:

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8strustedimages
spec:
  crd:
    spec:
      names:
        kind: K8sTrustedImages
      validation:
        openAPIV3Schema:
          properties:
            registries:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8strustedimages
        
        violation[{"msg": msg}] {
          image := input.review.object.spec.containers[_].image
          not startswith(image, concat("", [registry, "/"]))
          registry := input.parameters.registries[_]
          msg := sprintf("Image '%v' comes from untrusted registry", [image])
        }

這個 OPA Gatekeeper ConstraintTemplate 定義了一個策略,只允許來自受信任倉函式庫的映像檔佈署到叢集。K8sTrustedImages 是一個自定義資源定義,允許指定受信任的映像檔倉函式庫列表。Rego 策略語言用於實作驗證邏輯:它檢查每個容器的映像檔是否來自受信任的倉函式庫,如果不是,則生成違規訊息並阻止佈署。這種准入控制機制在映像檔佈署到叢集前進行檢查,提供了一個額外的安全層。除了倉函式庫驗證外,還可以擴充套件此策略以檢查映像檔是否已透過漏洞掃描、是否有數位簽名等。

應用 Gatekeeper 約束

定義了範本後,需要建立一個約束例項來應用策略:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sTrustedImages
metadata:
  name: trusted-images
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    namespaces:
      - "default"
      - "production"
  parameters:
    registries:
      - "registry.company.com"
      - "gcr.io/company-project"
      - "docker.io/company"

這個 Gatekeeper 約束例項應用了前面定義的 K8sTrustedImages 範本。它指定了策略適用的資源型別(Pod)和名稱空間(default 和 production)。parameters.registries 列出了允許的映像檔倉函式庫,只有來自這些倉函式庫的映像檔才能佈署到指定的名稱空間。這種方法實作了強制性的映像檔來源控制,確保只有經過組織審核和批准的映像檔源才能使用。約束可以根據不同環境的安全需求進行調整,例如開發環境可能有較寬鬆的策略,而生產環境則實施更嚴格的控制。

使用 Admission Controllers 進行漏洞阻斷

除了 OPA Gatekeeper,還可以使用專門的准入控制器來阻止有漏洞的映像檔佈署。

佈署 Kyverno 策略引擎

Kyverno 是一個專為 Kubernetes 設計的策略引擎,可用於實施映像檔安全策略:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: block-vulnerable-images
spec:
  validationFailureAction: enforce
  background: false
  rules:
  - name: check-image-vulnerability
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "Image contains vulnerabilities"
      webhook:
        service:
          name: trivy-service
          namespace: security
          path: "/validate"
        timeoutSeconds: 10

這個 Kyverno ClusterPolicy 定義了一個策略,使用外部 webhook 服務檢查映像檔是否存在漏洞。validationFailureAction: enforce 表示如果映像檔包含漏洞,佈署將被阻止。background: false 表示策略只應用於新建的資源,不會對現有資源進行驗證。策略規則指定了它適用於所有 Pod 資源,並使用名為 trivy-service 的 webhook 服務進行漏洞驗證。這種方法的優勢在於它將策略定義與漏洞掃描邏輯分離,允許使用專門的漏洞掃描服務。Kyverno 相比 OPA Gatekeeper 的一個優勢是其更簡單的策略語法和內建的 Kubernetes 資源驗證功能。

建立漏洞管理流程

技術工具只是漏洞管理的一部分,還需要建立完整的流程來管理和修復漏洞。

漏洞管理流程的關鍵元素

有效的漏洞管理流程應包含以下元素:

  1. 漏洞識別 - 使用多種工具和來源識別漏洞
  2. 風險評估 - 評估漏洞的嚴重性和潛在影響
  3. 優先順序排序 - 根據風險評估結果對漏洞進行優先順序排序
  4. 修復計劃 - 制定修復計劃,包括時間表和責任人
  5. 修復驗證 - 驗證修復措施的有效性
  6. 持續監控 - 持續監控新漏洞和修復狀態

使用 Kubernetes 自定義資源跟蹤漏洞修復

可以使用 Kubernetes 自定義資源來跟蹤漏洞修復進度:

apiVersion: security.company.com/v1
kind: VulnerabilityTicket
metadata:
  name: cve-2021-44228-log4j
  namespace: security
spec:
  cveId: CVE-2021-44228
  severity: Critical
  affectedWorkloads:
  - namespace: default
    name: payment-service
    kind: Deployment
  - namespace: backend
    name: order-processor
    kind: 有狀態集合
  remediationPlan: "Update Log4j to version 2.17.0 or later"
  assignee: "security-team"
  dueDate: "2024-01-15"
  status: InProgress

這個自定義資源定義了一個漏洞修復票據,用於跟蹤特定漏洞(這裡是著名的 Log4j 漏洞)的修復進度。它包含漏洞識別符、嚴重性、受影響的工作負載列表、修復計劃、負責人、截止日期和當前狀態。使用 Kubernetes 自定義資源來管理漏洞修復有幾個優勢:1) 它與現有的 Kubernetes 工具和流程整合;2) 它可以使用 Kubernetes RBAC 控制存取許可權;3) 它可以透過 Kubernetes 控制器自動化修復流程;4) 它提供了一個統一的介面來查詢和報告漏洞修復狀態。這種方法將安全管理與基礎設施管理緊密結合,促進了 DevSecOps 實踐。

容器執行時安全監控

除了靜態掃描,還需要實施容器執行時安全監控,以檢測和防止利用已知漏洞的攻擊。

佈署 Falco 進行執行時安全監控

Falco 是一個開放原始碼的容器執行時安全監控工具,可以檢測異常行為:

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: falco
  namespace: security
spec:
  interval: 1h
  chart:
    spec:
      chart: falco
      version: '1.16.x'
      sourceRef:
        kind: HelmRepository
        name: falco
        namespace: flux-system
  values:
    falco:
      jsonOutput: true
      programOutput:
        enabled: true
        keepAlive: false
        program: "curl -d @- -X POST http://alert-manager:8080/events"
    customRules:
      rules-vuln-exploit.yaml: |-
        - rule: Detect Log4j Exploitation Attempt
          desc: Detects attempts to exploit Log4j vulnerability
          condition: >
            spawned_process and
            ((proc.name = "java" and proc.args contains "jndi:ldap") or
             (proc.name = "curl" and proc.args contains "jndi:ldap"))
          output: "Log4j exploitation attempt (user=%user.name command=%proc.cmdline)"
          priority: CRITICAL
          tags: [vulnerability, exploitation, log4j, cve-2021-44228]

這個 Helm Release 定義瞭如何佈署 Falco 到 Kubernetes 叢集。Falco 使用系統呼叫監控來檢測容器中的異常行為,包括可能的漏洞利用嘗試。設定中啟用了 JSON 輸出和程式輸出,將警示傳送到 alert-manager 服務。自定義規則部分定義了一個特定規則,用於檢測 Log4j 漏洞的利用嘗試。規則監控程式建立事件,尋找包含 “jndi:ldap” 的 Java 或 curl 命令,這是 Log4j 漏洞利用的常見特徵。當檢測到比對條件時,Falco 會生成一個關鍵級別的警示,包含使用者名和完整命令列。這種執行時監控提供了一個額外的安全層,即使有漏洞的容器已經佈署,也能檢測到實際的利用嘗試。

建立全面的漏洞管理策略

綜合以上各點,玄貓建議建立一個全面的漏洞管理策略,涵蓋容器生命週期的各個階段。

漏洞管理策略的關鍵元件

一個有效的 Kubernetes 漏洞管理策略應包含以下元件:

  1. 開發階段安全 - 在開發過程中使用安全掃描工具,及早發現並修復漏洞
  2. CI/CD 整合 - 在 CI/CD 管道中整合漏洞掃描,阻止有漏洞的映像檔進入生產環境
  3. 映像檔倉函式庫安全 - 定期掃描映像檔倉函式庫,識別新發現的漏洞
  4. 准入控制 - 使用准入控制器阻止有漏洞的映像檔佈署到叢集
  5. 執行時監控 - 持續監控執行中的容器,檢測漏洞利用嘗試
  6. 漏洞修復流程 - 建立明確的流程來管理和修復發現的漏洞
  7. 安全意識培訓 - 提高開發和維運團隊的安全意識,培養安全文化

圖表說明漏洞管理流程

  flowchart TD
    C[C]
    G[G]
    K[K]
    Q[Q]
    U[U]
    A[開發] --> B[程式碼掃描]
    B --> C{發現漏洞?}
    C -->|是| D[修復漏洞]
    D --> B
    C -->|否| E[構建映像檔]
    E --> F[映像檔掃描]
    F --> G{發現漏洞?}
    G -->|是| H[更新基礎映像檔/依賴]
    H --> E
    G -->|否| I[推播到倉函式庫]
    I --> J[定期倉函式庫掃描]
    J --> K{發現新漏洞?}
    K -->|是| L[標記映像檔為有漏洞]
    L --> M[通知團隊]
    M --> N[更新映像檔]
    N --> E
    K -->|否| O[佈署到 Kubernetes]
    O --> P[准入控制檢查]
    P --> Q{透過檢查?}
    Q -->|否| R[拒絕佈署]
    R --> M
    Q -->|是| S[佈署到叢集]
    S --> T[執行時監控]
    T --> U{檢測到異常?}
    U -->|是| V[觸發警示]
    V --> W[調查與修復]
    W --> N
    U -->|否| X[持續監控]

結論與最佳實踐

確保 Kubernetes 叢集不執行含有已知漏洞的程式碼是一個持續的過程,需要在容器生命週期的各個階段實施安全措施。透過結合靜態掃描、准入控制和執行時監控,可以顯著降低漏洞帶來的風險。

玄貓建議採用「深度防禦」策略,在多個層面實施安全控制,而不僅依賴單一工具或方法。同時,漏洞管理不僅是技術問題,還需要建立明確的流程和責任分配,以確保及時有效地修復發現的漏洞。

最後,隨著新漏洞的不斷發現和容器技術的快速發展,漏洞管理策略也需要不斷演進和完善。定期審查和更新安全措施,跟蹤安全社群的最新發展,是維護 Kubernetes 環境安全的關鍵。

在容器化世界中,安全不是一次性的工作,而是一個持續的旅程。透過實施本文介紹的方法和工具,組織可以顯著提高其 Kubernetes 環境的安全性,減少已知漏洞帶來的風險。

保護容器執行時安全:限制攻擊者濫用容器的進階策略

Kubernetes 作為現代容器協調平台,其安全性不僅取決於初始設定,更需要在執行時實施有效的限制措施。玄貓在多年的容器安全實踐中發現,執行時的安全控制是防止攻擊者利用容器漏洞的關鍵防線。

容器執行時行為限制的重要性

容器技術雖然提供了隔離環境,但預設設定往往過於寬鬆,為潛在攻擊者提供了可乘之機。實施執行時限制不僅能減少攻擊面,還能在攻擊發生時將損害控制在最小範圍內。

常見的容器濫用途徑

當攻擊者取得容器存取許可權後,通常會嘗試:

  1. 提升許可權以取得主機系統存取
  2. 橫向移動到其他容器或服務
  3. 竊取敏感憑證或設定
  4. 利用容器資源進行惡意活動

實施有效的執行時安全控制

容器權限制

apiVersion: v1
kind: Pod
metadata:
  name: restricted-pod
spec:
  containers:
  - name: restricted-container
    image: nginx
    securityContext:
      allowPrivilegeEscalation: false
      runAsNonRoot: true
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE

這個 Pod 定義展示了關鍵的安全限制:allowPrivilegeEscalation: false 防止容器程式取得比父程式更高的許可權;runAsNonRoot: true 確保容器以非 root 使用者執行;而 capabilities 設定則移除了所有 Linux 能力,只增加了繫結低連線埠所需的 NET_BIND_SERVICE 能力。這種最小許可權原則大幅降低了容器被濫用的風險。

資源限制實施

除了許可權控制外,設定資源限制也是防止容器被濫用的重要手段:

apiVersion: v1
kind: Pod
metadata:
  name: resource-limited-pod
spec:
  containers:
  - name: limited-container
    image: myapp
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

這個設定為容器設定了明確的資源請求和上限。CPU 限制為 0.5 核心,記憶體限制為 128MB。這不僅能防止容器因資源耗盡影響其他工作負載,還能限制攻擊者利用容器資源進行密碼破解或加密貨幣挖礦等惡意活動。玄貓建議根據應用實際需求設定這些值,過低會影回應用效能,過高則無法有效限制攻擊者。

進階容器隔離技術

使用 Pod 安全策略

雖然 Pod 安全策略 (PSP) 已被棄用,但其繼任者 Pod Security Admission 提供了類別似功能:

apiVersion: v1
kind: Namespace
metadata:
  name: restricted-namespace
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

這個名稱空間設定啟用了 “restricted” 安全策略,強制執行一系列安全最佳實踐。它會阻止建立具有危險設定的 Pod,如特權容器或掛載敏感主機路徑的容器。這種名稱空間級別的控制為整個應用提供了一致的安全基線。

實施 AppArmor 設定檔案

AppArmor 提供了更細粒度的程式限制:

apiVersion: v1
kind: Pod
metadata:
  name: apparmor-pod
  annotations:
    container.apparmor.security.beta.kubernetes.io/secure-container: localhost/k8s-apparmor-example-deny-write
spec:
  containers:
  - name: secure-container
    image: busybox
    command: ["sh", "-c", "echo 'Hello AppArmor!' && sleep 1h"]

這個 Pod 使用了自定義的 AppArmor 設定檔案 k8s-apparmor-example-deny-write,該設定檔案限制了容器的寫入操作。這種方法可以防止攻擊者修改容器內的關鍵檔案,即使他們已經獲得了容器的存取許可權。AppArmor 提供了比基本容器安全上下文更精細的控制,但需要在節點上預先設定相應的設定檔案。

執行時威脅檢測與回應

限制容器行為只是第一步,還需要實施監控以檢測潛在的安全事件:

apiVersion: v1
kind: Pod
metadata:
  name: falco-monitoring
  namespace: security-monitoring
spec:
  containers:
  - name: falco
    image: falcosecurity/falco:latest
    securityContext:
      privileged: true
    volumeMounts:
    - name: dev-fs
      mountPath: /host/dev
    - name: proc-fs
      mountPath: /host/proc
    - name: boot-fs
      mountPath: /host/boot
    - name: lib-modules
      mountPath: /host/lib/modules
    - name: usr-fs
      mountPath: /host/usr
  volumes:
  - name: dev-fs
    hostPath:
      path: /dev
  - name: proc-fs
    hostPath:
      path: /proc
  - name: boot-fs
    hostPath:
      path: /boot
  - name: lib-modules
    hostPath:
      path: /lib/modules
  - name: usr-fs
    hostPath:
      path: /usr

這個設定佈署了 Falco,一個開放原始碼的容器執行時安全監控工具。Falco 需要以特權模式執行並存取多個主機檔案系統,以監控系統呼叫並檢測異常行為。雖然這看似違反了最小許可權原則,但這是安全監控工具的必要設定。Falco 可以檢測諸如異常程式執行、特權提升嘗試和敏感檔案存取等行為,並觸發警示或自動回應。

保護容器憑證安全

容器中的憑證管理是另一個關鍵安全領域。攻擊者常以儲存在容器中的憑證為目標,因為這些憑證可能提供對其他系統的存取許可權。

使用 Kubernetes Secrets

apiVersion: v1
kind: Secret
metadata:
  name: api-credentials
type: Opaque
data:
  api-key: VGhpcyBpcyBhIHNlY3JldCBrZXk=
apiVersion: v1
kind: Pod
metadata:
  name: secure-app-external-secrets
spec:
  volumes:
  - name: secrets-store
    csi:
      driver: secrets-store.csi.k8s.io
      readOnly: true
      volumeAttributes:
        secretProviderClass: "aws-secrets"
  containers:
  - name: app
    image: myapp
    volumeMounts:
    - name: secrets-store
      mountPath: "/mnt/secrets-store"
      readOnly: true

這個設定使用 Secrets Store CSI Driver 從 AWS Secrets Manager 取得憑證,並將其掛載為容器內的檔案。這種方法有多重優勢:憑證儲存在專用的金鑰管理系統中、可以實施精細的存取控制、支援自動輪換,並且可以稽核所有存取。這大降低了憑證被竊取的風險,即使攻擊者獲得了容器的存取許可權。

容器執行時安全的最佳實踐

根據玄貓在多個企業環境中的實施經驗,以下是確保容器執行時安全的關鍵最佳實踐:

  1. 實施最小許可權原則:容器應只擁有完成其任務所需的最低許可權

  2. 使用只讀檔案系統:對不需要寫入的容器,設定只讀檔案系統可以防止惡意軟體修改系統檔案

  3. 限制系統呼叫:使用 seccomp 設定檔案限制容器可以執行的系統呼叫

  4. 實施網路政策:限制容器間通訊,防止橫向移動

  5. 定期更新基礎映像:使用最新的安全補丁更新容器基礎映像

  6. 實施執行時監控:佈署工具檢測異常行為並自動回應

  7. 使用服務網格加密:在服務間實施 mTLS 加密,防止中間人攻擊

容器安全的演進趨勢

容器安全領域正在快速發展,玄貓觀察到幾個關鍵趨勢:

  1. 零信任安全模型的應用,要求所有容器間通訊都經過身份驗證和授權

  2. 供應鏈安全的重視,從映像構建到佈署的全流程安全控制

  3. 自適應安全策略,根據容器行為模式自動調整安全控制

  4. 安全即程式碼方法,將安全控制整合到 CI/CD 流程中

容器執行時安全是一個多層次的挑戰,需要結合多種技術和最佳實踐。透過實施這些限制和控制,可以顯著降低攻擊者濫用容器的可能性,即使他們成功突破了初始防線。隨著容器技術的不斷發展,安全控制也需要相應演進,以應對新興的威脅和挑戰。