使用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,使其在安全阶段运行
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已解决的已修复漏洞
- 与目标分支基线的对比
流水线优化
- 并行执行:安全扫描器在安全阶段并发运行
- 缓存:使用CI缓存加速依赖下载,提高扫描速度
- 增量扫描:使用
SAST_INCREMENTAL: "true"只扫描已更改的文件 - 故障条件:对关键扫描器设置
allow_failure: false,以强制执行质量门禁
监控与指标
| 指标 | 描述 | 目标 |
|---|---|---|
| 流水线安全覆盖率 | 启用所有扫描器的项目百分比 | > 95% |
| 关键漏洞平均修复时间(MTTR) | 从检测到解决关键发现的时间 | < 48小时 |
| 误报率 | 标记为误报的已忽略发现百分比 | < 15% |
| 密钥检测阻断率 | 被推送规则阻断的密钥提交百分比 | > 99% |