軟體供應鏈安全是 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_latest和deny_no_version。deny_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:元件的型別,如library或container。name和version:元件的名稱和版本。cpe和purl:元件的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流程的更緊密整合。
這些發展將有助於提高軟體供應鏈的安全性和可靠性,為開發者和安全團隊提供更強大的工具和框架,以應對未來的挑戰。