容器化應用程式盛行,映像檔安全成為 DevOps 流程關鍵環節。本文探討如何有效管理容器映像檔中的漏洞,涵蓋 CVE 與 NVD 等漏洞資料函式庫的應用,以及如何利用 CVSS 評分系統評估漏洞風險。文章以開源工具 Anchore Engine 為例,詳細說明如何掃描映像檔並執行政策評估,確保符合安全規範。最後,示範如何將映像檔掃描整合至 CI/CD 管道(如 GitHub Actions),實作自動化漏洞檢測與風險管理,強化容器化應用程式的安全性。

容器映像檔與漏洞管理

在 DevOps 流程中,映像檔掃描是確保容器化應用程式安全性的重要步驟。當我們談論容器映像檔的安全性時,不僅僅是尋找安全漏洞,更重要的是瞭解如何管理這些已知的漏洞。本章將討論如何透過漏洞管理來發現和管理已知的漏洞,以及如何在社群中追蹤和分享這些漏洞。

漏洞資料函式庫簡介

CVE(Common Vulnerability and Exposure)是一個用於識別和追蹤漏洞的資料函式庫。每當發現一個新的漏洞時,MITRE 就會為其分配一個唯一的 CVE ID,並提供描述和公開參考。NVD(National Vulnerability Database)則是同步 CVE 清單的資料函式庫,一旦 CVE 清單有新的更新,NVD 就會立即更新。

除了 NVD 之外,還有一些其他的漏洞資料函式庫,如 Synk。映像檔掃描工具的工作原理是提取映像檔中的可用套件和函式庫,並在漏洞資料函式庫中查詢其版本。如果發現任何套件的版本與 CVE 描述中的版本相符,掃描工具就會報告該映像檔存在漏洞。

管理漏洞

當我們擁有一個漏洞管理策略時,就不會驚慌失措。一般來說,每個漏洞管理策略都會從瞭解漏洞的可利用性和影響開始。NVD 提供了一個漏洞評分系統,也稱為 CVSS(Common Vulnerability Scoring System),幫助我們瞭解漏洞的嚴重程度。

要計算漏洞評分,需要提供以下資訊:

  • 攻擊向量:是否是網路攻擊、本地攻擊或實體攻擊
  • 攻擊複雜度:利用漏洞的難度
  • 許可權要求:是否需要特定的許可權,如 root 或非 root
  • 使用者互動:是否需要使用者互動
  • 範圍:是否會導致跨安全域
  • 保密性影響:對軟體保密性的影響
  • 完整性影響:對軟體完整性的影響
  • 可用性影響:對軟體可用性的影響

CVSS 計算器可於 https://nvd.nist.gov/vuln-metrics/cvss/v3-calculator 使用。根據 CVSS(版本 3),評分範圍分為四個等級:

  • 低:0.1-3.9
  • 中:4-6.9
  • 高:7-8.9
  • 嚴重:9-10

通常,映像檔掃描工具會在報告漏洞時提供 CVSS 評分。然而,在採取任何回應措施之前,還需要進行進一步的漏洞分析。我們需要了解漏洞的嚴重程度可能會受到自身環境的影響。例如,如果漏洞只在 Windows 上可被利用,但基礎 OS 映像檔不是 Windows,那麼該漏洞就不是那麼重要。

使用 Anchore Engine 掃描映像檔

Anchore Engine 是一個開源的映像檔掃描工具。它不僅分析 Docker 映像檔,還允許使用者定義接受映像檔掃描策略。本文將介紹 Anchore Engine 的基本使用案例。

Anchore Engine 簡介

當映像檔被提交給 Anchore Engine 分析時,Anchore Engine 首先會檢索映像檔的後設資料,然後下載映像檔並將其加入分析佇列。Anchore Engine 將分析以下專案:

  • 映像檔後設資料
  • 映像檔層
  • 作業系統套件,如 deb、rpm、apkg 等
  • 檔案資料
  • 應用程式依賴套件,如 Ruby gems、Node.js NPMs、Java archives 和 Python packages
  • 檔案內容

要使用 Helm 在 Kubernetes 叢集中佈署 Anchore Engine,請執行以下命令:

$ helm install anchore-demo stable/anchore-engine

Anchore Engine 由多個微服務組成。在 Kubernetes 叢集中佈署後,您將看到以下工作負載正在執行:

$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
anchore-demo-anchore-engine-analyzer 1/1 1 1 3m37s
anchore-demo-anchore-engine-api 1/1 1 1 3m37s
anchore-demo-anchore-engine-catalog 1/1 1 1 3m37s
anchore-demo-anchore-engine-policy 1/1 1 1 3m37s

使用 anchore-cli 操作 Anchore Engine

Anchore Engine 提供了一個 CLI 工具 anchore-cli,可以用來操作 Anchore Engine。下面是一個簡單的例子:

$ anchore-cli image add <image_name>
$ anchore-cli image wait <image_id>
$ anchore-cli image vuln <image_id> all

程式碼解析:

$ helm install anchore-demo stable/anchore-engine

內容解密:

此命令使用 Helm 在 Kubernetes 叢集中佈署 Anchore Engine。其中 anchore-demo 是佈署的名稱,stable/anchore-engine 是 Anchore Engine 的 Helm Chart。

$ kubectl get deploy

內容解密:

此命令用於檢視 Kubernetes 叢集中正在執行的 Deployment。其中 NAME 列顯示了 Deployment 的名稱,READY 列顯示了準備就緒的副本數量,UP-TO-DATE 列顯示了最新的副本數量,AVAILABLE 列顯示了可用的副本數量,AGE 列顯示了 Deployment 的存活時間。

$ anchore-cli image add <image_name>
$ anchore-cli image wait <image_id>
$ anchore-cli image vuln <image_id> all

內容解密:

這三個命令用於使用 anchore-cli 操作 Anchore Engine。第一個命令將指定的映像檔新增到 Anchore Engine 中。第二個命令等待指定的映像檔分析完成。第三個命令顯示指定映像檔的所有漏洞。

使用 Anchore Engine 掃描映像檔

Anchore Engine 將映像檔掃描服務分解為多個微服務,如前面的日誌所示:

  • API:接受映像檔掃描請求
  • Catalog:維護映像檔掃描作業的狀態
  • Policy:載入映像檔分析結果並執行政策評估
  • Analyzer:從映像檔登入檔提取映像檔並執行分析
  • Simplequeue:佇列映像檔掃描任務
  • PostgreSQL:儲存映像檔分析結果和狀態

現在 Anchore Engine 已成功佈署在 Kubernetes 叢集中,讓我們看看如何使用 anchore-cli 進行映像檔掃描。

使用 anchore-cli 掃描映像檔

Anchore Engine 支援透過 RESTful API 和 anchore-cli 進行存取。anchore-cli 在迭代式操作中很方便使用,不需要在 Kubernetes 叢集中執行。你需要設定以下環境變數以啟用 CLI 對 Anchore Engine 的存取:

  • ANCHORE_CLI_URL:Anchore Engine API 端點
  • ANCHORE_CLI_USER:存取 Anchore Engine 的使用者名稱
  • ANCHORE_CLI_PASS:存取 Anchore Engine 的密碼

設定環境變數後,可以使用以下命令驗證與 Anchore Engine 的連線:

root@anchore-cli:/# anchore-cli system status

輸出應該類別似如下:

Service analyzer (anchore-demo-anchore-engine-analyzer-5fd777cfb5-jtqp2, http://anchore-demo-anchore-engine-analyzer:8084): up
Service apiext (anchore-demo-anchore-engine-api-6dd475cf-n24xb, http://anchore-demo-anchore-engine-api:8228): up
Service policy_engine (anchore-demo-anchore-engine-policy-7b8f68fbc-q2dm2, http://anchore-demo-anchore-engine-policy:8087): up
Service simplequeue (anchore-demo-anchore-engine-simplequeue-6d4567c7f4-7sll5, http://anchore-demo-anchore-engine-simplequeue:8083): up
Service catalog (anchore-demo-anchore-engine-catalog-949bc68c9-np2pc, http://anchore-demo-anchore-engine-catalog:8082): up
Engine DB Version: 0.0.12
Engine Code Version: 0.6.1

anchore-cli 能夠與 Kubernetes 叢集中的 Anchore Engine 通訊。現在讓我們使用以下命令掃描一個映像檔:

root@anchore-cli:/# anchore-cli image add kaizheh/nginx-docker

輸出應該類別似如下:

Image Digest: sha256:416b695b09a79995b3f25501bf0c9b9620e82984132060bf7d66d8776c1554b7
Parent Digest: sha256:416b695b09a79995b3f25501bf0c9b9620e82984132060bf7d66d8776c1554b7
Analysis Status: analyzed
Image Type: docker
Analyzed At: 2020-03-22T05:48:14Z
Image ID: bcf644d78ccd89f36f5cce91d205643a47c8a5277742c5b311c9d96699a3af82
Dockerfile Mode: Guessed
Distro: debian
Distro Version: 10
Size: 1172316160
Architecture: amd64
Layer Count: 16
Full Tag: docker.io/kaizheh/nginx-docker:latest
Tag Detected At: 2020-03-22T05:44:38Z

你將獲得映像檔的摘要、完整標籤等資訊。Anchore Engine 分析映像檔可能需要一些時間,具體取決於映像檔大小。分析完成後,你將看到 Analysis Status 欄位已更新為 analyzed。使用以下命令檢查映像檔掃描狀態:

root@anchore-cli:/# anchore-cli image get kaizheh/nginx-docker

輸出應該類別似如下:

Image Digest: sha256:416b695b09a79995b3f25501bf0c9b9620e82984132060bf7d66d8776c1554b7
Parent Digest: sha256:416b695b09a79995b3f25501bf0c9b9620e82984132060bf7d66d8776c1554b7
Analysis Status: analyzed
Image Type: docker
Analyzed At: 2020-03-22T05:48:14Z
Image ID: bcf644d78ccd89f36f5cce91d205643a47c8a5277742c5b311c9d96699a3af82
Dockerfile Mode: Guessed
Distro: debian
Distro Version: 10
Size: 1172316160
Architecture: amd64
Layer Count: 16
Full Tag: docker.io/kaizheh/nginx-docker:latest
Tag Detected At: 2020-03-22T05:44:38Z

內容解密:

此段落說明如何使用 anchore-cli 對映像檔進行掃描,並檢查掃描結果。首先,需要設定環境變數以啟用 CLI 對 Anchore Engine 的存取。然後,使用 anchore-cli system status 命令驗證連線。接著,使用 anchore-cli image add 命令新增映像檔進行掃描,並使用 anchore-cli image get 命令檢查掃描狀態。

Anchore Engine 政策評估

我們之前簡要提到了 Anchore Engine 政策;Anchore Engine 政策允許你定義規則,以根據漏洞的嚴重程度不同地處理它們。在預設的 Anchore Engine 政策中,你將找到兩個規則。第一個規則如下:

{
  "action": "WARN",
  "gate": "vulnerabilities",
  "id": "6063fdde-b1c5-46af-973a-915739451ac4",
  "params": [
    {
      "name": "package_type",
      "value": "all"
    },
    {
      "name": "severity_comparison",
      "value": "="
    },
    {
      "name": "severity",
      "value": "medium"
    }
  ],
  "trigger": "package"
}

第一個規則定義了任何具有中等嚴重程度漏洞的套件仍將設定政策評估結果為透過。第二個規則如下:

{
  "action": "STOP",
  "gate": "vulnerabilities",
  "id": "b30e8abc-444f-45b1-8a37-55be1b8c8bb5",
  "params": [
    {
      "name": "package_type",
      "value": "all"
    },
    {
      "name": "severity_comparison",
      "value": ">"
    },
    {
      "name": "severity",
      "value": "medium"
    }
  ],
  "trigger": "package"
}

第二個規則定義了任何具有高或嚴重漏洞的套件將設定政策評估結果為失敗。映像檔分析完成後,使用以下命令檢查政策評估結果:

root@anchore-cli:/# anchore-cli --json evaluate check sha256:416b695b09a79995b3f25501bf0c9b9620e82984132060bf7d66d8776c1554b7 --tag docker.io/kaizheh/nginx-docker:latest

輸出應該類別似如下:

[
  {
    "sha256:416b695b09a79995b3f25501bf0c9b9620e82984132060bf7d66d8776c1554b7": {
      "docker.io/kaizheh/nginx-docker:latest": [
        {
          "detail": {},
          "last_evaluation": "2020-03-22T06:19:44Z",
          "policyId": "2c53a13c-1765-11e8-82ef-23527761d060",
          "status": "fail"
        }
      ]
    }
  }
]

內容解密:

此段落說明瞭 Anchore Engine 的政策評估功能。預設政策包含兩個規則,分別處理中等嚴重程度以上的漏洞。第一個規則對中等嚴重程度的漏洞發出警告,而第二個規則對高或嚴重漏洞停止評估。可以使用 anchore-cli --json evaluate check 命令檢查政策評估結果。

將映像掃描整合至 DevOps 管道

在前面的章節中,我們討論瞭如何使用 Anchore Engine 掃描映像中的漏洞。現在,我們將介紹如何將映像掃描整合至 CI/CD 管道。

為何需要在 DevOps 管道中進行映像掃描?

映像掃描可以在 DevOps 管道的多個階段觸發。雖然在早期階段掃描映像有很多好處,但新的漏洞仍會不斷被發現,因此您的漏洞資料函式庫應該不斷更新。這意味著,如果在建置階段透過了映像掃描,但在執行階段發現了新的嚴重漏洞,則仍然可能存在風險。因此,當發生這種情況時,您應該停止工作負載佈署並採取相應的緩解策略。

DevOps 階段的定義

在討論整合之前,讓我們先看看適用於映像掃描的 DevOps 階段的粗略定義:

  • 建置:當在 CI/CD 管道中建置映像時
  • 佈署:當映像即將佈署到 Kubernetes 叢集時
  • 執行階段:當映像已佈署到 Kubernetes 叢集且容器正在執行時

在建置階段進行掃描

有多種 CI/CD 工具可供選擇,例如 Jenkins、Spinnaker 和 Screwdriver。在本文中,我們將展示如何將映像掃描整合到 GitHub 工作流程中。GitHub 工作流程是一種可組態的自動化流程,包含多個作業。它與 Jenkins 管道類別似,但定義為 YAML 格式。

一個簡單的工作流程,包括映像掃描,定義如下:

  1. 簽出 PR 分支。
  2. 從分支建置映像。
  3. 將映像推播到登入檔(此步驟可選)。
  4. 掃描新建置或推播的映像。
  5. 如果發生政策違規,則使工作流程失敗。

以下是一個在 GitHub 中定義的範例工作流程:

name: CI

build:
  runs-on: ubuntu-latest
  steps:
    # 簽出儲存函式庫
    - uses: actions/checkout@v2
    
    # 建置和推播映像
    - name: Build and Push
      env:
        DOCKER_SECRET: ${{ secrets.DOCKER_SECRET }}
      run: |
        cd master/chapter9 && echo "Build Docker Image"
        docker login -u kaizheh -p ${DOCKER_SECRET}
        docker build -t kaizheh/anchore-cli . && docker push kaizheh/anchore-cli
    
    # 掃描映像
    - name: Scan
      env:
        ANCHORE_CLI_URL: ${{ secrets.ANCHORE_CLI_URL }}
        ANCHORE_CLI_USER: ${{ secrets.ANCHORE_CLI_USER }}
        ANCHORE_CLI_PASS: ${{ secrets.ANCHORE_CLI_PASS }}
      run: |
        pip install anchorecli # 安裝 anchore-cli
        export PATH="$HOME/.local/bin/:$PATH"
        img="kaizheh/anchore-cli"
        anchore-cli image add $img # 新增映像
        sha=$(anchore-cli --json --api-version=0.2.4 image get $img | jq .[0].imageDigest -r) # 取得 sha 值
        anchore-cli image wait $img # 等待映像分析完成
        anchore-cli --json evaluate check $sha --tag $img # 評估映像
    
    # 傳送掃描結果通知
    - name: Post Scan
      run: |
        # 將掃描結果通知開發人員或邀請新的審查者(如果失敗)
        exit 1 # 特意在此結束

程式碼解析:

  1. 首先,使用 actions/checkout@v2 簽出儲存函式庫,以便存取程式碼。
  2. Build and Push 步驟中,登入 Docker Hub,建置並推播 kaizheh/anchore-cli 映像。
  3. Scan 步驟中,安裝 anchore-cli,新增映像,等待分析完成,並評估映像是否符合政策要求。
  4. 最後,在 Post Scan 步驟中,可以傳送掃描結果通知給開發人員或邀請新的審查者。

將映像掃描結果整合至 CI/CD 管道的好處

  • 及早發現映像中的漏洞和風險。
  • 自動化掃描和評估過程,提高效率和準確性。
  • 與 CI/CD 管道整合,實作持續的安全監控和風險管理。