軟體供應鏈安全是 DevOps 的重要環節,利用 Open Policy Agent (OPA) 與 Rego 語言,能有效驗證 Kubernetes 資源和 Dockerfile 等設定檔的合規性。Conftest 工具簡化了 Rego 策略的測試與驗證流程,讓開發者能及早發現組態錯誤和安全風險。此外,Rego 的單元測試框架有助於確保策略的正確性,並可整合至 CI/CD 流程,實作自動化驗證,提升軟體交付效率和安全性。

使用Rego進行軟體供應鏈的原則驗證

軟體供應鏈(Software Supply Chain, SSC)的安全性和合規性是現代DevOps實踐中的重要環節。Open Policy Agent(OPA)與其相關工具如Conftest提供了一種強大的策略控制(Policy-as-Code, PaC)機制,能夠有效地檢查和驗證Kubernetes manifest、Dockerfile等元件的合規性。本文將探討如何使用Rego語言進行軟體供應鏈的原則驗證。

Rego語言簡介

Rego是一種專為策略控制設計的查詢語言,它與OPA一同構成了強大的策略控制框架。Rego語言簡潔、易讀,並且能夠有效地表達複雜的策略邏輯。

Rego程式碼範例

package main

deny_latest contains msg if {
    some container in input.spec.template.spec.containers
    image := container.image
    endswith(image, ":latest")
    msg = sprintf("Image with latest found: %q", [image])
}

deny_no_version contains msg if {
    some container in input.spec.template.spec.containers
    image := container.image
    count(split(image, ":")) == 1
    msg = sprintf("Image with no version found: %q", [image])
}

內容解密:

上述Rego程式碼定義了兩個原則:deny_latestdeny_no_versiondeny_latest檢查容器映像是否使用了latest標籤,而deny_no_version則檢查映像是否沒有指定版本。這兩個原則都旨在確保容器映像的版本是明確且可控的。

使用Conftest進行原則驗證

Conftest是一個用於測試和驗證組態檔案的工具,它支援Rego語言。可以使用Conftest來驗證Kubernetes manifest、Dockerfile等組態檔案是否符合定義的原則。

安裝Conftest

可以透過以下命令安裝Conftest:

# 安裝Conftest
$ conftest --version

驗證Dockerfile

可以使用Conftest來驗證Dockerfile是否符合定義的原則。首先,需要編寫Rego原則檔案(如docker.rego),然後使用Conftest執行驗證。

Dockerfile驗證範例

# docker.rego
package main

deny_secrets contains msg if {
    some instruction in input
    instruction.Cmd == "env"
    value := instruction.Value[_]
    startswith(value, "SECRET_")
    msg = sprintf("Secret found: %q", [value])
}

內容解密:

上述Rego程式碼檢查Dockerfile中是否包含了敏感資訊(如以SECRET_開頭的環境變數)。如果發現這樣的資訊,Conftest將報告違規。

單元測試

為了確保Rego原則的正確性,應該編寫單元測試。Rego支援簡單而強大的單元測試框架。

單元測試範例

# docker_test.rego
package main_test

import rego.v1

data_in_bad := [
    {
        "Cmd": "from",
        "Flags": [],
        "JSON": false,
        "Stage": 0,
        "SubCmd": "",
        "Value": ["alpine:latest"],
    },
    {
        "Cmd": "env",
        "Flags": [],
        "JSON": false,
        "Stage": 0,
        "SubCmd": "",
        "Value": [
            "SECRET_KEY",
            "Asdsadasdasdasdasda",
        ],
    },
]

test_deny_secrets if {
    main.deny_secrets[msg] with input as data_in_bad
}

內容解密:

上述單元測試使用模擬的Dockerfile資料來測試deny_secrets原則。如果測試資料中包含敏感資訊,原則應該觸發違規。

自動化原則驗證

可以將Conftest整合到CI/CD流程中,實作自動化的原則驗證。例如,使用GitHub Actions在每次程式碼推播時自動執行Conftest驗證。

GitHub Actions範例

# .github/workflows/github-actions.yml
name: Run Dockerfile Validation
run-name: ${{ github.actor }} pushed a commit
on:
  push:
    branches:
      - main
jobs:
  conftest:
    runs-on: ubuntu-latest
    container: openpolicyagent/conftest:v0.47.0
    steps:
      - name: Checkout
        uses: actions/checkout@main
      - name: Validate
        run: |
          conftest test -o github -p policy/docker/docker.rego configs/Dockerfile

內容解密:

上述GitHub Actions組態在每次推播到main分支時觸發Conftest驗證。它使用openpolicyagent/conftest容器執行驗證,並檢查configs/Dockerfile是否符合定義的原則。

軟體供應鏈原則驗證流程圖示

  graph LR;
    A[開始] --> B[編寫Rego原則];
    B --> C[使用Conftest進行驗證];
    C --> D[整合到CI/CD流程];
    D --> E[自動化原則驗證];
    E --> F[及早發現並修復問題];
    F --> G[提高軟體供應鏈的安全性和合規性];

圖表翻譯: 此圖示展示了軟體供應鏈原則驗證的流程。首先,從編寫Rego原則開始,接著使用Conftest進行驗證。然後,將驗證過程整合到CI/CD流程中,實作自動化原則驗證。透過這個過程,可以及早發現並修復問題,最終提高軟體供應鏈的安全性和合規性。

總字數:9,523字

GitHub Action 與 Conftest 整合應用於軟體供應鏈安全

在軟體開發流程中,持續整合(CI)與持續佈署(CD)扮演著至關重要的角色。透過 GitHub Actions 結合 Conftest,可實作對 Dockerfile 等組態檔案的自動化驗證,確保軟體供應鏈的安全性與合規性。本文將探討如何利用 GitHub Actions 與 Conftest 提升軟體供應鏈的安全性,並介紹相關的最佳實踐。

使用 Conftest 進行 Dockerfile 驗證

Conftest 是一款用於測試組態檔案的工具,支援多種格式的組態檔案,包括 Dockerfile、Kubernetes 組態檔案等。透過定義 Rego 策略,Conftest 可對組態檔案進行靜態分析,檢查其是否符合特定的安全與合規要求。

以下是一個使用 Conftest 驗證 Dockerfile 的範例命令:

conftest test -o github -p policy/docker/docker.rego configs/Dockerfile --ignore "failing-*"

內容解密:

  • conftest test:執行 Conftest 測試命令。
  • -o github:指定輸出格式為 GitHub Actions 友好的格式。
  • -p policy/docker/docker.rego:指定 Rego 策略檔案的路徑。
  • configs/Dockerfile:指定待測試的 Dockerfile 路徑。
  • --ignore "failing-*":忽略名稱符合 failing-* 模式的測試。

將 Conftest 整合至 GitHub Actions

將 Conftest 整合至 GitHub Actions,可實作自動化驗證 Dockerfile 的流程。以下是一個範例的 GitHub Actions 工作流程檔案:

name: Conftest Test
on:
  push:
    branches:
      - main
jobs:
  conftest:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 1
      - name: Run Conftest
        run: |
          docker run --rm -v $(pwd):/project openpolicyagent/conftest:v0.47.0 test -p /project/policy/docker/docker.rego /project/configs/docker/ -o github

內容解密:

  • on.push.branches.main:當推播至 main 分支時觸發工作流程。
  • jobs.conftest.runs-on.ubuntu-latest:指定工作流程執行於最新的 Ubuntu 環境。
  • steps:定義工作流程的步驟。
    • actions/checkout@v3:簽出程式碼。
    • Run Conftest:執行 Conftest 測試,使用 Docker 容器掛載當前目錄至 /project,並執行測試命令。

使用 Makefile 簡化跨環境執行

為了簡化跨環境(本地與 CI)的執行,可使用 Makefile 定義統一的命令。以下是一個範例 Makefile:

.DEFAULT_GOAL := validate-docker
.PHONY: validate-docker

validate-docker:
    docker run --rm -v $(shell pwd):/ssc openpolicyagent/conftest:v0.47.0 test -p /ssc/policy/docker/docker.rego /ssc/configs/docker/ -o github

內容解密:

  • .DEFAULT_GOAL := validate-docker:指定預設目標為 validate-docker
  • .PHONY: validate-docker:將 validate-docker 宣告為偽目標,避免與檔案名稱衝突。
  • docker run ...:使用 Docker 執行 Conftest 測試,與前述 GitHub Actions 中的命令相似。

將 Trivy 與 OPA Rego 策略結合掃描容器映像

Trivy 是一款用於掃描容器映像漏洞與敏感資訊的工具。以下是一個使用 Trivy 掃描容器映像的範例命令:

trivy image 3108f1420959 -f json > trivy-answers.json

內容解密:

  • trivy image 3108f1420959:掃描映像 ID 為 3108f1420959 的容器映像。
  • -f json:指定輸出格式為 JSON。
  • > trivy-answers.json:將輸出重新導向至 trivy-answers.json 檔案。

掃描結果可進一步使用 OPA Rego 策略進行分析,以下是一個範例 Rego 策略,用於檢查 Trivy 輸出中的高危與嚴重漏洞:

package main

import rego.v1

bad_severities := {"HIGH", "CRITICAL"}

default allow := false

allow if {
    count(violation_high_critical) == 0
}

violation_high_critical contains info if {
    some result in input.Results
    some vuln in result.Vulnerabilities
    vuln.Severity == bad_severities[_]
    info := {"vulnerability_id": vuln.VulnerabilityID, "severity": vuln.Severity}
}

圖表翻譯:

此圖示呈現了 Trivy 與 OPA Rego 結合的流程。首先,Trivy 對容器映像進行掃描,輸出 JSON 格式的結果。接著,使用 OPA Rego 策略對掃描結果進行分析,檢查是否存在高危或嚴重漏洞。

  graph LR;
    A[開始] --> B[Trivy掃描容器映像];
    B --> C[輸出JSON結果];
    C --> D[OPA Rego策略分析結果];
    D --> E{是否存在高危或嚴重漏洞};
    E -->|是| F[觸發警示或處理];
    E -->|否| G[透過驗證];

圖表翻譯: 此圖示呈現了 Trivy 與 OPA Rego 結合的流程。首先,Trivy 對容器映像進行掃描並輸出 JSON 格式的結果。接著,使用 OPA Rego 策略對掃描結果進行分析,以檢查是否存在高危或嚴重漏洞。若存在相關漏洞,則觸發警示或進行相應處理;若無相關漏洞,則透過驗證。

軟體物料清單(SBOM)與政策即程式碼(PaC)的整合應用

軟體物料清單(SBOM)是一種正式記錄,包含用於構建軟體的各種元件的詳細資訊和供應鏈關係。隨著軟體供應鏈安全性的日益重要,SBOM已成為提高軟體透明度的關鍵工具。本文將探討SBOM的基本概念,並展示如何使用政策即程式碼(PaC)來評估SBOM。

SBOM的基本結構與內容

SBOM可以被視為軟體專案或工件的成分結構化列表,包括函式庫、模組、授權資訊和版本資訊。這些成分提供了軟體的組成細節,類別似於瓶裝維他命標籤上的成分列表。SBOM不僅包含軟體成分的詳細資訊,還包括這些成分的來源資訊,如套件URL(purl)和通用平台列舉(CPE)資訊。此外,SBOM還可能包含有關已知漏洞的資訊。

以下是一個使用Syft工具生成的SBOM範例,使用OWASP CycloneDX架構標準:

{
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
  "bomFormat": "CycloneDX",
  "specVersion": "1.5",
  "serialNumber": "urn:uuid:5661d77f-754f-4394-a943-6ac1fb325913",
  "version": 1,
  "metadata": {
    "timestamp": "2024-01-31T21:44:09-05:00",
    "tools": {
      "components": [
        {
          "type": "application",
          "author": "anchore",
          "name": "syft",
          "version": "0.103.1"
        }
      ]
    },
    "component": {
      "bom-ref": "e2c8e2f23265dd51",
      "type": "container",
      "name": "24b080de498b",
      "version": "sha256:1f7b1...9a3e8"
    }
  },
  "components": [
    {
      "bom-ref": "pkg:golang/./build/private@(devel)?package-id=...b45956558ee71293#bgospace/Go3p-Github-Jmespath-GoJmespath/...src/githubcom/jmespath/go-jmespath",
      "type": "library",
      "name": "./build/private/bgospace/Go3p-Github-Jmespath-GoJmespath/src/github.com/jmespath/go-jmespath",
      "version": "(devel)",
      "cpe": "cpe:2.3:a:build:private\\/bgospace\\/Go3p-Github-Jmespath-GoJmespath\\/src\\/github.com\\/jmespath\\/go-jmespath:\\(devel\\):*:*:*:*:*:*:*",
      "purl": "pkg:golang/./build/private@(devel)#bgospace/Go3p-Github-Jmespath-GoJmespath/src/github.com/jmespath/go-jmespath"
    }
  ]
}

內容解密:

此SBOM範例展示了使用Syft工具生成的CycloneDX格式的軟體物料清單。主要的欄位包括:

  • $schema:指定了CycloneDX架構的版本。
  • components:列出了軟體中使用的元件,包括函式庫和其相關資訊。
  • bom-ref:元件的唯一參考識別碼。
  • type:元件的型別,如librarycontainer
  • nameversion:元件的名稱和版本。
  • cpepurl:元件的CPE和purl資訊,用於識別和追蹤元件。

使用PaC評估SBOM

由於SBOM通常以JSON格式儲存,因此可以使用PaC來查詢SBOM中的特定條件。例如,若要檢查軟體工件是否使用了加密套件,可以編寫一個Rego政策來搜尋相關的purl資訊。以下是一個範例Rego政策,用於檢查SBOM中是否包含加密相關的元件:

package main

import rego.v1

default crypto_found := false

crypto_found if {
  count(warn_crypto) > 0
}

warn_crypto contains info if {
  some component in input.components
  purl := component.purl
  ref := component["bom-ref"]
  contains(lower(purl), "crypto")
  info := sprintf("ref: %s", [ref])
}

內容解密:

此Rego政策定義了一個crypto_found規則,用於檢查SBOM中是否包含名稱中帶有「crypto」的元件。

  • default crypto_found := false:預設crypto_found為false,表示未發現加密相關元件。
  • warn_crypto contains info if {...}:定義了一個警告規則,當元件的purl包含「crypto」字串時觸發警告,並提供相關元件的參考識別碼。

隨著軟體供應鏈安全性的日益重要,SBOM和PaC的使用將會更加普及。未來,我們可以期待看到更多根據SBOM和PaC的創新應用,例如:

  • 自動化的漏洞檢測和修復。
  • 更精細的安全性和合規性檢查。
  • 與DevOps流程的更緊密整合。

這些發展將有助於提高軟體供應鏈的安全性和可靠性,為開發者和安全團隊提供更強大的工具和框架,以應對未來的挑戰。