OCI

容器运行时标准,Open Container Initiative containerd,cri-o,docker,rkt都是OCI的实现。 所以对镜像加密实际上是需要对OCI镜像进行处理。 # containerd containerd 支持对image的加解密具体说明参考containerd文档。 加密的镜像是包含加密blob(二进制对象)的OCI格式的镜像。 # 加密 ## imgcrypt ### install 需要提前准备好golang环境

git clone https://github.com/containerd/imgcrypt.git
cd imgcrypt
make
sudo make install

encrypt

创建RSA key

openssl genrsa -out mykey.pem
openssl rsa -in mykey.pem -pubout -out mypubkey.pem

创建加密镜像

# 这里使用已经安装好的containerd服务
sudo chmod 0666 /run/containerd/containerd.sock
CTR="/usr/local/bin/ctr-enc"
$CTR images pull --all-platforms docker.io/library/bash:latest

查看镜像层数

$CTR images layerinfo --platform linux/amd64 docker.io/library/bash:latest
Pastedimage20241106181333.png

加密

$CTR images encrypt --recipient jwe:mypubkey.pem --platform linux/amd64 docker.io/library/bash:latest bash.enc:latest

查看镜像层数

$CTR images layerinfo --platform linux/amd64 bash.enc:latest

Pasted image 20241106181803.png 可以看到加密后的信息 ### use 启动一个本地registry

sudo docker pull registry:latest
sudo docker run -d -p 5000:5000 --restart=always --name registry registry

推送镜像

$CTR images tag bash.enc:latest localhost:5000/bash.enc:latest
$CTR images push localhost:5000/bash.enc:latest
$CTR images rm localhost:5000/bash.enc:latest bash.enc:latest

查看本地images

ctr images ls

Pasted image 20241106182948.png 只有一个bash镜像

尝试拉取镜像

ctr images pull localhost:5000/bash.enc:latest

Pasted image 20241106183111.png 拉取成功

启动镜像:

ctr run --rm localhost:5000/bash.enc:latest test echo 'Hello World!'

what ??? 居然可以直接运行??

在搜索一圈之后发现,需要删除本地镜像,不光包括生成的加密镜像,还包括原始镜像,才可以使用加密功能。 在删除所有镜像之后,再次拉取镜像,拉镜像时需要提供key。

ctr images pull --key ./mykey.pem  localhost:5000/bash.enc:latest

然后直接运行

ctr run --rm localhost:5000/bash.enc:latest test echo 'Hello World!'

也是可以运行的

这是因为 一次解密以后就可以一直使用,不需要每次创建容器时都输入秘钥 参考链接

结论

仅第一次使用时需要认证,后续运行可以进入到容器中查看容器中的内容。因此并不适合对容器中的代码做保护,对容器中的代码保护还是需要从二进制加密和代码混淆角度入手。