共计 3925 个字符,预计需要花费 10 分钟才能阅读完成。
文章目录 [显示]
你的 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 --version
第一次扫描
选一个你正在用的镜像,直接扫:
trivy image nginx:1.24
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% 的漏洞来自基础镜像中的系统包。把 python:3.11 换成 python:3.11-slim,或者把 node:18 换成 node:18-alpine,漏洞数量可能直接砍掉一半。
# 修复前:基于完整 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 文件显式忽略:
# .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
这里的关键参数是 exit-code: 1——当发现 CRITICAL 或 HIGH 级别漏洞时,直接让流水线失败。镜像发不出去,代码合不进去。这就是 " 安全卡点 " 的含义: 不是建议你修,是不修就别想上线 。
ignore-unfixed: true 会跳过那些还没有补丁的漏洞,避免因为无法修复的问题阻塞整个发布流程。
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 把门槛压到了几乎为零。真正难的是把它变成团队的习惯——每次构建都扫、每个漏洞都评估、每条流水线都卡。
安全这件事,最怕的不是攻击多复杂,而是 " 我以为没问题 "。
现在打开终端,对你正在跑的那个镜像执行一次 trivy image,看看结果——可能会有惊喜,也可能会有惊吓。
但无论如何, 知道问题在哪,永远是解决问题的第一步 。