前段时间一个项目里面,对方用扫描器扫出来 grafana 有 sourcemap 文件,其实这原本是无风险的,有瑕疵还是处理一下。
本文会简单介绍一下修改镜像 layer 的方法。
首先要明确一个概念,镜像是由一层层的 layer 叠加起来的,所以直接在 Dockerfile 当中 from image
RUN rm -rf file
是没有意义的,前面的 layer 当中的文件依然可以被提取出来。所以需要直接对 layer 进行操作。
然后要读懂 image 的格式,我喜欢 oci format,所以以下均为 oci format 的操作。
先把镜像拉下来
oci format 为一个文件夹,目录树为
所有 manifest 里面的 sha256 都是对应 blobs/sha256/ 底下的文件
所以就一层一层找
index.json [> multi_platform_manifest ]> single_platform_manifest > special_layer
这样的路径向下找要修改的文件,找到目标 layer(layer 会是一个 gzip tarball)修改完内容之后对内容进行 sha256sum,把内容重命名为 sha256value,然后修改上一层 manifest 里面的 digest 和 size,然后继续向上修改 manifest,不断重复这件事。
这是 layer 部分的修改,除此之外,还需要修改 image config。
special_layer 是一个 tar.gz。我们解压出来修改完内容之后(这会是一个 tar),此时也需要计算一次 sha256,这个值需要被填充到 image config 的 .rootfs.diff_ids[layer_index]
。然后再进行 gzip 生成 tar.gz。要是不进行 config diff_ids 的修改,会出现 layers from manifest don't match image configuration.
的报错。
大体流程就是如此。
针对本次目标(删除 grafana 里面的 sourcemap),找了了 layer 之后,只需要
完整的过程我写成了一个 bash 脚本,放在了 hunshcn/grafana-sourcemap-less,可以自行制作 sourcemap less 镜像,寻找 target layer 的规则是 layer 倒序找到第一个 size > 1000000 的 layer,理论上如果有其他镜像需要移除 sourcemap 只需要修改这个逻辑即可。
手改的和脚本改的会有一点点差异。
因为脚本改的会把 manifest 的缩进扔掉,因为用了 yq –inplace, size 可能会因此出现变化。
然后手改的缩进自然是不会变的,但是 size 一样会变,用 vim 修改会比原来多一个字节(比如 2203 把 sha256 替换了会变成 2204),应该是多了一个控制字符,我没有过多探究。