[docker] docker 安全知识 - 镜像,port registry

[docker] docker 安全知识 - 镜像,port & registry

这是第一篇,安全部分还有一篇笔记就记完了

说实话,看完了要学的这些东西,感觉大多数安全问题都可以通过验证登录的合法性去解决

镜像

镜像的问题还是比较多的,主要问题也是集中在:

  • 镜像的可变性

    这是针对使用了 恶意镜像(malicious images) 这一情况

  • 镜像的不可变性

    这是针对当前镜像使用了 不安全的镜像(images with vulnerabilities) 这一情况

  • 镜像的 layer 结构

    这个是 docker 为了在建造镜像的过程中提速而实现的缓存机制,从而可能会导致信息被嵌入 layer 中,从而被暴露——只要获取镜像,就能够查看所有的 layers

需要注意,恶意镜像和不安全的镜像二者有这本质的区别:

前者是黑客 有意 嵌入具有攻击性的代码,从而威胁到镜像的安全性

后者是开发 无意 实现的 bug

恶意镜像

一般来说正常下载镜像的时候都会使用镜像名+tag 的方式,如果只是想拉一个最新版本,那么也会忽略 tag,如:

docker run node
Unable to find image 'node:latest' locally
# automically pull the latest version from docker hub
latest: Pulling from library/node
609c73876867: Downloading [========================>                          ]  24.25MB/49.56MB
7247ea8d81e6: Download complete
be374d06f382: Download complete
b4580645a8e5: Downloading [==>                                                ]  10.19MB/211.1MB
dfc93b8f025c: Waiting
a67998ba05d7: Waiting
9513f49617f6: Waiting
e2a102227dc6: Waiting

或者是用 docker-compose:

server:
  image: "nginx:stable-alpine3.17"
  ports:
    - "8000:80"
  volumes:
    - ./src:/var/www/html:delegated
    - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro

乍一看好像没什么问题,但是如果跑过几次 docker build 的话就会注意到一件事情——镜像+tag 这一组合,其实是可以包含不同的镜像的,如:

docker build -f image.dockerfile  -t image-vulnerability .
# 省略步骤若干
 => [5/5] RUN rm /root/.ssh/id_rsa                                                                                                                                            0.2s
 => exporting to image
 => => exporting layers                                                                                                                                                       0.0s
 => => writing image sha256:1a32b91cf2968f0431c6b357b91f0af97c3ad20a4243743fc830f38eb6e3d769                                                                                  0.0s
 => => naming to docker.io/library/image-vulnerability

 ❯ docker build -f image.dockerfile  -t image-vulnerability .
 # 省略步骤若干
[+] Building 0.4s (11/11) FINISHED                                                                                                                            docker:desktop-linux
 => [internal] load build definition from image.dockerfile                                                                                                                    0.0s
 => [6/6] RUN echo "build completed"                                                                                                                                          0.1s
 => exporting to image                                                                                                                                                        0.0s
 => => exporting layers                                                                                                                                                       0.0s
 => => writing image sha256:2ffc6854752a07eb98cf5f83c775bb79b9d39ee50a1713037248b679d5af1031                                                                                  0.0s
 => => naming to docker.io/library/image-vulnerability

这里我重新修改了一下 Dockerfile,所以运行的结果会不一样,打包的 image 不一样:

  • 前者的 id 为 sha256:1a32b91cf2968f0431c6b357b91f0af97c3ad20a4243743fc830f38eb6e3d769
  • 后者的 id 为 sha256:2ffc6854752a07eb98cf5f83c775bb79b9d39ee50a1713037248b679d5af1031

但是二者共享的是一个镜像名,即 image-vulnerability:latest,如果只是拉去 image-vulnerability:latest,那么无法判断使用的究竟是哪一个镜像。因此,这里的情况就是:

如果黑客获取了 repository 的权限,并且覆盖上传了恶意镜像,在 黑客上传了恶意镜像管理员发现问题删除恶意镜像 这个时间段之间,就有可能会下载到恶意镜像

对于恶意镜像比较常见的处理方式有:

  • 选择验证过的镜像
  • 选择 docker content trust 镜像
  • 选择不可变的 hash 值去下载镜像

以 docker hub 为例,尽量选择官方支持/验证的镜像:

在这里插入图片描述

在这里插入图片描述

使用有漏洞的镜像

这里有漏洞的镜像可以被两个组件使用:

  • docker 镜像本身

    如使用 Node 作为基础镜像去搭建服务器

  • 应用软件

    如一个前后端项目,前端向使用有问题镜像的服务器发送请求

尽管不是所有的漏洞都会被黑客攻击,还是需要了解所使用的镜像包含哪些漏洞,以及根据漏洞等级进行对应的更新

监狱 docker 镜像的不可变性,每一次的更新都会比较具有挑战性,因为需要更新

  • 使用有漏洞镜像的容器

    包括 dockerfile(更新镜像 A),以及重新打包容器

  • 所有和对应容器有依赖关系的容器

    还是因为容器的不可变性,无法做到更新了 A,让所有与 A 有引用关系的容器都自动更新

    所以这里需要重新打包所有基于 A 的容器

secret

之前在一篇笔记里提到可以使用 ARG 而非 ENV,不过很不幸地发现,使用 ARG 也不保险。一般常遇到的情况可能有两个:

  • 直接使用 ARG 明文

    这种情况使用 ENVARG 没区别,一样直接通过 docker inspect 就能看到明文信息

    ⚠️:Docker 17.07 之前 ARG 是会明文显示在打包历史中的,之后的版本尽管移除了这个设定,使得 ARG 的安全性有了提升,不过任何 secrets(密钥相关) 最好还是不要用 ARG 写入 docker 镜像中。不当使用依旧会造成 secrets 被写入 docker layers 中,从而使得密钥可以被所有人访问

  • ARG 写入文件,再删除掉文件

    下面的案例就是写入文件的问题——这里不一定需要使用 ARG ,任何情况的写入,包括使用 COPY 都会造成这个问题

下面是不当设置密钥的 dockerfile:

FROM node:20-alpine

WORKDIR /app

RUN mkdir -p /root/.ssh

COPY id_rsa /root/.ssh/id_rsa

RUN rm /root/.ssh/id_rsa

这里从当前文件夹复制了一个密钥文件,之后执行了一些操作,最终再删除这个密钥

下面是用 dive 简单地进行了一个命令行的可视化,让案例讲解变得简单一些

在某一层 layer 中可以清楚地看到执行的操作是 COPY id_rsa /root/.ssh/id_rsa

在这里插入图片描述

这个时候就可以下载这个镜像,在 本地 打包,构筑一个容器,再使用下面的指令,以管理员的全选对容器进行操作:

docker run -it --privileged --pid=host image-vulnerability nsenter -t 1 -m -u -n -i sh

下面这个截图就是从 overlay2 中获取 id_rsa 的方法了:

在这里插入图片描述

👀 最后一行,通过 cat 指令可以轻松获取已经被删除的 id_rsa 文件,这也是因为 overlayer2 的实现,所有的 COPYFUNDELETE 操作都是在底层的只读层,而这些只读层是会被持久化的。换言之,文件看起来可能像是被删除了,但是因为这个操作被持久化了,所以还是可以在 overlayer2 找到被删除的文件

这里的使用方法是使用 --mount, -ssh--secret

使用方法如下:

RUN --mount=type=ssh git clone git@github.com:user/repo.git

这种情况下,docker 会使用宿主机器上的 SSH 配置去下载 repo


docker build --ssh default=id_rea .

这种情况下,docker 也会使用宿主机器上的 SSH 配置去下载 repo


❯ docker build --secret id=mysecret,src=mysecret.txt .

这种用法更多,可以传更多的 secret 而不是只有 SSH

暴露端口

docker 容器的 network 设置其实挺复杂的,默认情况下是 bridge,这种也是用的比较多的情况,但是 network 的类型总共是有 6 种。除了 None 是彻底关闭容器的端口,不需要予以考量之外,其他的 networking 连接方式总是会涉及到 docker 容器的网络配置与宿主机器的网络配置

最简单的可能涉及到端口冲突,比如说 docker 想使用宿主机器上 3000 的端口,不过宿主机器上已经有一个进程占用了 3000,其他更加复杂的情况,鉴于我也不是 network engineer,这里就不过多涉及了

总之简单来说,如果 dockerfile 没有配置好的话,那么就有可能会引起安全问题,其中一个比较常见的情况是未授权访问的情况

一个简单的案例描述如下:

某产品可能使用了 phpMyAdmin 进行 debug,但是在生产环境下,因为没有配置好 dockerfile 使得 phpMyAdmin 的端口暴露了。黑客使用了一些软件,比如说 Nmap,查看了所有连接到当前网址的端口,如:

在这里插入图片描述

这个情况下,phpMyAdmin 与当前网址的连接端口就会被暴露了,黑客如果访问了这个端口,并且 phpMyAdmin 又没有设置防护,或是防护加密等级比较低,那么就代表着生产环境的数据就全都暴露在了黑客的眼皮子底下

这种情况下的解决方案也比较简单:

  • 生产环境的配置文件一定需要再三检查
  • 如非必需,不要暴露端口
  • 如果必须要暴露端口,那么使用加密登陆的方式

⚠️:配置是很重要的,暴露端口的 flag 是 -p,但是同样还有一个 --publish-all 的 flag。使用这个 flag 会保证所有在 dockerfile 中声明的 EXPOSE 端口会被 自动随机 地 map 到宿主机器上的任意端口

虽然感觉是很方便的配置,不过也增加了不可预测性。因为端口是随机配置的,所以对宿主机器上的防火墙配置也有更高的挑战,如果没有配置好,那么也会暴露出更多的安全问题

docker registry

registry 的安全也是可能出现的漏洞之一,如上文提到的恶意镜像,如果黑客没有权限访问到 registry,那么自然也无法下载恶意镜像,从而规避了风险

registry 中,最知名的公开 registry 是 docker hub(也就是官方),对于私有 registry,那么选择就比较多了

下面是使用 nexus 去建立了一个 registry,并且 curl 了一下所有的 docker 镜像,与 curl 一下 docker hub 官方镜像的对比:

curl http://localhost:8081/repository/docker-private-repo/v2/_catalog
{"repositories":[]}%

# 对比 docker hubcurl Https://index.docker.io/v2/_catalog
{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}

可以看到,curl nexus 的时候不需要任何的验证,直接就返回所有的 repositories,对比 curl docker hub,则是需要验证才能够获取所有的镜像

⚠️:我这里只是新建了一个 nexus 服务器和对应的 docker repository,并没有上传任何镜像,所以返回的结果是空数组:

在这里插入图片描述

如果里面真的有镜像的话,那么就会返回所有的镜像,那么这个时候,就可以根据 http://localhost:8081/repository/docker-private-repo/image-name 这样的路径去下载镜像,检查镜像,然后再上传镜像,从而触发 恶意镜像 这个安全隐患

就算实现了一些基础的验证,让黑客无法上传被修改的镜像,但是黑客也可以尝试下载所有的镜像,导致 DoS(Denial of Service)……毕竟会对 registry 添加 load balancer 的操作,还蛮少见的……正常访问都不会触发这种问题

解决方法也挺简单的:

  • 验证,验证,还是验证

    authentication 真的可以解决七八成的网络安全问题……

  • 添加 TLS

  • 权限管理

    即 authorization,确认只有对应权限的人才分别具有 CRUD 等不同的操作权限


讲道理,docker 的报错 icon 还蛮可爱的……

在这里插入图片描述

reference

  • Content trust in Docker

  • dive

  • Nmap

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/651649.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【学习记录】服务器转发使用tensorboard

场景 代码在服务器上运行,想使用tensorboard查看训练的过程。 但是服务器上不能直接访问地址,所以要转发端口到本地,从而在本地网页中能够打开tensorboard。 参考:https://zhuanlan.zhihu.com/p/680596384 这时我们需要建立本地…

LVGL圆弧、线条、图片、色环、按钮矩阵、文本区域、键盘部件

目录 LVGL圆弧部件 LVGL线条部件 LVGL图片部件 LVGL色环部件 LVGL按钮矩阵部件 LVGL文本区域部件 LVGL键盘部件 LVGL圆弧部件 圆弧部件以弧形滑动的形式来调节、显示某个参数的值。 圆弧部件组成部分: 背景弧(LV_PART_MAIN) 前景弧&am…

实现 Vue 标签页切换效果的组件开发

在本次开发中,我们将实现一个 Vue 组件,用于展示和切换标签页。 背景有移动动画效果 该组件将具有以下功能: 标签页左右滚动点击标签页切换内容关闭指定标签页支持多种标签页风格 以下是实现该组件的具体步骤: 创建 Vue 组件…

APM2.8下载固件的方法(两种办法详解)

1.把APM飞控用安卓手机的USB线插入电脑。 选择COM口,不要选择auto,如果你没有COM口说明你驱动安装有问题。 波特率115200。点击相应的图标就可以下载固件到飞控板。 请注意:烧录APM必须选择INSTALL FIRMWARE LEAGACY,第一个是用于刷pixhawk的…

数据泄露防护:企业如何通过软件限制U盘使用

在数字化办公时代,数据安全已成为企业运营中的一个关键议题。U盘作为一种便携式的数据存储和传输工具,其使用在企业内部非常普遍。然而,U盘的不当使用也可能导致严重的数据泄露问题。本文将探讨企业如何通过软件解决方案,有效限制…

2024 年科技裁员综合清单

推荐阅读: 独立国家的共同财富 美国千禧一代的收入低于父辈 创造大量就业机会却毁掉了财富 这四件事是创造国家财富的关键 全球财富报告证实联盟自始至终无能 美国人已陷入无休止债务循环中,这正在耗尽他们的财务生命 2024 年,科技行业…

告别低效率||智能BI财务分析软件

在当今信息爆炸的时代,财务数据作为企业运营的核心,其处理和分析的效率直接关系到企业的决策速度和市场竞争力。奥威BI软件凭借其卓越的性能和智能化的分析功能,为企业提供了一套高效、准确的财务分析解决方案。 奥威BI软件在财务分析中的优…

行为设计模式之职责链模式

文章目录 概述原理代码实现小结 概述 职责链模式(chain of responsibility pattern) 定义: 避免将一个请求的发送者与接收者耦合在一起,让多个对象都有机会处理请求.将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止. 在职责链模式中&…

【Mybatis】映射文件获取新增记录的id

我们在讲JDBC的时候讲过在插入新数据值的时候需要获得到自动生成的那个主键id的值 ①获取PreparedStatement的对象的时候 PreparedStatement st conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS ); ②在执行SQL语句后 st.executeUpdate();ResultSet rs st.ge…

Springboot项目——博客平台

前言:为巩固之前学习的知识,同时锻炼自己的代码能力,项目经验,熟悉前后端交互方式等,特此完成一个博客平台系统。(总之,为了学习,为了进步) 博客平台:本项目…

QQ名片满级会员装x助手HTML源码

源码介绍 QQ名片满级会员展示生成HTML源码,源码由HTMLCSSJS组成,双击html文件可以本地运行效果,也可以上传到服务器里面,保存素材去选择QQ个性名片-选择大图模板-把图上传照片墙即可 源码效果 源码下载 蓝奏云:http…

如何远程访问Redis?

远程访问Redis是一种常见的需求,特别是在分布式系统或跨地域网络中。通过远程访问,我们可以轻松地对远程的Redis数据库进行操作和管理。 天联保障数据安全 对于远程访问Redis的安全性问题,我们可以借助天联来保障数据的安全。天联是一种基于…

mybatisplus填充公共字段MetaObjectHandler后不生效解决方式

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component;import java.util.Date;/*** 拦截处理公共字…

开发一个comfyui的自定义节点

文章目录 目标功能开发环境comfyui自定义节点的实现原理仓库地址完整代码目标功能 开发一个comfyui的自定义节点,该节点的功能是:可以对comfyui工作流中最终输出的图像添加一些自定义文案,且可以指定文案在图像上的位置、文案的字体样式、字体大小、字体颜色等。最终效果如…

全网讲的最详细的Docker镜像分层存储原理

先说结论,容器镜像分层存储图示 欢迎关注 实验环境准备 当前实验docker版本24.0.7如下,当前docker版本使用overlay2机制存储镜像 Client: Docker Engine - CommunityVersion: 24.0.7API version: 1.43Go version: go1.20.10…

YOLOv8+PyQt5西红柿成熟度检测系统完整资源集合(yolov8模型,从图像、视频和摄像头三种路径识别检测,包含登陆页面、注册页面和检测页面)

西红柿成熟度检测(https://mbd.pub/o/bread/mbd-ZpWbk5ly)_哔哩哔哩_bilibili 资源包含可视化的西红柿成熟度检测系统,基于最新的YOLOv8训练的西红柿成熟度检测模型,和基于PyQt5制作的可视化西红柿成熟度检测系统,包含…

系统思考—战略沙盘推演咨询服务

今日与JSTO团队一起学习了《战略沙盘推演咨询服务》。通过沙盘体验,我深刻感受到组织与战略就像一张皮的正反两面。在转型过程中,即使战略非常明确,团队成员由于恐惧和顾虑,往往不愿意挑战新的业务,从而难以实现战略目…

创新实训2024.05.28日志:记忆化机制、基于MTPE与CoT技术的混合LLM对话机制

1. 带有记忆的会话 1.1. 查询会话历史记录 在利用大模型自身能力进行对话与解答时,最好对用户当前会话的历史记录进行还原,大模型能够更好地联系上下文进行解答。 在langchain chat chat的chat函数中,通过实现langchain框架提供的ChatMemo…

虚拟化技术 分布式资源调度

一、实验内容 实现分布式资源调度 二、实验主要仪器设备及材料 安装有64位Windows操作系统的台式电脑或笔记本电脑,建议4C8G或以上配置已安装VMware Workstation Pro已安装Windows Server 2008 R2 x64已安装vCenter Server 三、实验步骤 将主机esxi1和esxi2加入…

【找出缺失的观测数据】python

思路: 主要在于分配剩余的部分分配问题 代码: class Solution:def missingRolls(self, rolls: List[int], mean: int, n: int) -> List[int]:m len(rolls)total_sum (n m) * meantoset total_sum - sum(rolls)# 检查 toset 是否在可能的范围内i…