开源镜像漏洞扫描器

Python016

开源镜像漏洞扫描器,第1张

现在打包应用到 Docker Image 变的越来越普遍了,因此镜像的安全性也变得越来越重要了;

很多人认为只要打包成镜像应用就是安全的,但是大家也知道镜像是一个静态文件,由很多层组成,只要其中的一层发现漏洞,就会对你的应用造成威胁;

现在也出现了很多开源的漏洞扫描工具,用来扫描镜像中可能存在的漏洞,有 Anchore , Clair 和 Trivy

Anchore 是用 python 写的,主要功能就是对 Docker Image 的扫描,它是一个 CLI 工具,当然也可以通过 API 的方式调用; Anchore 也有一款带有界面的 Anchore Enterprise 版本

Anchore Github

Clair 是用 Golang 写的,主要实现了对 Docker image 的漏洞分析,用户可以调用它的 API 来扫描镜像中的漏洞

Clair Github

Trivy 也是用 Golang 写的,它不仅实现了对 Image 的扫描,还可以扫描文件,Git 仓库以及配置;它也是一个 CLI 工具,安装之后就可以通过命令实现扫描功能

Tricy Github

下面就用这三个扫描器分别对 Docker 官方统计的常用镜像扫描,扫描结果的对比如下:

Anchore 和 Clair 相比较 Trivy 出现的时间更早,但是扫描的结果发现 Trivy 能发现更多的漏洞,尤其是对 alphine 镜像;现在大部分镜像的基础镜像都会选择 alpine ,因为它更加轻量级而且漏洞相对较少

而 Anchore 和 Clair 对一些 alpine 镜像是扫描不出来漏洞的,但是使用 Trivy 却能够找到;之前部署的 Harbor 版本使用的扫描器是 Clair ,扫描 alphine 镜像之后没有发现漏洞,就认为是安全的;现在 Harbor2.0 之后是使用 Trivy 作为默认扫描器,对一些 alphine 就能够扫描出来漏洞了

Trivy 相对于其他两个来说,安装更加的简单,使用也更加的方便;并且能够支持多种类型的文件的扫描,目前也是 Harbor 默认的扫描器

参考连接:

https://boxboat.com/2020/04/24/image-scanning-tech-compared/

https://www.a10o.net/devsecops/docker-i

使用go语言递归查找指定目录下的文件,根据正则匹配筛选出需要的文件,并且忽略指定的目录

先使用 ioutil.ReadDir 遍历出指定目录下的文件,再递归进目录中遍历,问题的关键在于识别出文件为目录, fs.FileInfo 中有一个 IsDir() 函数可以识别是否是目录

正则匹配使用 regexp.MatchString ,regexp中有很多正则操作的工具,如根据正则替换字符串中的指定字符

最近在看左神新书 《Go 语言设计与实现》的垃圾收集器时产生一个疑惑,花了点时间搞清楚了记录一下。

Go 语言垃圾回收的实现使用了标记清除算法,将对象的状态抽象成黑色(活跃对象)、灰色(活跃对象中间状态)、白色(潜在垃圾对象也是所有对象的默认状态)三种,注意没有具体的字段标记颜色。

整个标记过程就是把白色对象标黑的过程:

1.首先将 ROOT 根对象(包括全局变量、goroutine 栈上的对象等)放入到灰色集合

2.选一个灰色对象,标成黑色,将所有可达的子对象放入到灰色集合

3.重复2的步骤,直到灰色集合中为空

下图是书上的插图,看上去是一个典型的深度优先搜索的算法。

下图是刘丹冰写的《Golang 修养之路》的插图,看上去是一个典型的广度优先搜索的算法。

我疑惑的点在于这个标记过程是深度优先算法还是广度优先算法,因为很多文章博客对此都没有很清楚的说明,作为学习者这种细节其实也不影响对整个 GC 流程的理解,但是这种细节我非常喜欢扣:)

对着书和源码摸索着大致找到了一个结果是深度优先。下面看下大致的过程,源码基于1.15.2版本:

gcStart 是 Go 语言三种条件触发 GC 的共同入口

启动后台标记任务

为每个处理器创建用于执行后台标记任务的 Goroutine

上面休眠的 G 会在调度循环中检查并唤醒执行

执行标记

gcw 是每个 P 独有的所以不用担心并发的问题 和 GMP、mcache 一样设计,减少锁竞争

尝试在全局列表中获取一个不为空的 buf

这是官方实现的无锁队列:)涨见识了,for 循环加原子操作实现栈的 pop

到这里从灰色集合中获取待扫描的对象逻辑说完了。找到对象了接着就是 scanobject(b, gcw) 了,里面有两段逻辑要注意

根据索引位置找到对象进行标色

尝试存入 gcwork 的缓存中,或全局队列中

无锁队列,for 循环加原子操作实现栈的 push

到这里把灰色对象标黑就完成了,又放回灰色集合接着扫下一个指针。

Go 语言设计与实现 垃圾收集器

Golang三色标记+混合写屏障GC模式全分析