|
|
你的 Docker 镜像里,可能正藏着 147 个已知漏洞——而你对此一无所知。
这不是危言耸听。2023 年 Sysdig 的云安全报告显示,87% 的容器镜像中包含高危或严重漏洞。更扎心的是,其中大部分漏洞早已有补丁可用,只是没人扫描、没人修复。
好消息是,解决这个问题的工具门槛极低。今天我们聊的 Trivy,就是那个"装上就能用、扫完就明白"的镜像安全扫描利器。
为什么是 Trivy
容器安全扫描工具不少——Clair、Anchore、Snyk,各有各的地盘。但 Trivy 能从中杀出来,靠的是三个字:够简单。
一个二进制文件,零配置,直接扫。不需要部署数据库,不需要启动守护进程,不需要写一堆 YAML。对于大多数团队来说,安全工具最大的敌人不是黑客,是"太麻烦所以没人用"。
Trivy 由 Aqua Security 开源维护,支持扫描容器镜像、文件系统、Git 仓库和 Kubernetes 集群。它的漏洞数据库覆盖 NVD(National Vulnerability Database)、Red Hat、Ubuntu、Alpine 等多个上游源,更新频率以小时计。
安装与基础用法
安装
macOS 和 Linux 环境下,一行命令搞定:
- # macOS
- brew install trivy
- # Linux (Debian/Ubuntu)
- sudo apt-get install -y trivy
- # 通用方式:直接拉取官方脚本
- curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
复制代码
验证安装:
第一次扫描
选一个你正在用的镜像,直接扫:
Trivy 会自动下载漏洞数据库(首次运行约需 30 秒),然后逐层分析镜像中的操作系统包和应用依赖。
扫描结果会直接打印在终端,类似这样:
- nginx:1.24 (debian 12.4)
- Total: 83 (UNKNOWN: 0, LOW: 52, MEDIUM: 21, HIGH: 8, CRITICAL: 2)
- ┌──────────────┬────────────────┬──────────┬───────────────┬──────────────────────┐
- │ Library │ Vulnerability │ Severity │ Installed │ Fixed Version │
- ├──────────────┼────────────────┼──────────┼───────────────┼──────────────────────┤
- │ libssl3 │ CVE-2024-XXXX │ CRITICAL │ 3.0.11-1 │ 3.0.13-1~deb12u1 │
- │ curl │ CVE-2024-YYYY │ HIGH │ 7.88.1-10 │ 7.88.1-10+deb12u5 │
- └──────────────┴────────────────┴──────────┴───────────────┴──────────────────────┘
复制代码
这张表就是你镜像的"体检报告"。
读懂扫描报告
报告中最关键的是 Severity(严重等级),它直接决定你的修复优先级。
五个等级,两种态度
| 等级 | CVSS 分数 | 处理策略 |
|------|-----------|----------|
| CRITICAL | 9.0-10.0 | 立即修复,阻断发布流水线 |
| HIGH | 7.0-8.9 | 优先修复,限期 72 小时内处理 |
| MEDIUM | 4.0-6.9 | 排入迭代计划,下个版本修复 |
| LOW | 0.1-3.9 | 记录跟踪,有空再修 |
| UNKNOWN | 无评分 | 人工评估,判断是否影响业务 |
CRITICAL 和 HIGH 是你真正要盯的。其余等级当然不能完全无视,但在资源有限的情况下,先把房子着火的地方灭了,再考虑墙皮掉没掉。
关注 Fixed Version 列
报告中的 "Fixed Version" 列至关重要。如果这一列有值,说明上游已经发布了补丁,你只需要更新基础镜像或对应的包。如果显示为空,意味着目前无修复方案,这时候需要评估是否可以通过其他方式缓解风险(比如网络隔离、权限收紧)。
制定修复策略
扫出漏洞只是开始,关键是怎么修。
策略一:升级基础镜像
80% 的漏洞来自基础镜像中的系统包。把换成,或者把换成,漏洞数量可能直接砍掉一半。
- # 修复前:基于完整 Debian,包含大量无用系统包
- FROM python:3.11
- # 修复后:最小化基础镜像
- FROM python:3.11-slim
复制代码
策略二:多阶段构建
构建工具链(gcc、make、git)不应该出现在最终镜像中。用多阶段构建把编译环境和运行环境分离:
- # 构建阶段
- FROM golang:1.22 AS builder
- WORKDIR /app
- COPY . .
- RUN go build -o server .
- # 运行阶段:只包含二进制文件
- FROM gcr.io/distroless/base-debian12
- COPY --from=builder /app/server /server
- CMD ["/server"]
复制代码
distroless 镜像甚至没有 shell,攻击面小到几乎可以忽略。
策略三:锁定并更新依赖
对于应用层的漏洞(npm、pip、Maven 依赖),定期执行依赖更新:
- # Node.js 项目
- npm audit fix
- # Python 项目
- pip install --upgrade package_name
复制代码
更新后重新扫描,确认漏洞已消除。
策略四:忽略不可修复的漏洞
有些漏洞暂时没有补丁,或者经评估对你的场景不构成威胁。可以用文件显式忽略:
- # .trivyignore
- CVE-2024-ZZZZ # 该组件未在运行时加载,风险可接受
复制代码
显式忽略比假装看不见强一百倍——至少你评估过了。
嵌入 CI/CD 流水线
手动扫描靠自觉,自动扫描靠流程。真正的安全卡点,必须嵌入 CI/CD。
GitHub Actions 集成
- name: Image Security Scan
- on:
- push:
- branches: [main]
- pull_request:
- branches: [main]
- jobs:
- scan:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
- - name: Build Docker image
- run: docker build -t myapp:${{ github.sha }} .
- - name: Run Trivy scan
- uses: aquasecurity/trivy-action@master
- with:
- image-ref: myapp:${{ github.sha }}
- format: table
- exit-code: 1
- severity: CRITICAL,HIGH
- ignore-unfixed: true
复制代码
这里的关键参数是 ——当发现 CRITICAL 或 HIGH 级别漏洞时,直接让流水线失败。镜像发不出去,代码合不进去。这就是"安全卡点"的含义:不是建议你修,是不修就别想上线。
会跳过那些还没有补丁的漏洞,避免因为无法修复的问题阻塞整个发布流程。
GitLab CI 集成
- container_scan:
- stage: test
- image:
- name: aquasec/trivy:latest
- entrypoint: [""]
- script:
- - trivy image --exit-code 1 --severity CRITICAL,HIGH --ignore-unfixed myapp:${CI_COMMIT_SHA}
- allow_failure: false
复制代码
生成结构化报告
终端输出适合人看,但流水线中你可能需要机器可读的格式:
- # JSON 格式,方便后续处理
- trivy image --format json --output report.json myapp:latest
- # SARIF 格式,可直接上传到 GitHub Security 面板
- trivy image --format sarif --output report.sarif myapp:latest
复制代码
JSON 报告可以对接告警系统,SARIF 格式能直接在 GitHub 的 Security 标签页中展示漏洞详情。
实战建议
第一,定期扫描存量镜像。不只是构建时扫一次,已经部署的镜像也需要周期性扫描。新漏洞每天都在被披露,昨天安全的镜像今天可能就不安全了。
- # 扫描本地所有镜像
- for img in $(docker images --format "{{.Repository}}:{{.Tag}}"); do
- trivy image --severity HIGH,CRITICAL "$img"
- done
复制代码
第二,设置合理的阈值。一开始别太激进。如果你的存量镜像有几百个 HIGH 漏洞,把卡点设成 CRITICAL 先跑起来,逐步收紧到 HIGH。安全是个渐进过程,不是一步到位的事。
第三,把扫描报告可视化。Trivy 支持输出 HTML 格式的报告,配合定期发送邮件或推送到 Slack,让团队所有人看到镜像的安全状态。看不见的问题永远不会被修复。
写在最后
镜像安全扫描不是什么高深技术,Trivy 把门槛压到了几乎为零。真正难的是把它变成团队的习惯——每次构建都扫、每个漏洞都评估、每条流水线都卡。
安全这件事,最怕的不是攻击多复杂,而是"我以为没问题"。
现在打开终端,对你正在跑的那个镜像执行一次,看看结果——可能会有惊喜,也可能会有惊吓。
但无论如何,知道问题在哪,永远是解决问题的第一步。 |
|