镜像扫描:容器漏洞管理
镜像扫描:容器漏洞管理
什么是镜像扫描
镜像扫描是分析容器镜像中已知漏洞的过程。通过扫描镜像中的软件包和依赖项,识别CVE漏洞和配置问题,帮助团队在部署前修复安全问题。
扫描工具
Trivy
# 安装Trivy
sudo apt-get install trivy
# 扫描镜像
trivy image nginx:latest
# 只显示高危和严重漏洞
trivy image --severity HIGH,CRITICAL nginx:latest
# 输出JSON格式
trivy image -f json -o results.json nginx:latest
# 扫描本地Docker镜像
docker build -t myapp .
trivy image myapp:latest
# 忽略未修复的漏洞
trivy image --ignore-unfixed nginx:latest
Snyk
# 安装Snyk
npm install -g snyk
# 认证
snyk auth
# 扫描镜像
snyk container test nginx:latest
# 监控持续扫描
snyk container monitor nginx:latest --file=Dockerfile
# 修复漏洞
snyk container fix nginx:latest
Grype
# 安装Grype
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s
# 扫描镜像
grype nginx:latest
# 只显示高危漏洞
grype nginx:latest --fail-on high
# 输出JSON格式
grype nginx:latest -o json > results.json
CI/CD集成
GitHub Actions
# .github/workflows/image-scan.yml
name: Container Image Scan
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
ignore-unfixed: true
- name: Upload scan results
uses: actions/upload-artifact@v3
if: always()
with:
name: scan-results
path: trivy-results.sarif
GitLab CI
# .gitlab-ci.yml
image-scan:
stage: test
image: docker:latest
services:
- docker:dind
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image --exit-code 1 --severity HIGH,CRITICAL $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
allow_failure: false
Jenkins Pipeline
// Jenkinsfile
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'docker build -t myapp:${BUILD_NUMBER} .'
}
}
stage('Security Scan') {
steps {
sh 'trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:${BUILD_NUMBER}'
}
}
stage('Push') {
when {
expression { currentBuild.resultIsBetterOrEqualTo('SUCCESS') }
}
steps {
sh 'docker push registry.example.com/myapp:${BUILD_NUMBER}'
}
}
}
post {
always {
archiveArtifacts artifacts: 'trivy-results.json'
}
}
}
扫描策略
配置策略
# scan-policy.yaml
scan_policy:
triggers:
- on_push: true
- on_pr: true
- scheduled: "0 2 * * *" # 每天凌晨2点
severity_levels:
- CRITICAL
- HIGH
ignore_unfixed: true
timeout: "30m"
exclusions:
- cve: "CVE-2021-12345"
reason: "已评估为误报"
expires: "2024-12-31"
- package: "libssl1.1"
reason: "内部补丁已应用"
基础镜像管理
# base-images.yaml
base_images:
- name: "alpine"
version: "3.18"
scan_frequency: "weekly"
auto_update: true
- name: "python"
version: "3.11-slim"
scan_frequency: "weekly"
auto_update: false
- name: "node"
version: "20-alpine"
scan_frequency: "weekly"
auto_update: true
漏洞管理
漏洞分类
# vulnerability-classification.yaml
severity:
CRITICAL:
description: "严重漏洞"
cvss_range: "9.0-10.0"
response_time: "24小时"
action: "立即修复"
HIGH:
description: "高危漏洞"
cvss_range: "7.0-8.9"
response_time: "7天"
action: "尽快修复"
MEDIUM:
description: "中危漏洞"
cvss_range: "4.0-6.9"
response_time: "30天"
action: "计划修复"
LOW:
description: "低危漏洞"
cvss_range: "0.1-3.9"
response_time: "90天"
action: "评估后决定"
修复流程
#!/bin/bash
# fix-vulnerabilities.sh
IMAGE=$1
SEVERITY=$2
# 扫描并获取漏洞列表
echo "扫描镜像: $IMAGE"
VULNS=$(trivy image -f json $IMAGE | jq -r '.Results[].Vulnerabilities[] | select(.Severity == "'$SEVERITY'") | .VulnerabilityID')
# 逐个修复
for vuln in $VULNS; do
echo "修复漏洞: $vuln"
# 检查是否有可用修复
FIX_AVAILABLE=$(trivy image -f json $IMAGE | jq -r '.Results[].Vulnerabilities[] | select(.VulnerabilityID == "'$vuln'") | .FixedVersion')
if [ -n "$FIX_AVAILABLE" ]; then
echo "有可用修复: $FIX_AVAILABLE"
# 更新包版本
# docker run --rm -it $IMAGE apk upgrade --available
else
echo "暂无可用修复,添加到忽略列表"
fi
done
监控和报告
Prometheus监控
# prometheus-rules.yaml
groups:
- name: image-scan-alerts
rules:
- alert: CriticalVulnerabilityFound
expr: trivy_vulnerabilities{severity="CRITICAL"} > 0
for: 5m
labels:
severity: critical
annotations:
summary: "发现严重漏洞"
description: "镜像 {{ $labels.image }} 发现 {{ $value }} 个严重漏洞"
- alert: HighVulnerabilityCount
expr: trivy_vulnerabilities{severity="HIGH"} > 10
for: 1h
labels:
severity: warning
annotations:
summary: "高危漏洞数量过多"
description: "镜像 {{ $labels.image }} 有 {{ $value }} 个高危漏洞"
生成报告
#!/bin/bash
# generate-report.sh
REPORT_DIR="/reports/$(date +%Y%m%d)"
mkdir -p $REPORT_DIR
# 扫描所有生产镜像
for image in $(kubectl get pods -n production -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u); do
echo "扫描: $image"
trivy image -f json -o "$REPORT_DIR/$(echo $image | tr '/:' '_').json" $image
done
# 生成汇总报告
echo "生成汇总报告..."
trivy image --format table $(kubectl get pods -n production -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u) > "$REPORT_DIR/summary.txt"
最佳实践
- 早期扫描: 在CI/CD流水线早期阶段进行扫描
- 定期扫描: 定期重新扫描已部署的镜像
- 策略执行: 设置扫描失败阻止部署
- 漏洞跟踪: 建立漏洞跟踪和修复流程
- 基础镜像更新: 定期更新基础镜像
- 最小化镜像: 使用最小化基础镜像减少攻击面