iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Kubernetes

從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台系列 第 21

[Day 21] 供應鏈安全:鏡像掃描 (Image Scanning) 與漏洞管理 —— 在 Image 進入叢集前,先抓出潛在的安全漏洞。

  • 分享至 

  • xImage
  •  

Day 21: 供應鏈安全:鏡像掃描 (Image Scanning) 與漏洞管理

在 Image 進入叢集前,先抓出潛在的安全漏洞。

1. 什麼是供應鏈安全

Dockerfile 寫下 FROM python:3.10-slim,或在 pom.xml / package.json 加入第三方套件時,等於把別人寫的、你沒審查過的程式碼一起打包進了 image。這些依賴(以及它們的依賴的依賴)裡任何一個出現已知漏洞(CVE),你的服務就跟著曝險——即使你自己的程式碼完全沒問題。

供應鏈安全要處理兩個層面:套件層(原始碼依賴,例如 Maven/npm/pip 套件)與 image 層(作業系統套件、基礎映像的既有漏洞)。Wafer BI 分兩條線處理:Dependabot 顧套件層,Trivy 顧 image 層。

2. GitHub Dependabot

Dependabot 定期掃描 repo 裡各服務的依賴檔案,發現有 CVE 的版本就自動開 PR 升級。設定檔 .github/dependabot.yml

version: 2
updates:
  - package-ecosystem: "maven"
    directories: ["/services/user-service", "/services/license-service"]
    schedule: { interval: "weekly" }
  - package-ecosystem: "pip"
    directories: ["/services/wafer-bi", "/services/ai-mcp-service"]
    schedule: { interval: "weekly" }
  - package-ecosystem: "npm"
    directories: ["/services/api-gateway", "/services/frontend"]
    schedule: { interval: "weekly" }
  - package-ecosystem: "docker"
    directories: ["/services/*"]
    schedule: { interval: "weekly" }
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule: { interval: "weekly" }

每個服務用的套件管理工具不同(Maven、pip、npm),Dependabot 用 package-ecosystem 分別對應,docker 這條額外掃 Dockerfile 裡 FROM 指定的基礎映像版本。

3. 容器鏡像掃描:Trivy 實測

Dependabot 抓的是「原始碼依賴」,但最終跑起來的是「image」——裡面還包含作業系統套件、已編譯進 jar 的間接依賴。這層要靠 Trivy 掃。直接對已建置的 image 掃描:

trivy image --severity CRITICAL --exit-code 1 wafer-user-service:ironman

實際掃描結果:

https://ithelp.ithome.com.tw/upload/images/20260823/201825495mHghUq7JC.png

▲ Trivy 掃描發現真實 CRITICAL 漏洞、修復兩輪後清零

第一次掃描找到 4 個 CRITICAL,其中 CVE-2025-24813 是 Apache Tomcat 的 partial PUT 請求漏洞,可能導致遠端程式碼執行或資訊洩漏——這不是憑空編造的示範漏洞,是這個專案的 user-service 當時實際在用的 Spring Boot 3.3.0 內建的 Tomcat 10.1.24 真的中鏢。

4. 修復過程:兩輪嘗試

第一輪:把 spring-boot-starter-parent 從 3.3.0 升到 3.3.13。重新掃描,CVE-2025-24813 消失了,但還剩 3 個 CRITICAL——因為 3.3.13 內建的 Tomcat 是 10.1.42,仍然比後續公告的幾個 CVE 舊。

第二輪:不完全依賴 Spring Boot 的 BOM 版本管理,直接在 pom.xml 覆寫 Tomcat 版本:

<properties>
  <java.version>21</java.version>
  <jjwt.version>0.12.5</jjwt.version>
  <tomcat.version>10.1.55</tomcat.version>
</properties>

重新 build、重新掃描:

$ trivy image --severity CRITICAL --exit-code 1 wafer-user-service:patched-v2
...
app/app.jar   jar   0
$ echo $?
0

CRITICAL 清零,exit code 0。這個過程說明一件事:升級框架版本不等於自動拿到最新的所有子依賴——框架的 BOM(Bill of Materials)本身也有更新節奏,關鍵依賴的版本落後時,需要手動覆寫。

5. 接入 CI

.github/workflows/deploy.yml 的 build 流程之後加入掃描步驟:

- name: Scan image with Trivy
  uses: aquasecurity/trivy-action@0.28.0
  with:
    image-ref: ghcr.io/${{ needs.setup.outputs.owner_lc }}/${{ matrix.service }}:${{ github.sha }}
    format: table
    severity: CRITICAL
    exit-code: '1'

exit-code: '1' 是關鍵:只要掃到 CRITICAL 等級的漏洞,這個 job 就會失敗,阻止 image 進入後面的 deploy-trigger 步驟。掃描的嚴重度門檻可以依團隊風險承受度調整(例如 staging 環境可以放寬到只擋 CRITICAL,production 前的最終關卡收緊到 HIGH 以上)。

6. 小結

Dependabot 與 Trivy 分別覆蓋了「原始碼依賴」與「image 內容」兩層,兩者互補而非重複——Dependabot 能主動開 PR 升級版本,Trivy 則是最後一道守門,確保就算 PR 沒被及時合併,有 CRITICAL 漏洞的 image 也不會流入叢集。


上一篇
[Day 20] 部署策略:滾動更新、回滾與金絲雀發布 —— 從 Deployment 內建的滾動更新,到 Argo Rollouts 的金絲雀,以及出事時到底該怎麼退回去。
系列文
從零到一:使用 K8S + GitOps 打造異構技術棧的資料分析平台21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言