harbor-trivy 漏洞扫描


官网文档

  1. 官网: https://aquasecurity.github.io/trivy/
  2. GitHub: https://github.com/aquasecurity/trivy
  3. 官方文档: https://aquasecurity.github.io/trivy/latest/


作用

  1. Trivy 是 Aqua Security 开发的开源漏洞扫描器,主要特点:
  2. 全面性: 扫描操作系统包(Alpine, RHEL, Debian 等)和语言特定包(npm, yarn, pip, gem, composer 等)
  3. 简单易用: 只需一个二进制文件,无需数据库或前置依赖
  4. 快速: 首次运行后缓存漏洞数据库,后续扫描速度极快
  5. 多平台: 支持容器镜像、文件系统、Git 仓库、Kubernetes 等


应用场景

  1. CI/CD 流水线: 在构建时扫描镜像,阻止有漏洞的镜像部署
  2. 容器安全: 扫描 Docker/OCI 镜像
  3. 基础设施即代码: 扫描 Terraform、Kubernetes manifests
  4. 开发环境: 开发者在本地扫描依赖
  5. 合规检查: 满足安全合规要求


安装 trivy


上传安装解压


链接: https://pan.baidu.com/s/1obr3le1ZKol7O90Y3-AiCQ 提取码: is43

tar -zxvf trivy_0.69.3_Linux-64bit.tar.gz


将 trivy 移动到系统 PATH 目录

mv trivy /usr/local/bin/


赋予执行权限

chmod +x /usr/local/bin/trivy


清理临时文件

rm -f trivy_0.69.3_Linux-64bit.tar.gz README.md LICENSE


检查版本

trivy --version
# 输出应该是: Version: 0.69.3


配置连接 Harbor 私有仓库

docker login harbor250.oldboyedu.com


配置证书

cp /etc/docker/certs.d/harbor250.oldboyedu.com/ca.crt /usr/local/share/ca-certificates/ca.crt

#更新生效证书
update-ca-certificates


扫描镜像


#下载 html 模板

#开启vpn
/scripts/vpn-control.sh on
export http_proxy=http://192.168.0.101:7890
export https_proxy=http://192.168.0.101:7890
#关闭vpn
unset  http_proxy https_proxy

#下载html
wget https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/html.tpl -O html.tpl


生成报告


扫描 xiuxianv3.0 并生成报告

trivy image --format template --template "@./html.tpl" --output trivy-report.html harbor250.oldboyedu.com/greytracks/xiuxian:v3.0


加入CICD流水线


trivy 加入 CICD 流水线

pipeline {
    agent any
    
    environment {
        HARBOR = 'harbor250.oldboyedu.com'
        PROJECT = 'greytracks'
        IMAGE_NAME = 'xiuxian'
        TRIVY_TEMPLATE = '/root/html.tpl'
    }
    
    // 触发条件:Push 或打 Tag 都触发
    triggers {
        githubPush()
        gitlab(triggerOnPush: true, triggerOnTagPush: true)
    }
    
    parameters {
        string(name: 'IMAGE_TAG', defaultValue: '', description: '镜像Tag(留空用BUILD_NUMBER)')
    }
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your/repo.git'
            }
        }
        
        stage('Build & Push') {
            steps {
                script {
                    env.TAG = params.IMAGE_TAG ?: "build-${BUILD_NUMBER}"
                    env.FULL_IMAGE = "${HARBOR}/${PROJECT}/${IMAGE_NAME}:${env.TAG}"
                    
                    sh """
                        docker build -t ${env.FULL_IMAGE} .
                        docker push ${env.FULL_IMAGE}
                    """
                }
            }
        }
        
        stage('Trivy 漏洞扫描') {
            steps {
                script {
                    env.HTML_REPORT = "trivy-report-${env.TAG}.html"
                    env.JSON_REPORT = "trivy-report-${env.TAG}.json"
                    
                    echo "开始扫描镜像: ${env.FULL_IMAGE}"
                    
                    // 1. 生成 HTML 报告(给人看)
                    sh """
                        trivy image \
                          --format template \
                          --template "@${TRIVY_TEMPLATE}" \
                          --output ${env.HTML_REPORT} \
                          ${env.FULL_IMAGE}
                    """
                    
                    // 2. 生成 JSON 报告(给机器用)
                    sh """
                        trivy image \
                          --format json \
                          --output ${env.JSON_REPORT} \
                          ${env.FULL_IMAGE}
                    """
                    
                    // 3. 快速统计一下漏洞数量(显示在日志里)
                    sh '''
                        echo "=== 漏洞统计 ==="
                        trivy image --format json ''' + env.FULL_IMAGE + ''' | python3 -c "
import json, sys
data = json.load(sys.stdin)
severity_count = {'CRITICAL':0, 'HIGH':0, 'MEDIUM':0, 'LOW':0}
for r in data.get('Results', []):
    for v in r.get('Vulnerabilities', []):
        sev = v.get('Severity', 'UNKNOWN')
        if sev in severity_count:
            severity_count[sev] += 1
print(f'严重: {severity_count[\"CRITICAL\"]}')
print(f'高危: {severity_count[\"HIGH\"]}')
print(f'中危: {severity_count[\"MEDIUM\"]}')
print(f'低危: {severity_count[\"LOW\"]}')
"
                    '''
                }
            }
            post {
                always {
                    // 归档报告,永远保留
                    archiveArtifacts artifacts: "*.html, *.json", fingerprint: true
                }
            }
        }
    }
    
    post {
        always {
            // 清理
            sh 'docker rmi ${env.FULL_IMAGE} 2>/dev/null || true'
            
            echo ""
            echo "=========================================="
            echo "扫描完成!请查看归档的 HTML 报告"
            echo "构建编号: ${BUILD_NUMBER}"
            echo "镜像: ${env.FULL_IMAGE}"
            echo "=========================================="
        }
        success {
            echo "构建流程完成"
        }
        // 注意:没有 failure,永远都是 success
    }
}
 
上一篇
下一篇