前陣子線上環境爆發了一個開源組件漏洞,緊急急忙忙忙慌地升級版本時,我才意識到之前的安全檢測環節有多薄弱。Docker鏡像裏藏着的基礎鏡像漏洞、依賴包風險,就像定時炸彈,必須在CI/CD流程里加上掃描環節。試了幾款工具後,發現Trivy特別適合DevOps場景——輕量、快速,還能無縫集成到流水線裏。
為什麼選Trivy?
剛開始用的是Clair,雖然功能全,但掃描速度太慢,一個普通鏡像要等好幾分鐘,團隊抱怨影響開發效率。換成Trivy後明顯不一樣:它本地就有漏洞數據庫,掃描一個Nginx鏡像只要十幾秒;支持的漏洞類型還特別全,從操作系統層面的CVE到應用依賴的安全問題(比如npm包漏洞)都能檢測;最重要的是,它的輸出格式靈活,JSON、表格都能出,方便後續處理。
基礎使用:先手動掃起來
先在本地裝個Trivy試試水,用Docker運行最方便:
# 掃描官方Nginx鏡像
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image nginx:latest
掃描結果會按嚴重程度分級(CRITICAL、HIGH、MEDIUM、LOW),比如能看到Nginx鏡像裏的libssl庫有沒有心臟出血漏洞,glibc有沒有已知風險。我第一次掃公司的業務鏡像時,發現基礎鏡像用的還是兩年前的Ubuntu版本,光CRITICAL級漏洞就有17個,嚇出一身冷汗。
如果只想看高危以上的漏洞,可以加參數過濾:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image --severity HIGH,CRITICAL myapp:v1.0
集成到CI流水線:在構建時堵漏洞
手動掃描不靠譜,必須嵌到CI流程裏。以GitLab CI為例,在.gitlab-ci.yml里加個掃描階段:
stages:
- build
- scan
- deploy
build_image:
stage: build
script:
- docker build -t myapp:$CI_COMMIT_SHORT_SHA .
- docker save myapp:$CI_COMMIT_SHORT_SHA -o myapp.tar
trivy_scan:
stage: scan
image: aquasec/trivy
script:
- trivy image --input myapp.tar --severity HIGH,CRITICAL --exit-code 1
artifacts:
reports:
dependency_scanning: trivy-results.json
這裏有個小技巧:用--exit-code 1參數,一旦檢測到高危漏洞,流水線就會失敗,直接阻止有風險的鏡像進入部署階段。上週開發提交了一個包含Log4j漏洞的鏡像,就是被這個規則攔下來的,避免了線上風險。
進階配置:忽略已知可接受風險
有些漏洞暫時沒法修復(比如需要等上游基礎鏡像更新),可以建個.trivyignore文件排除:
# 忽略低危漏洞
CVE-2023-12345:LOW
# 忽略特定鏡像的某個漏洞
CVE-2022-5678:myapp:v1.0
還可以生成HTML報告,方便分享給安全團隊:
trivy image --format template --template "@/contrib/html.tpl" -o report.html myapp:latest
實際使用中的坑
剛開始集成時,遇到過掃描時間忽長忽短的問題,後來發現是Trivy每次啓動都會更新漏洞庫。解決辦法是在CI節點上持久化存儲漏洞庫目錄,或者用定時任務提前更新,避免每次掃描都花時間在同步數據上。
另外要注意,掃描私有鏡像時,需要讓Trivy能訪問私有倉庫。在GitLab CI裏可以通過設置DOCKER_AUTH_CONFIG變量,把倉庫認證信息傳進去。
總結
把Trivy加到DevOps流程後,團隊的安全意識明顯提高了。現在每次代碼提交都會自動過一遍鏡像掃描,開發們也養成了定期更新基礎鏡像的習慣。其實安全防護不用搞得太複雜,像這樣在關鍵節點加一道輕量掃描,就能攔下大部分已知漏洞。畢竟,比起出了問題再補救,在構建階段解決風險的成本可要低多了。