Docker镜像漏洞定期扫描安全巡检自动化脚本完整实践
搜索“Docker镜像漏洞扫描”的用户,通常不是想了解概念,而是想知道怎么定期自动检查服务器上的镜像有没有高危漏洞,并在结果出来后能查看和处理。
本文直接用一个可落地的方案:基于 Trivy + Crontab 做整机镜像漏洞扫描,把结果写入日志,再配套一个通知动作。
为什么选 Trivy 做定期扫描
Trivy 是开源容器镜像漏洞扫描工具,支持本地镜像、容器文件系统,也支持已知 CVE 库对比。
对零基础用户来说,优点在于安装简单、指令少、默认输出可读性好。
配合 Docker 后,一行命令就能扫描:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image --severity HIGH,CRITICAL nginx
这条命令会扫描 nginx 镜像的高危和严重漏洞。
注意:如果服务器无法拉取外网镜像,需要在脚本里配置镜像加速器,或者提前把相关镜像导入。
编写漏洞扫描安全巡检脚本
先把脚本放到 /usr/local/bin/docker-scan.sh,内容如下:
#!/bin/bash
LOG_DIR="/var/log/docker-scan"
LOG_FILE="$LOG_DIR/scan_$(date +%F_%H%M).log"
mkdir -p "$LOG_DIR"
echo "=== Docker image scan started: $(date) ===" > "$LOG_FILE"
# 只扫描本地仓库中已有镜像,避免扫到外部私有库
docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "" | while read img; do
echo "--- Scanning: $img ---" >> "$LOG_FILE"
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --severity HIGH,CRITICAL --ignore-unfixed "$img" >> "$LOG_FILE" 2>&1
done
echo "=== Scan done: $(date) ===" >> "$LOG_FILE"
# 这里可以接入企业微信/钉钉通知,先用邮件模板做占位
然后给执行权限:
chmod +x /usr/local/bin/docker-scan.sh
脚本里 --ignore-unfixed 会跳过没有修复版本的漏洞,减少误报。
如果你的环境希望保留所有结果,可以去掉这个参数。
配置 Crontab 定时执行
编辑定时任务:
crontab -e
加入下面一行,代表每天凌晨 2 点执行扫描:
0 2 * * * /usr/local/bin/docker-scan.sh
保存后重启 cron:
systemctl restart crond
扫描日志会以日期时间命名存放在 /var/log/docker-scan/ 目录,不会覆盖旧记录。
避坑与常见问题
- 不要在容器内每隔几分钟就全量扫描:镜像层多、镜像数量大时,扫描耗时会明显拉长,建议每天一次或每周一次。
- Trivy 镜像更新问题:脚本执行时需要拉取或更新 Trivy 数据库,建议先执行一次
docker pull aquasec/trivy,确认网络能通。 - 日志快速膨胀:日志文件多了之后还需要配合
find做自动清理,例如只保留最近 30 天:
find /var/log/docker-scan -name "*.log" -mtime +30 -delete
如何验证自动化是否生效
手动执行一次脚本:
bash /usr/local/bin/docker-scan.sh
然后检查日志:
tail -n 30 /var/log/docker-scan/scan_*.log
看到 Total: 0 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) 之类的统计就说明正常。
再通过 crontab -l 查看任务是否已写入。
如果发现脚本没有被执行,先手动跑一次看是否有权限或路径错误。
本文给的命令可以直接复制使用,适合自己的服务器环境后,再根据镜像数量和业务需要调整扫描周期。
如果扫描中发现高危漏洞,优先更新镜像或更换基础镜像,临时修不了可以先限制容器对外暴露端口。