容器镜像漏洞定期扫描安全巡检脚本
很多运维小伙伴会定期拉取新镜像更新容器,但镜像里的底层漏洞往往容易被忽略。
手动逐个扫描不仅低效,还可能漏掉关键风险。
本文用 Trivy 这个免费开源工具,带你从零写一个自动扫描脚本,配合 cron 定时任务实现容器镜像漏洞的定期安全巡检。
适合刚接触容器安全、没有专职安全人员的小团队,跟着步骤走就能跑起来。
准备工作:安装 Trivy 并确认环境
Trivy 支持多种安装方式,推荐用官方安装脚本一步到位。
在 Linux 服务器上执行:
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh
安装完成后,运行 trivy --version 验证。
如果返回版本号,说明安装成功。
注意 Trivy 第一次扫描会下载漏洞数据库,需要服务器能正常访问 GitHub 或配置代理。
如果下载慢,可以设置 TRIVY_DB_REPOSITORY 环境变量指定国内镜像源(例如阿里云镜像)。
后续脚本中会用到 Docker 命令,所以服务器上必须安装好 Docker 并确保当前用户有执行权限(或者用 sudo)。
可以执行 docker ps 测试。
编写安全巡检脚本:单镜像扫描与报告输出
我们创建一个脚本 scan_images.sh,实现批量扫描本地所有镜像并输出 CSV 格式报告。
脚本核心逻辑如下:
#!/bin/bash
# 容器镜像漏洞定期扫描安全巡检脚本
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
REPORT_DIR="/var/log/image_scan"
mkdir -p $REPORT_DIR
# 获取所有镜像 ID
IMAGES=$(docker images -q)
for IMAGE in $IMAGES; do
IMAGE_NAME=$(docker images --no-trunc | grep $IMAGE | awk '{print $1":"$2}' | head -1)
echo "扫描镜像: $IMAGE_NAME"
trivy image --quiet --format csv --output "${REPORT_DIR}/${IMAGE_NAME//\//_}_${TIMESTAMP}.csv" $IMAGE
done
echo "扫描完成,报告已保存至 $REPORT_DIR"
保存后赋予执行权限:chmod +x scan_images.sh。
脚本执行时会逐镜像扫描,生成的 CSV 文件包含漏洞编号、严重等级、受影响的包等信息。
如果要限时扫描,可以加 --timeout 10m 参数。
配置定时任务:让扫描自动跑起来
用 crontab -e 编辑定时任务,添加一行每周日凌晨 2 点执行:
0 2 * * 0 /home/you/scan_images.sh
如果想每天凌晨 3 点扫描,改为 0 3 * * *。
注意脚本路径要写绝对路径,避免环境变量问题。
建议在脚本开头显式指定 PATH,例如 PATH=/usr/local/bin:/usr/bin:/bin,因为 cron 执行时的环境变量有限。
避坑指南:新手最容易踩的三个雷
- Trivy 数据库下载失败:首次扫描会下载约 500MB 的漏洞库,如果网络不稳定,脚本会卡住。建议先用
trivy image --download-db-only手动下载一次,确认成功后再加上--cache-dir参数指定缓存目录。 - 镜像名称包含特殊符号导致 CSV 报错:脚本中用
//\//_替换路径分隔符,但如果镜像名含有冒号、斜杠等,建议改用$IMAGE(镜像 ID) 作为文件名前缀,避免报错:"${REPORT_DIR}/scan_${IMAGE}_${TIMESTAMP}.csv"。 - 报告文件堆积:每天扫描会生成大量 CSV,建议脚本末尾添加旧文件清理逻辑:
find $REPORT_DIR -name "*.csv" -mtime +30 -delete
这样只保留最近 30 天的报告。
验证效果:检查报告并确认定时任务生效
手动执行一次脚本:bash scan_images.sh,观察终端输出。
完成后进入 /var/log/image_scan/ 目录,用 cat 或 less 查看 CSV 文件。
如果有漏洞记录,会看到类似 CVE-2023-XXXX,CRITICAL 的行。
查看定时任务是否生效:crontab -l 可以列出当前任务,注意检查时间表达式是否正确。
还可以查看 cron 日志(一般位于 /var/log/cron 或 journalctl -u cron)。
如果脚本没有按时执行,先手动跑一次排除业务逻辑问题。
常见问题
问:扫描所有镜像会花很长时间,能不能只扫描特定标签的镜像?
答:可以修改脚本中的镜像列表,用 docker images --format "{{.Repository}}:{{.Tag}}" | grep "^mycompany/" 过滤出需要的镜像。
问:扫描结果怎么推送到告警平台?
答:脚本扫描结束后,可以用 grep -i critical 从 CSV 中提取高危漏洞,再通过 curl 调用企业微信或钉钉 webhook 发送通知。
如果你正在部署容器镜像漏洞定期扫描安全巡检脚本,建议先按本文步骤完整执行,再根据自己的镜像规模调整扫描频率和报告保存策略;
遇到异常时优先回看避坑和高频问题部分。