【云原生安全篇】Trivy助力离线Harbor漏洞扫描实践
【云原生安全篇】Trivy助力离线Harbor漏洞扫描实践
目录
- 1 概念
- 1.1 为什么需要离线漏洞扫描
- 1.2 Trivy和Harbor 简介
- 1.3 实现离线漏洞扫描的技术方案
- 2 实践:Trivy 为Harbor提供离线漏洞扫描
- 2.1 环境准备
- 2.2 安装Trivy作为数据库离线包下载代理
- 2.2.1 通过包管理工具安装
- 2.2.2 通过二进制方式安装
- 2.2.3 使用官方脚本安装
- 2.2.4 查看trivy版本
- 2.3 下载最新的漏洞数据库:
- 2.4 使用oras下载数据库离线包(可选)
- 2.4.1 什么是oras
- 2.4.2 安装oras
- 2.4.3 下载离线数据库文件
- 2.5 配置 Harbor 使用 Trivy 扫描器
- 2.6 将数据库转移到离线环境
- 2.6.1 打包历史离线数据库文件
- 2.6.2 同步最新的离线数据库文件
- 2.7 扫描镜像并查看结果
- 2.7.1 查看trivy状态
- 2.7.2 找一个镜像手动扫描漏洞
- 2.8 trivy下载和同步脚本
- 2.8.1 在trivy端和harbor端添加脚本
- 2.8.2 设置定时任务
- 3 总结
❤️ 摘要: 在云原生环境中,容器镜像的安全性至关重要。作为一个强大的、轻量级的开源漏洞扫描工具,Trivy 能为Harbor容器镜像仓库提供了安全扫描和扫描结果可视化等功能。然而,在一些网络隔离的环境中,Harbor 的在线扫描功能可能无法使用。本文将介绍如何通过 Trivy 实现 离线 Harbor 漏洞扫描,并详细展示如何使用 Trivy 结合 Harbor,在离线环境中保护镜像安全。
💯 本文关联文章:
- 《【云原生安全篇】一文读懂Trivy》
- 《【云原生安全篇】一文掌握Harbor集成Trivy应用实践》
1 概念
1.1 为什么需要离线漏洞扫描
在一些安全性要求高的企业和政府单位环境中,网络出于安全原因会受到限制,可能无法连接到互联网。特别是在敏感业务的生产环境中,Harbor 镜像仓库被隔离在内部网络中,无法直接与在线漏洞扫描服务通信。
在这种情况下,使用 Trivy 的 离线扫描 功能,可以在不访问互联网的前提下,保持对镜像的高效漏洞扫描,确保容器的安全性。
1.2 Trivy和Harbor 简介
Trivy
Trivy 是由 Aqua Security 开发的开源安全扫描工具,能够扫描容器镜像、文件系统、基础设施即代码(IaC)等对象中的已知漏洞。Trivy 提供了快速、准确的扫描结果,帮助开发人员在开发早期识别潜在的安全风险。
Trivy 有以下几个主要特性:
- 快速扫描:支持高效的漏洞数据库更新。
- 丰富的漏洞检测:支持扫描操作系统漏洞、第三方库漏洞(如 Java、Node.js 等)以及错误配置。
- 离线模式:支持离线使用和数据库更新,这对于网络受限的环境非常有用。
Harbor
Harbor 是一个开源的企业级云原生镜像仓库,它不仅可以存储和分发 Docker 镜像,还提供了镜像复制、权限控制、镜像签名、漏洞扫描等功能。通过与安全工具的集成,Harbor 能够在上传和管理镜像时对其进行漏洞检测。
1.3 实现离线漏洞扫描的技术方案
为了实现离线的漏洞扫描,需要通过Trivy代理将 最新漏洞数据库提前下载并复制到离线环境中。然后,结合 Harbor 的内置扫描器功能,通过配置 Harbor 使用 Trivy 作为扫描引擎,执行镜像的漏洞扫描。
- Trivy 的离线数据库支持:可以预先在有网络的环境中下载漏洞数据库,并将其导入到离线环境中。
- Harbor 的 Trivy 扫描集成: Trivy 作为harbor默认支持的扫描工具,与 Harbor 集成实现自动漏洞扫描。
2 实践:Trivy 为Harbor提供离线漏洞扫描
接下来,我们将详细介绍如何在离线环境中配置 Trivy 并结合 Harbor 实现镜像的漏洞扫描。
2.1 环境准备
- Harbor:已经部署并运行在一个没有互联网访问的环境中。
- Trivy:将在离线环境中使用,作为 Harbor 的漏洞扫描器。
2.2 安装Trivy作为数据库离线包下载代理
首先,你需要安装Trivy,可以根据你的操作系统使用以下方式安装。
2.2.1 通过包管理工具安装
通过包管理工具安装,执行以下命令安装:
sudo apt-get install wget apt-transport-https gnupg
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
2.2.2 通过二进制方式安装
❔ 参考: trivy二进制包下载地址
下载二进制安装包
mkdir trivy
cd trivy
wget https://github.com/aquasecurity/trivy/releases/download/v0.55.1/trivy_0.55.1_Linux-64bit.tar.gz
解压安装包
TEMP_DIR=$(mktemp -d)
tar xvf trivy_0.55.1_Linux-64bit.tar.gz -C ${TEMP_DIR}
sudo cp ${TEMP_DIR}/trivy /usr/local/bin/
2.2.3 使用官方脚本安装
可以自动识别操作系统并完成包安装, 但是对网络有一定依赖。
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
2.2.4 查看trivy版本
你可以通过以下命令确认Trivy安装成功:
root@ub22:~/trivy# trivy version
Version: 0.55.1
2.3 下载最新的漏洞数据库:
下载离线漏洞库文件
trivy image --download-db-only --db-repository ghcr.io/aquasecurity/trivy-db:2
下载离线java缺陷库文件
trivy image --download-java-db-only --java-db-repository ghcr.nju.edu.cn/aquasecurity/trivy-java-db:1
参数说明:
- –download-db-only: 只下载离线缺陷数据库文件
- –download-java-db-only: 只下载java索引数据库文件
- –db-repository: 指定trivy-db的OCI源(默认是ghcr.io/aquasecurity/trivy-db:2)
- –java-db-repository: 指定trivy-java-db的OCI源(默认是:ghcr.io/aquasecurity/trivy-java-db:1)
- ghcr.io/aquasecurity/trivy-db:2、ghcr.nju.edu.cn/aquasecurity/trivy-java-db:1:国内源加速下载。
查看文件结构
.cache/
├── motd.legal-displayed
└── trivy├── db # 缺陷数据库│ ├── metadata.json│ └── trivy.db└── java-db # java缺陷数据库├── metadata.json└── trivy-java.db3 directories, 5 files
❔ 说明: 数据库文件会保存在当前用户主目录的
~/.cache/ trivy
文件夹下。
2.4 使用oras下载数据库离线包(可选)
2.4.1 什么是oras
ORAS 是一个专门用于将各种类型的非容器镜像的二进制文件(如软件包、配置文件、Helm Charts、OCI Artifacts 等)推送和拉取到 OCI (Open Container Initiative) 兼容的镜像仓库中的轻量级的工具。
简单来说,ORAS 使得用户能够使用 OCI 兼容的仓库来存储和分发各种文件,而不仅仅是容器镜像。它扩展了 OCI 标准的适用范围,使得开发者可以将应用程序的所有部分(不仅是容器镜像)存储在同一个基础设施中。
2.4.2 安装oras
执行以下命令安装oars
VERSION="1.2.0"
curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz"
mkdir -p oras-install/
tar -zxf oras_${VERSION}_*.tar.gz -C oras-install/
sudo mv oras-install/oras /usr/local/bin/
rm -rf oras_${VERSION}_*.tar.gz oras-install/
检查oras版本信息,执行oras version
:
Version: 1.2.0
Go version: go1.22.3
Git commit: dcef719e208a9b226b15bc6512ad729a7dd93270
Git tree state: clean
2.4.3 下载离线数据库文件
切换到临时目录
cd /tmp
下载离线漏洞库文件
oras pull ghcr.nju.edu.cn/aquasecurity/trivy-db:2 -v --insecure
下载离线java索引库文件
oras pull ghcr.nju.edu.cn/aquasecurity/trivy-java-db:1 -v --insecure
解压trivy-db并拷贝到cache目录
mkdir /tmp/trivy && tar -zxvf /tmp/db.tar.gz -C /tmp/trivy
cp -rfp /tmp/trivy/* /root/.cache/trivy/db/
解压trivy-java-db并拷贝到cache目录
mkdir /tmp/trivy-java && tar -zxvf /tmp/javadb.tar.gz -C /tmp/trivy-java
cp -rfp /tmp/trivy-java/* /root/.cache/trivy/java-db
2.5 配置 Harbor 使用 Trivy 扫描器
在离线环境中,Harbor 默认集成了 Trivy 扫描器,但是需要配置 Trivy 以便它可以使用离线数据库。
在 Harbor 服务器中,编辑 harbor.yml
配置文件,确保启用了 Trivy 扫描器。
trivy:ignore_unfixed: falseskip_update: true # 关闭在线更新缺陷数据库skip_java_db_update: true # 关闭在线更新java缺陷数据库offline_scan: true # 启用离线扫描模式 security_check: vulninsecure: true
重启 Harbor 以应用配置更改:
./install.sh --with-trivy
或者
./prepare.sh
docker-compose restart
2.6 将数据库转移到离线环境
下载好的漏洞数据库文件需要定时上传至离线harbor环境中。通常实现方式有:
- 如果代理服务器与其他离线环境内网未打通, 则手动传输。
- 如果内网打通的场景,使用内网的文件传输工具(如
scp
或rsync
)将相关文件传输到离线环境的服务器。
2.6.1 打包历史离线数据库文件
trivy数据目录说明:
- 主路径: harbor会把主机的
/data/trivy-adapter/trivy
映射到trivy-adapter容器的/home/scanner/.cache/trivy
- db: 存放vulnerable缺陷数据库文件和元数据
- fanal: Trivy 的核心库,可以作为 Go 库导入。您可以扫描 Go 中的配置文件并使用 Go 的测试方法(例如表驱动测试)测试您的自定义策略。这允许您使用实际的配置文件作为输入,从而轻松准备测试数据并确保您的自定义策略在实践中发挥作用。
- java-db: 存放java缺陷数据库文件和元数据
- backup: 自定义,存放备份数据库文件
创建备份文件夹
mkdir -p
/data/trivy-adapter/trivy/backup
备份数据库
# 定义打包日期格式
CURRENT_DATE=$(date +'%Y%m%d')
BACKUP_PATH="/data/trivy-adapter/trivy/backup"# 打包主数据库
tar -czf ${BACKUP_PATH}/db_${CURRENT_DATE}.tar.gz -C /data/trivy-adapter/trivy/db .# 打包 Java 数据库
tar -czf ${BACKUP_PATH}/java_db_${CURRENT_DATE}.tar.gz -C /data/trivy-adapter/trivy/java-db .
2.6.2 同步最新的离线数据库文件
# 远程地址
REMOTE_IP="root@192.168.3.200"# 定义本地数据库路径
LOCAL_DB_PATH="/data/trivy-adapter/trivy/db/"
LOCAL_JAVA_DB_PATH="/data/trivy-adapter/trivy/java-db/"# 远程数据库缓存目录
REMOTE_DB_PATH="/root/.cache/trivy/db/"
REMOTE_JAVA_DB_PATH="/root/.cache/trivy/java-db/"# 创建本地目录如果不存在
mkdir -p ${LOCAL_DB_PATH}
mkdir -p ${LOCAL_JAVA_DB_PATH}# 同步 Trivy 主数据库
rsync -avz --delete ${REMOTE_IP}:${REMOTE_DB_PATH}/* ${LOCAL_DB_PATH}# 同步 Trivy Java 数据库
rsync -avz --delete ${REMOTE_IP}:${REMOTE_JAVA_DB_PATH}/* ${LOCAL_JAVA_DB_PATH}# 修改db文件的属主和属组
chown -R 10000.10000 ${LOCAL_DB_PATH} ${LOCAL_JAVA_DB_PATH}
2.7 扫描镜像并查看结果
2.7.1 查看trivy状态
配置完成后,登录Harbor的管理后台查看。
路径:首页→审查服务→扫描器
说明: trivy的配置已经生效。
2.7.2 找一个镜像手动扫描漏洞
路径:项目→选择hcie项目→选择redis镜像
点击镜像,并在操作选项中选择 “扫描”。-
扫描完成后,Harbor 的界面会显示每个镜像的漏洞情况,包括漏洞的严重等级(如 High
、Medium
、Low
)。
2.8 trivy下载和同步脚本
2.8.1 在trivy端和harbor端添加脚本
#!/bin/bash# 任务1: Trivy更新离线数据库
update_trivy_db() {echo "开始更新 Trivy 数据库..."# 更新 Trivy 离线数据库trivy image --download-db-only --db-repository ghcr.io/aquasecurity/trivy-db:2trivy image --download-java-db-only --java-db-repository ghcr.nju.edu.cn/aquasecurity/trivy-java-db:1echo "Trivy 数据库更新完成。"
}# 任务2: Harbor打包之前的数据库文件
backup_trivy_db() {echo "开始打包 Trivy 数据库文件..."# 定义打包日期格式CURRENT_DATE=$(date +'%Y%m%d')BACKUP_PATH="/data/trivy-adapter/trivy/backup"# 确保备份目录存在mkdir -p ${BACKUP_PATH}# 打包主数据库tar -zczf ${BACKUP_PATH}/db_${CURRENT_DATE}.tar.gz -C /data/trivy-adapter/trivy/db .# 打包 Java 数据库tar -zczf ${BACKUP_PATH}/java_db_${CURRENT_DATE}.tar.gz -C /data/trivy-adapter/trivy/java-db .echo "Trivy 数据库文件打包完成:db_${CURRENT_DATE}.tar.gz 和 java_db_${CURRENT_DATE}.tar.gz"# 任务3: 只保留最近7天的数据库文件echo "清理旧的备份文件..."find ${BACKUP_PATH} -type f -name "*.tar.gz" -mtime +7 -exec rm -f {} \;echo "旧的备份文件清理完成。"
}# 任务4: 使用 rsync 同步最新数据库到本地目录
sync_trivy_db() {echo "开始同步数据库到本机..."# 定义远端地址REMOTE_IP="root@192.168.3.200"# 定义本地数据库路径LOCAL_DB_PATH="/data/trivy-adapter/trivy/db/"LOCAL_JAVA_DB_PATH="/data/trivy-adapter/trivy/java-db/"# 远端数据库缓存目录REMOTE_DB_PATH="/root/.cache/trivy/db/"REMOTE_JAVA_DB_PATH="/root/.cache/trivy/java-db/"# 创建本地目录如果不存在mkdir -p ${LOCAL_DB_PATH}mkdir -p ${LOCAL_JAVA_DB_PATH}# 同步 Trivy 主数据库rsync -avz --delete ${REMOTE_IP}:${REMOTE_DB_PATH} ${LOCAL_DB_PATH}# 同步 Trivy Java 数据库rsync -avz --delete ${REMOTE_IP}:${REMOTE_JAVA_DB_PATH} ${LOCAL_JAVA_DB_PATH}# 修改本地数据库属组和属主chown -R 10000.10000 ${LOCAL_DB_PATH} ${LOCAL_JAVA_DB_PATH}echo "数据库同步完成。"
}# 检查第一个脚本参数并执行相应的函数
case "$1" inupdate_trivy_db)update_trivy_db;;backup_trivy_db)backup_trivy_db;;sync_trivy_db)sync_trivy_db;;*)echo "Usage: $0 {update_trivy_db|backup_trivy_db|sync_trivy_db}"exit 1;;
esac
给脚本添加执行权限
chmod +x /usr/local/bin/trivy_rsync.sh
2.8.2 设置定时任务
在trivy端添加更新数据库任务,在终端中运行以下命令编辑 crontab 文件:
crontab -e
添加以下定时任务调度规则:
# 每天0点更新Trivy数据库
0 0 * * * /usr/local/bin/trivy_rsync.sh update_trivy_db > /var/log/trivy.log 2>&1
在harbor端添加备份文件和同步文件的任务,在终端中运行以下命令编辑 crontab 文件:
crontab -e
添加以下定时任务调度规则:
# 每天23点30分打包数据库文件,清理旧文件
30 23 * * * /usr/local/bin/trivy_rsync.sh backup_trivy_db > /var/log/trivy.log 2>&1# 每天0点30分同步数据库文件到本地
30 0 * * * /usr/local/bin/trivy_rsync.sh sync_trivy_db > /var/log/trivy.log 2>&1
3 总结
通过本文的介绍和实践步骤,我们展示了如何使用 Trivy 结合 Harbor 实现 离线漏洞扫描,在没有互联网访问的环境中仍然保持对容器镜像的安全检查。这个解决方案在隔离环境中,能够有效防止因未修补的漏洞导致的潜在攻击。