《OpenShift 4.x HOL教程汇总》

说明

本文将对测试镜像签名,然后推送到本地Docker Registry上。当用户有签名对应秘钥时,可以正常从Docker Registry获得该镜像;如果没有合法秘钥,则无法从Docker Registry上获取被签名的镜像。

以下用root用户操作。

准备环境

安装python3

$ yum install python3 -y

配置镜像签名

  1. 先创建一个GPG密钥对。根据提示提供用户名、邮箱和密码,并接受缺省选项即可。
$ gpg --full-gen-key
gpg (GnuPG) 2.2.20; Copyright (C) 2020 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.Please select what kind of key you want:(1) RSA and RSA (default)(2) DSA and Elgamal(3) DSA (sign only)(4) RSA (sign only)(14) Existing key from card
Your selection?
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.0 = key does not expire<n>  = key expires in n days<n>w = key expires in n weeks<n>m = key expires in n months<n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) yGnuPG needs to construct a user ID to identify your key.Real name: liuxiaoyu
Email address: xiaoyliu@redhat.com
Comment: test
You selected this USER-ID:"liuxiaoyu (test) <xiaoyliu@redhat.com>"Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key D28961834BC7974B marked as ultimately trusted
gpg: directory '/root/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/root/.gnupg/openpgp-revocs.d/433F149D481E050260F36F88D28961834BC7974B.rev'
public and secret key created and signed.pub   rsa2048 2021-08-11 [SC]433F149D481E050260F36F88D28961834BC7974B
uid                      liuxiaoyu (test) <xiaoyliu@redhat.com>
sub   rsa2048 2021-08-11 [E]
  1. 再用“aaa、aaa@redhat.com”创建另一个签名使用的密钥对。
  2. 查看刚刚创建的GPG秘钥
$ gpg --list-keys xiaoyliu@redhat.com
gpg: checking the trustdb
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   rsa2048 2021-08-11 [SC]433F149D481E050260F36F88D28961834BC7974B
uid           [ultimate] liuxiaoyu (test) <xiaoyliu@redhat.com>
sub   rsa2048 2021-08-11 [E]
  1. 在本地运行一个Docker Registry容器。
$ podman run -d -p 5000:5000 docker.io/registry
Trying to pull docker.io/library/registry:latest...
Getting image source signatures
Copying blob 6eda6749503f done
Copying blob 12008541203a done
Copying blob ddad3d7c1e96 done
Copying blob 363ab70c2143 done
Copying blob 5b94580856e6 done
Copying config 1fd8e1b0bb done
Writing manifest to image destination
Storing signatures
3df860c0e5ef3292d7373e183acedf8c3e8405a98a6c1917d09a89f1d0e4587b
  1. pull一个alpine镜像到本地
$ podman pull docker://docker.io/alpine:latest
Trying to pull docker://docker.io/alpine:latest...
Getting image source signatures
Copying blob 29291e31a76a done
Copying config 021b342311 done
Writing manifest to image destination
Storing signatures
021b3423115ff662225e83d7e2606475217de7b55fde83ce3447a54019a77aa2
  1. 查看alpine镜像并打标签
$ podman images alpine
REPOSITORY                TAG     IMAGE ID      CREATED     SIZE
docker.io/library/alpine  latest  021b3423115f  4 days ago  5.87 MB
$ podman tag alpine localhost:5000/alpine
$ podman images alpine
REPOSITORY                TAG     IMAGE ID      CREATED     SIZE
docker.io/library/alpine  latest  021b3423115f  4 days ago  5.87 MB
localhost:5000/alpine     latest  021b3423115f  4 days ago  5.87 MB
  1. 修改/etc/containers/registries.d/default.yaml文件,修改其中default-docker下面的sigstore和sigstore-staging为以下内容。
default-docker:sigstore: http://localhost:8000 # Added by ussigstore-staging: file:///var/lib/containers/sigstore
  1. 签名alpine镜像并推送到本地Docker Registry,然后删除本地的alpine镜像。
$ GNUPGHOME=$HOME/.gnupg
$ podman push --tls-verify=false --sign-by xiaoyliu@redhat.com localhost:5000/alpine
Getting image source signatures
Copying blob bc276c40b172 done
Copying config 021b342311 done
Writing manifest to image destination
Signing manifest
Storing signatures
$ podman rmi docker.io/alpine localhost:5000/alpine
  1. 查看系统签名存储,
$ ls /var/lib/containers/sigstore
'alpine@sha256=864fe88b86abf48d78de06f57cc5c8be02cc907cfb01c54ef4b668db1c8e0056'
  1. 修改/etc/containers/policy.json文件,把以下内容“docker”部分复制到/etc/containers/policy.json文件中的“transports”区域,以强制验证镜像签名必须是合法的。验证签名使用的key是"/tmp/key.gpg"。
{"default": [{ "type": "insecureAcceptAnything" }],"transports": {"docker": {"localhost:5000": [{"type": "signedBy","keyType": "GPGKeys","keyPath": "/tmp/key.gpg"}]}}
}

验证

  1. 在本地运行一个临时http服务,监控镜像签名目录。
$ cd /var/lib/containers/sigstore && python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
  1. 将xiaoyliu@redhat.com对应的秘钥导出到/tmp/key.gpg文件,然后从Docker Registry上pull已被签名的alpine镜像。由于该镜像签名时就是使用xiaoyliu@redhat.com对应的秘钥,因此可以正常获取该镜像到本地。
$ gpg --output /tmp/key.gpg --armor --export xiaoyliu@redhat.com
$ podman pull --tls-verify=false localhost:5000/alpine
Trying to pull localhost:5000/alpine:latest...
Getting image source signatures
Checking if image destination supports signatures
Copying blob f0eabd2439ac done
Copying config 021b342311 done
Writing manifest to image destination
Storing signatures
021b3423115ff662225e83d7e2606475217de7b55fde83ce3447a54019a77aa2
  1. 将aaa@redhat.com对应的秘钥导出到/tmp/key.gpg文件,然后从Docker Registry上pull已被签名的alpine镜像。由于该镜像签名时没有使用aaa@redhat.com对应的秘钥,因此无法正常获取该镜像到本地。
$ gpg --output /tmp/key.gpg --armor --export aaa@redhat.com
$ podman pull --tls-verify=false localhost:5000/alpine
Trying to pull localhost:5000/alpine:latest...Invalid GPG signature: gpgme.Signature{Summary:128, Fingerprint:"433F149D481E050260F36F88D28961834BC7974B", Status:gpgme.Error{err:0x9}, Timestamp:time.Time{wall:0x0, ext:63764273480, loc:(*time.Location)(0x55f4d64ac040)}, ExpTimestamp:time.Time{wall:0x0, ext:62135596800, loc:(*time.Location)(0x55f4d64ac040)}, WrongKeyUsage:false, PKATrust:0x0, ChainModel:false, Validity:0, ValidityReason:error(nil), PubkeyAlgo:1, HashAlgo:8}
Error: Source image rejected: Invalid GPG signature: gpgme.Signature{Summary:128, Fingerprint:"433F149D481E050260F36F88D28961834BC7974B", Status:gpgme.Error{err:0x9}, Timestamp:time.Time{wall:0x0, ext:63764273480, loc:(*time.Location)(0x55f4d64ac040)}, ExpTimestamp:time.Time{wall:0x0, ext:62135596800, loc:(*time.Location)(0x55f4d64ac040)}, WrongKeyUsage:false, PKATrust:0x0, ChainModel:false, Validity:0, ValidityReason:error(nil), PubkeyAlgo:1, HashAlgo:8}

参考

https://github.com/containers/podman/blob/main/docs/tutorials/image_signing.md
http://redhatgov.io/workshops/security_container_intro/lab07-signing/

容器入门(8) - 镜像签名相关推荐

  1. linux代码签名,浅谈Linux容器和镜像签名(示例代码)

    导读 从根本上说,几乎所有的主要软件,即使是开源软件,都是在基于镜像的容器技术出现之前设计的.这意味着把软件放到容器中相当于是一次平台移植.这也意味着一些程序可以很容易就迁移,而另一些就更困难. 我大 ...

  2. Harbor2.2.1配置(trivy扫描器、镜像签名)

    docker-compose下载 https://github.com/docker/compose/releases 安装 cp docker-compose /usr/local/bin chmo ...

  3. 自动化集成:Docker容器入门简介

    前言:该系列文章,围绕持续集成:Jenkins+Docker+K8S相关组件,实现自动化管理源码编译.打包.镜像构建.部署等操作:本篇文章主要描述Docker基础用法. 一.Docker简介 1.基础 ...

  4. 容器入门(6) - 获取访问Docker Registry的公钥证书

    <OpenShift 4.x HOL教程汇总> 获取问Docker Registry的证书 在根据<容器入门(1) - 安装和使用Docker Registry>,我们可以使用 ...

  5. 容器入门(3) - docker

    <OpenShift 4.x HOL教程汇总> 文章目录 安装Docker客户端 客户端配置文件 登录/登出Container Registry 登录身份凭证 查询镜像 pull/push ...

  6. 容器入门(4) - skopeo

    <OpenShift 4.x HOL教程汇总> 文章目录 对独立的Docker Registry操作 查看Registry上的Image信息 在2个Registry之间复制Image 对O ...

  7. 容器入门(2) - podman

    <OpenShift 4.x HOL教程汇总> 文章目录 安装Podman环境 运行配置文件 登录/登出Container Registry 利用登录凭证免密操作 查询镜像 pull/pu ...

  8. Docker容器入门及网易最佳实践

    文章目录 第一节 Docker容器入门 1.1.1 基础概念 1. Docker是什么 2. Docker和传统虚拟机的对比 3. 为什么要使用Docker 4. Docker架构 5. Docker ...

  9. 亚马逊云科技——云原生主题容器入门笔记

    嗨,大家好,我是异星球的小怪同志 一个想法有点乱七八糟的小怪 如果觉得对你有帮助,请支持一波. 希望未来可以一起学习交流. 目录 一.容器入门课程 二.容器入门课堂笔记 1.容器背后的发展历史 2.区 ...

最新文章

  1. Java 理论与实践: 垃圾收集简史
  2. 清理 zabbix 历史数据, 缩减 mysql 空间
  3. android和windows技术,《技术》android运行windows的优化与试调整
  4. site_url()和base_url()
  5. Spring-bean的循环依赖以及解决方式___Spring源码初探--Bean的初始化-循环依赖的解决
  6. Python 打开目录与指定文件
  7. 碰撞与鲜血:人类与自动驾驶的坎坷摩擦
  8. 大数据质量管理策略有哪些
  9. 微软总部首席测试专家做客中关村图书大厦“说法”
  10. ubuntu 串口调试工具推荐_Qt开源作品3-串口调试助手
  11. 利用系统函数获取Windows明文密码
  12. python opencv读大华摄像头视频流实时移动侦测运动检测截图拍照保存
  13. 软件开发常见的开发方向
  14. oracle中imp命令详解
  15. Springboot疫苗接种管理系统毕业设计-附源码191451
  16. Ruoyi框架学习--Vue前端配置文件详解
  17. Python摇骰子-A05
  18. 【Algorithms公开课学习笔记3】 栈与队列
  19. 20175312陶光远 与 20175309刘雨恒 结对
  20. 搜酷:紧跟淘宝步伐的大卖家

热门文章

  1. mysql80压缩版安装_裕-安装MySQL80(压缩版)
  2. oracle用户的追踪文件,Oracle中怎样通过触发器来追踪用户的活动?
  3. 计算机能实现哪些人类智力活动,人工智能是电脑科学的一个重要分支,它的近期目标是什么?...
  4. java聊天系统异常问题_【图片】写的socket编程实现窗口聊天出现空指针错误 在自己电脑没事【java吧】_百度贴吧...
  5. android 多媒体文件信息,Android如何获取多媒体文件信息
  6. 牛年春节与年俗插画素材,年味十足
  7. 素材干货|UI设计师不会插画?不难搞!有了这些模板,作品安了!
  8. python递归创建目录_Python学习第172课——Linux中一次性创建多层目录以及递归列出所有子目录...
  9. C语言为四维数组申请动态内存空间的方法(二)
  10. Linux开机启动过程(13):start_kernel()->setup_arch()完结