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
加密
$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
可以看到加密后的信息
### 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
只有一个bash镜像
尝试拉取镜像
ctr images pull localhost:5000/bash.enc:latest
拉取成功
启动镜像:
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!'
也是可以运行的
这是因为 一次解密以后就可以一直使用,不需要每次创建容器时都输入秘钥 参考链接
结论
仅第一次使用时需要认证,后续运行可以进入到容器中查看容器中的内容。因此并不适合对容器中的代码做保护,对容器中的代码保护还是需要从二进制加密和代码混淆角度入手。