本文目录导读:

在Shell脚本中扫描容器镜像漏洞,通常需要借助第三方的漏洞扫描工具,以下是几种常见的方法和对应的脚本示例:
使用 Trivy(推荐)
Trivy 是最流行的开源容器漏洞扫描工具之一。
安装 Trivy
# macOS brew install trivy # Linux curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh # Docker 方式运行 docker run aquasec/trivy --help
扫描脚本示例
#!/bin/bash
# 扫描单个镜像
scan_image() {
local image_name="$1"
echo "扫描镜像: $image_name"
# Trivy 扫描,输出 JSON 格式
trivy image --format json --output "${image_name//\//_}_scan.json" "$image_name"
# 检查是否有严重漏洞
trivy image --severity CRITICAL,HIGH --exit-code 1 "$image_name"
if [ $? -eq 1 ]; then
echo "警告: 发现严重或高危漏洞!"
return 1
fi
return 0
}
# 批量扫描多个镜像
scan_images() {
local images=("$@")
local failed=0
for image in "${images[@]}"; do
if ! scan_image "$image"; then
failed=$((failed + 1))
fi
done
echo "扫描完成: $failed 个镜像存在漏洞"
return $failed
}
# 使用示例
images=(
"nginx:latest"
"node:14-alpine"
"python:3.9-slim"
)
scan_images "${images[@]}"
使用 Grype
Grype 是 Anchore 的开源漏洞扫描工具。
安装 Grype
# macOS brew install grype # Linux curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
扫描脚本
#!/bin/bash
scan_with_grype() {
local image="$1"
local output_file="${image//\//_}_grype_scan.json"
echo "使用 Grype 扫描: $image"
# JSON 格式输出
grype "$image" -o json > "$output_file"
# 仅显示严重漏洞
echo "严重漏洞:"
cat "$output_file" | jq '.matches[] | select(.vulnerability.severity == "Critical") | {package: .artifact.name, vulnerability: .vulnerability.id}'
# 检查并返回退出码
grype "$image" --fail-on Critical --quiet
return $?
}
# 使用示例
if scan_with_grype "nginx:latest"; then
echo "未发现严重漏洞"
else
echo "发现严重漏洞,请检查报告"
fi
使用 Docker Scout(Docker Desktop 内置)
#!/bin/bash
# 需要 Docker Desktop 4.17+
scan_with_docker_scout() {
local image="$1"
echo "使用 Docker Scout 扫描: $image"
# 登录 Docker Hub(如果需要)
# docker login
# 启用 Docker Scout
docker scout enable
# 扫描镜像
docker scout quickview "$image"
# 获取详细报告
docker scout recommendations "$image"
# 比较镜像
docker scout compare "$image" --to "nginx:1.25-alpine"
}
# 使用示例
scan_with_docker_scout "nginx:latest"
综合扫描脚本(带CI/CD集成)
#!/bin/bash
set -euo pipefail
# 配置
SCANNER="trivy" # trivy, grype, or docker-scout
SEVERITY_THRESHOLD="CRITICAL,HIGH"
EXIT_ON_FINDINGS=true
REPORT_DIR="./security_reports"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 检查工具安装
check_tool() {
if ! command -v "$1" &> /dev/null; then
log_error "$1 未安装"
exit 1
fi
}
# 创建报告目录
setup_reports() {
mkdir -p "$REPORT_DIR"
local timestamp=$(date +%Y%m%d_%H%M%S)
REPORT_FILE="$REPORT_DIR/scan_report_$timestamp.json"
}
# 使用 Trivy 扫描
trivy_scan() {
local image="$1"
local image_safe="${image//\//_}"
log_info "开始 Trivy 扫描: $image"
# 完整扫描并输出 JSON
trivy image --format json \
--severity "$SEVERITY_THRESHOLD" \
--output "$REPORT_DIR/${image_safe}_trivy.json" \
"$image" 2>/dev/null
# 快速检查漏洞
local vuln_count=$(trivy image --severity "$SEVERITY_THRESHOLD" \
--exit-code 0 \
--quiet \
"$image" 2>/dev/null | grep -c "Total:")
echo "$vuln_count"
}
# 生成HTML报告
generate_html_report() {
local image="$1"
local image_safe="${image//\//_}"
local html_file="$REPORT_DIR/${image_safe}_report.html"
cat > "$html_file" << EOF
<!DOCTYPE html>
<html>
<head>容器漏洞扫描报告 - $image</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: #333; }
.critical { color: red; }
.high { color: orange; }
.medium { color: yellow; }
.low { color: green; }
</style>
</head>
<body>
<h1>扫描报告: $image</h1>
<p>扫描时间: $(date)</p>
<h2>漏洞摘要</h2>
<pre>$(cat "$REPORT_DIR/${image_safe}_trivy.json" | python3 -m json.tool 2>/dev/null || cat "$REPORT_DIR/${image_safe}_trivy.json")</pre>
</body>
</html>
EOF
log_info "HTML报告已生成: $html_file"
}
# 清理函数
cleanup() {
log_info "清理临时文件..."
# 可以在这里添加清理逻辑
}
# 主函数
main() {
local images=("$@")
if [ ${#images[@]} -eq 0 ]; then
log_error "请提供要扫描的镜像名称"
echo "用法: $0 <镜像1> [镜像2] ..."
exit 1
fi
# 设置清理陷阱
trap cleanup EXIT
# 检查工具
check_tool "$SCANNER"
setup_reports
local total_vulns=0
local failed_images=0
for image in "${images[@]}"; do
echo -e "\n${YELLOW}═══════════════════════════════════════${NC}"
log_info "扫描镜像: $image"
echo -e "${YELLOW}═══════════════════════════════════════${NC}\n"
# 执行扫描
if [ "$SCANNER" = "trivy" ]; then
vuln_count=$(trivy_scan "$image")
if [ "$vuln_count" -gt 0 ] && [ "$EXIT_ON_FINDINGS" = true ]; then
log_warn "发现 $vuln_count 个漏洞"
generate_html_report "$image"
failed_images=$((failed_images + 1))
else
log_info "未发现漏洞"
fi
fi
total_vulns=$((total_vulns + vuln_count))
done
# 输出总结
echo -e "\n${YELLOW}═══════════════════════════════════════${NC}"
log_info "扫描完成"
echo "扫描镜像数: ${#images[@]}"
echo "存在漏洞的镜像数: $failed_images"
echo "总漏洞数: $total_vulns"
echo "报告位置: $REPORT_DIR"
echo -e "${YELLOW}═══════════════════════════════════════${NC}"
# 返回非零退出码表示有漏洞
if [ "$failed_images" -gt 0 ] && [ "$EXIT_ON_FINDINGS" = true ]; then
exit 1
fi
}
# 执行主函数
main "$@"
使用方式
基本用法
# 扫描单个镜像 ./scan.sh nginx:latest # 扫描多个镜像 ./scan.sh nginx:latest node:14-alpine python:3.9 # 忽略漏洞继续执行 ./scan.sh --no-fail nginx:latest
CI/CD 集成示例 (GitLab CI)
container-scan:
stage: test
image: aquasec/trivy:latest
script:
- trivy image --severity CRITICAL,HIGH --exit-code 1 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
- main
重要提示
-
更新漏洞数据库:定期更新扫描工具的漏洞数据库
trivy image --update # 或 trivy image --cache-backend redis://localhost:6379
-
性能考虑:大规模扫描时考虑使用缓存和并行处理
-
权限管理:确保脚本有适当的执行权限
chmod +x scan.sh
-
结果处理:根据业务需求决定如何处理发现的漏洞(阻塞发布、记录报警等)
这些脚本提供了完整的容器漏洞扫描解决方案,可以根据具体需求进行调整和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播