离线更新k8s环境下的trivy漏洞库方法
本文记录的是如何在离线环境下快速更新trivy.db,解决国内下载东西网络慢的问题,以及如何将文件拷贝进容器。这两个小技巧比较实用,以供未来参考。
本文的场景是在K8S中使用Helm部署的Harbor仓库使用trivy进行漏洞扫描,需要注意我这里harbor版本是v2.1.4。对应的trivy的容器镜像是trivy-adapter-photon:v2.1.4,使用的是trivy version 1,使用的Trivy DB 的更新日期还是2021年,支持的最高Trivy DB v1只更新到2023-02-08,可以参考:https://github.com/aquasecurity/trivy-db#download-the-vulnerability-database官方文档。如果要更新到更新的trivy漏洞库估计得同步更新Harbor才行了。这里仅对我这个版本进行记录,即只将Trivy DB更新到2023-02-08。
根据官方文档其实更新trivy.db的方式很简单,如果能访问外网直接一条trivy image --download-db-only
命令搞定或者能搭建一个db库也行trivy image --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db
。如果没有外网则直接替换harbor-harbor-trivy-0
Pod中/home/scanner/.cache/trivy/db/
目录下的trivy.db和metadata.json文件即可。
如果在Trivy version 1里面直接使用Trivy DB v2则会报错:
the version of DB schema doesn't match. Local DB: 2, Expected: 1(点击展开)
2023-09-04T09:14:54Z [INFO] [/pkg/scan/job.go:325]: registration: 2023-09-04T09:14:54Z [INFO] [/pkg/scan/job.go:336]: { "uuid": "145755d1-008f-11ec-9901-f6b6534433d6", "name": "Trivy", "description": "The Trivy scanner adapter", "url": "http://harbor-harbor-trivy:8080", "disabled": false, "is_default": true, "health": "healthy", "auth": "", "skip_certVerify": false, "use_internal_addr": true, "adapter": "Trivy", "vendor": "Aqua Security", "version": "v0.9.2", "create_time": "2021-08-19T01:45:06.323427Z", "update_time": "2021-08-19T01:45:06.323428Z" } 2023-09-04T09:14:54Z [INFO] [/pkg/scan/job.go:325]: scanRequest: 2023-09-04T09:14:54Z [INFO] [/pkg/scan/job.go:336]: { "registry": { "url": "http://harbor-harbor-core:80", "authorization": "[HIDDEN]" }, "artifact": { "namespace_id": 3, "repository": "ci/javabase", "tag": "", "digest": "sha256:6bef11801820b6ec976ab59fb474807d3c9d763613c95ede87a0e27589002c7d", "mime_type": "application/vnd.docker.distribution.manifest.v2+json" } } 2023-09-04T09:14:54Z [INFO] [/pkg/scan/job.go:156]: Report mime types: [application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0] 2023-09-04T09:14:54Z [INFO] [/pkg/scan/job.go:202]: Get report for mime type: application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0 2023-09-04T09:14:56Z [INFO] [/pkg/scan/job.go:219]: Report with mime type application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0 is not ready yet, retry after 5 seconds 2023-09-04T09:15:01Z [ERROR] [/pkg/scan/job.go:284]: check scan report with mime type application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0: running trivy wrapper: running trivy: exit status 1: 2023-09-04T09:14:58.588Z [31mERROR[0m Trivy version (0.9.2) is old. Update to the latest version. 2023-09-04T09:14:58.588Z [31mFATAL[0m database error: the version of DB schema doesn't match. Local DB: 2, Expected: 1 : general response handler: unexpected status code: 500, expected: 200下载DB
根据官方文档说明,如果是Trivy DB V1则直接在github release里面下载,V1的库只更新到2023年2月,V2则需要通过Trivy or Oras CLI下载。
Trivy:
# 1. 创建一个临时目录
TRIVY_TEMP_DIR=$(mktemp -d)
# 2. 使用 Trivy 下载漏洞数据库到临时目录
docker run --rm -v $TRIVY_TEMP_DIR:/root/.cache/ aquasec/trivy image --download-db-only
# 3. 将文件打包到 db.tar.gz
tar -cf ./db.tar.gz -C $TRIVY_TEMP_DIR trivy/db
# 4. 删除临时目录
rm -rf $TRIVY_TEMP_DIR
Oras CLI:
oras pull ghcr.io/aquasecurity/trivy-db:2
但是国内下载都非常之慢,这里有个小技巧:通过https://labs.play-with-docker.com/和https://www.tmp.link/进行下载。
play-with-docker可以比较快速的访问外网和启动Docker容器,在里面执行上面的Trivy命令得到我们需要的trivy.db和metadata.json文件;
而tmp.link是一个临时网盘,可以方便的使用Curl进行文件上传下载,将文件通过Curl上传到这个网盘就可以在国内比较快速地下载了。
curl -k -F "file=@/root/db.tar.gz" -F "token=xxx" -F "model=1" -X POST "https://tmp-cli.vx-cdn.com/app/upload_cli"
更换Trivy的DB
我这里是直接替换harbor-harbor-trivy-0
Pod中/home/scanner/.cache/trivy/db/
目录下的trivy.db和metadata.json文件即可。
首先容易想到的就是直接kubectl cp命令就行了。可是无法执行,如下:
# 拷贝出来
$ kubectl cp xxx-namespace/harbor-harbor-trivy-0:/home/scanner/.cache/trivy/db/metadata.json ./metadata.json
command terminated with exit code 126
# 拷贝进去
$ kubectl cp ./trivy.db xxx-namespace/harbor-harbor-trivy-0:/home/scanner/.cache/trivy/db/trivy.db
OCI runtime exec failed: exec failed: container_linux.go:346: starting container process caused "exec: \"tar\": executable file not found in $PATH": unknown
command terminated with exit code 126
kubectl cp
命令依赖tar命令,如果容器没有tar命令是没法执行的。而刚好trivy容器对应的镜像trivy-adapter-photon:v2.1.4没有tar命令。
第二个小技巧:大多数容器中都有curl命令,我们可以通过curl内部的minio文件服务进行下载。
### 备份
kubectl exec -it pod/harbor-harbor-trivy-0 -n xxx-namespace -- mv /home/scanner/.cache/trivy/db/metadata.json /home/scanner/.cache/trivy/db/metadata.json.bak2
kubectl exec -it pod/harbor-harbor-trivy-0 -n xxx-namespace -- mv /home/scanner/.cache/trivy/db/trivy.db /home/scanner/.cache/trivy/db/trivy.db.bak2
### 下载文件
kubectl exec -it pod/harbor-harbor-trivy-0 -n xxx-namespace -- curl -o /home/scanner/.cache/trivy/db/metadata.json 'http://10.221.113.1:32367/minio/download/trivy/metadata.json?token=' \
-H 'Connection: keep-alive' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' \
-H 'Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6' \
-H 'Cookie: redirect_to=%252F' \
--compressed \
--insecure
kubectl exec -it pod/harbor-harbor-trivy-0 -n xxx-namespace -- curl -o /home/scanner/.cache/trivy/db/trivy.db 'http://10.221.113.1:32367/minio/download/trivy/trivy.db?token=' \
-H 'Connection: keep-alive' \
-H 'Upgrade-Insecure-Requests: 1' \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36' \
-H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' \
-H 'Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6' \
-H 'Cookie: redirect_to=%252F' \
--compressed \
--insecure
这里还有个小问题就是我们的minio服务是使用的内部域名,直接在容器里无法解析域名也无法修改hosts文件,所以这里把minio通过NodePort暴露出来即可。尝试直接curl minio:9000
也不行(k8s service name+port),所以我添加了很多Header来模拟浏览器访问,这个命令是通过浏览器访问http://10.221.113.1:32367
下载文件时,从F12控制台 Copy的Curl命令得到的。
总结
- Trivy的漏洞库DB更新直接替换文件即可,但需要注意Trivy DB V1还是V2;
- 技巧一:通过https://labs.play-with-docker.com/和https://www.tmp.link/操作,解决国内下载文件慢的问题
- 技巧二:容器中没有tar命令无法执行kubectl cp命令时,可以通过curl 从文件存储上下载/上传文件。