使用 GitLab CI 建立 DevSecOps 流水線 是做什麼的?
概述
GitLab 提供了一個整合的 DevSecOps 平台,將安全性測試直接嵌入 CI/CD 流水線中。透過 GitLab 內建的安全掃描器——SAST、DAST、容器掃描、相依性掃描、秘密偵測及授權合規掃描——團隊可以實現「左移安全」,在開發階段就捕捉漏洞,而非等到部署之後。GitLab Duo AI 能協助偵測 SAST 漏洞的誤報,幫助安全團隊專注於真正的問題。
使用時機
- 在您的環境中部署或設定使用 GitLab CI 建立 DevSecOps 流水線的功能時
- 建立符合合規要求的安全控制項時
- 為此領域建置或改善安全架構時
- 執行需要此實作的安全評估時
先決條件
- GitLab Ultimate 授權(完整安全掃描套件必備)
- 已設定的 GitLab Runner(共享或自管)
- 熟悉
.gitlab-ci.yml流水線配置 - Docker-in-Docker (DinD) 或 Kaniko 用於容器建置
- 已部署至測試環境的應用程式(用於 DAST 掃描)
核心安全掃描階段
靜態應用程式安全測試 (SAST)
SAST 在編譯前分析原始碼以找出弱點。GitLab 使用 Semgrep、SpotBugs、Gosec、Bandit 和 NodeJsScan 等分析器支援 14 種以上的語言。最簡單的方式是使用 GitLab 的託管範本。
動態應用程式安全測試 (DAST)
DAST 透過對 HTTP 端點模擬攻擊負載來測試正在執行的應用程式。它能偵測 XSS、SQLi、CSRF 以及其他靜態分析無法發現的執行時期弱點。DAST 需要一個已部署且可存取的目標 URL。
容器掃描
使用 Trivy 掃描 Docker 映像中作業系統套件與應用程式相依性的已知 CVE。在 Docker 建置階段之後執行,以便在映像到達登錄庫之前進行閘控。
相依性掃描
檢查相依性清單(package.json、requirements.txt、pom.xml、Gemfile.lock)中是否有已知的易受攻擊版本。在原始碼層級運作,與容器掃描互補。
秘密偵測
透過模式比對和熵分析,掃描提交中不小心提交的憑證、API 金鑰、權杖和私鑰。每次提交時都會執行,以防止秘密進入儲存庫。
實作
完整流水線配置
# .gitlab-ci.yml
stages:
- build
- test
- security
- deploy-staging
- dast
- deploy-production
variables:
DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
SECURE_LOG_LEVEL: "info"
# 引入 GitLab 託管的安全範本
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/Container-Scanning.gitlab-ci.yml
- template: DAST.gitlab-ci.yml
- template: Security/License-Scanning.gitlab-ci.yml
build:
stage: build
image: docker:24.0
services:
- docker:24.0-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $DOCKER_IMAGE .
- docker push $DOCKER_IMAGE
rules:
- if: $CI_COMMIT_BRANCH
unit-tests:
stage: test
image: $DOCKER_IMAGE
script:
- npm ci
- npm run test:coverage
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
artifacts:
reports:
junit: junit-report.xml
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
# 覆寫 SAST 使其在 security 階段執行
sast:
stage: security
variables:
SAST_EXCLUDED_PATHS: "spec,test,tests,tmp,node_modules"
SEARCH_MAX_DEPTH: 10
# 覆寫容器掃描
container_scanning:
stage: security
variables:
CS_IMAGE: $DOCKER_IMAGE
CS_SEVERITY_THRESHOLD: "HIGH"
# 覆寫相依性掃描
dependency_scanning:
stage: security
# 覆寫秘密偵測
secret_detection:
stage: security
# 授權合規掃描
license_scanning:
stage: security
deploy-staging:
stage: deploy-staging
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE -n staging
- kubectl rollout status deployment/app -n staging --timeout=300s
environment:
name: staging
url: https://staging.example.com
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
# DAST 針對已部署的測試環境執行
dast:
stage: dast
variables:
DAST_WEBSITE: https://staging.example.com
DAST_FULL_SCAN_ENABLED: "true"
DAST_BROWSER_SCAN: "true"
needs:
- deploy-staging
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
deploy-production:
stage: deploy-production
image: bitnami/kubectl:latest
script:
- kubectl set image deployment/app app=$DOCKER_IMAGE -n production
- kubectl rollout status deployment/app -n production --timeout=300s
environment:
name: production
url: https://app.example.com
when: manual
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
安全審批政策
設定掃描執行政策以強制執行必要的安全掃描:
- 導覽至 安全與合規 > 政策
- 建立一個「掃描執行政策」,要求所有分支都執行 SAST 和秘密偵測
- 建立一個「合併請求審批政策」,當偵測到重大弱點時要求安全團隊核准
自訂 SAST 規則集配置
建立 .gitlab/sast-ruleset.toml 來自訂分析器行為:
[semgrep]
[[semgrep.ruleset]]
dirs = ["src"]
[[semgrep.passthrough]]
type = "url"
target = "/sgrep-rules/custom-rules.yml"
value = "https://semgrep.dev/p/owasp-top-ten"
[[semgrep.passthrough]]
type = "url"
target = "/sgrep-rules/java-rules.yml"
value = "https://semgrep.dev/p/java"
安全儀表板與弱點管理
弱點報告
GitLab 將所有掃描器的發現結果整合到一個統一的弱點報告中,您可以在 安全與合規 > 弱點報告 存取。每個弱點包含:
- 嚴重性評級(重大、高、中、低、資訊)
- 掃描器來源(SAST、DAST、容器、相依性、秘密)
- 原始碼或映像層中的位置
- 修復指引與建議修正
- 狀態追蹤(已偵測、已確認、已關閉、已解決)
合併請求安全小工具
每個合併請求都會顯示一個安全掃描小工具,展示:
- 此 MR 引入的新弱點
- 此 MR 已修復的弱點
- 與目標分支基線的比較
流水線最佳化
- 並行執行:安全掃描器在 security 階段並行運作
- 快取:使用 CI 快取來加速相依性下載,從而加快掃描速度
- 增量掃描:SAST 可以使用
SAST_INCREMENTAL: "true"僅掃描已變更的檔案 - 失敗條件:在關鍵掃描器上設定
allow_failure: false以強制執行品質閘控
監控與指標
| 指標 | 描述 | 目標 |
|---|---|---|
| 流水線安全覆蓋率 | 已啟用所有掃描器的專案百分比 | > 95% |
| 重大弱點平均修復時間 | 從偵測到解決重大發現的平均時間 | < 48 小時 |
| 誤報率 | 被歸為誤報而關閉的發現百分比 | < 15% |
| 秘密偵測攔截率 | 被推送規則攔截的秘密提交百分比 | > 99% |