[docker] docker 安全知识 - docker api, 权限提升 资源管理

[docker] docker 安全知识 - docker api, 权限提升 & 资源管理

这是 docker 安全的最后一篇

暴露 docker api

在 [docker] docker 安全知识 - docker 系统性简介 中曾经提到,docker cli 使用 restful api 与客户端和 docker daemon 之间交流。默认情况下,docker cli 和 docker api 通过 unix socket /var/run/docker.sock 进行交流,而 docker 引擎在宿主机器上默认是有 root 权限的

crul docker socket

这是之前 curl 的 socket 的结果

docker engine

docker daemon 是核心的 server,server+rest API + client 加起来是 docker engine

在有些情况下,也会遇到需要将 docker api 使用的 socket 暴露到网络上的情况,如:

  • 当容器在不同的宿主机器上运作

    这个情况下则需要 query 其他宿主机器的 docker 情况以便实施下一步操作,特别是容器之间有依赖关系的情况

  • 集中化容器管理

  • CI/CD

  • 监控&日志

在这种情况,其他人就可以通过暴露出来的 docker api 对容器和镜像进行管理,从而获取对 docker daemon 的操作权限——搭配上 docker 引擎是以 root 权限在宿主机器上运作的这一情况,这就意味着可以调用 docker api 的用户有可能通过暴露 docker api,获取 root 权限。这种漏洞叫 特权提升,后面也会有一个部分会专门讲 特权提升 的常见出发点情况

docker 官方文档是对暴露 socket 有警告的:

在这里插入图片描述

毕竟用户通过访问 socket,就有可能获取当前宿主上的文件夹和文件,这也是之前跑有漏洞的镜像时的截图:

在这里插入图片描述

在这个情况下,用户可以访问到 /var/lib/docker 这个路径——虽然在 mac 和 windows 上,这可能是虚拟机所在的位置。不过如果是 linux 服务器的话,那就是服务器所在的位置——再重复一遍,在 linux 环境下,docker 并不会重新创建一个虚拟机,而是会使用宿主机器上的 kernal,从而提升性能

换言之,用户也可以直接访问到 /var 下的文件与文件夹,并借助 docker api,以 root 权限在 /var 下进行操作

不安全的配置

下面会列举几种将 socket 暴露出来的方式

  • docker cli

    sudo dockerd
        -H unix:///var/run/docker.sock
        -H tcp://192.168.59.106:2375
    

    这是一个临时地暴露端口的方法,无法持久化

    执行完该命令后,任何可以访问 192.168.59.106:2375 就可以访问通过 unix:///var/run/docker.sock 暴露的 dockerd

  • 使用 systemd service

    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://192.168.59.106:2375
    

    这个配置和上面的指令一样,不过将其暴露成了一个 service,因此可以持久化

  • 通过 daemon.json

    {
      "hosts": ["unix:///var/run/docker.sock", "tcp://192.168.59.106:2375"],
      "experimental": true,
      "features": {
        "buildkit": true
      }
    }
    

    这是通过 docker daemon 实现的暴露

执行了上面任何一个指令后,就可以监听到被暴露的端口了,运行结果大致如下:

sudo netstat -lntp | grep dockerd
tcp        0      0 192.168.59.106:2375     0.0.0.0:*               LISTEN      8745/dockerd

curl 的结果大体如下:

curl http://192.168.59.106:2375/containers/json | jq
[
  {
    "Id": "8dfafdbc3a40",
    "Names": [
      "/registry-server"
    ],
    "Image": "registry:2",
    "ImageID": "sha256:2d4f4b5309b1e65c4a8b6265ffaecc58b239c89973864a7308bda2c95515c5b2",
    "Command": "/entrypoint.sh /etc/docker/registry/config.yml",
    "Created": 1621859727,
    "Ports": [
      {
        "IP": "0.0.0.0",
        "PrivatePort": 5000,
        "PublicPort": 5000,
        "Type": "tcp"
      }
    ],
    "Labels": {
      "maintainer": "Docker <support@docker.com>"
    },
    "State": "running",
    "Status": "Up 3 hours",
    "HostConfig": {
      "NetworkMode": "default"
    },
    "NetworkSettings": {
      "Networks": {
        "bridge": {
          "IPAMConfig": null,
          "Links": null,
          "Aliases": null,
          "NetworkID": "7ea29fc14125a32c4f66af3c258854d9f72f4961d6903d673b56fbd51581cb1b",
          "EndpointID": "d865b3c89d2f06036a8d53133974be4c809cdc1b667a3b3a0a891f62396e92bd",
          "Gateway": "172.17.0.1",
          "IPAddress": "172.17.0.2",
          "IPPrefixLen": 16,
          "IPv6Gateway": "",
          "GlobalIPv6Address": "",
          "GlobalIPv6PrefixLen": 0,
          "MacAddress": "02:42:ac:11:00:02",
          "DriverOpts": null
        }
      }
    },
    "Mounts": [
      {
        "Type": "bind",
        "Source": "/mnt/registry",
        "Destination": "/var/lib/registry",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
      }
    ]
  }
]

一旦可以被 curl 到,也就代表着可以通过扫描软件扫到端口,之前曾经提到的一个 Nmap 就是这样的工具,其运行结果大体如下:

在这里插入图片描述

如果别人运行了类似的软件去扫对应的网址,那么被暴露的 dockerd 也会显示在这里

这里最好的解决方法当然是不暴露 dockerd,不过如果需求是一定要暴露的话,那么解决方案就是添加安全连接的方式,如使用 SSH/TLS

特权提升

特权提升有两种:

  • 水平提升

    这种情况下,同等级的信息会被获取

    如之前提到的使用 Nmap 去探查被暴露在当前域名上的端口

    另外一个看到过是在钓鱼邮件里看到的案例,比如说钓鱼邮件被 cc 给了群组,群组又有人点击/回复了邮件,那么就通过群组(比如说 hr@example.com 这种常见群组)获取了个人信息

  • 垂直提升 (docker 最常见的问题)

bind mounts

之前在 [docker] 多容器项目 - PHP+MySQL+Nginx+utility containers 案例里比较详细地说明了怎么使用 bind mounts,不在本地安装 php、mysql 实现开发一个 laravel 网站,而这里利用的就是容器修改的文件映射到本地,而本地的修改同样也会映射到容器中

这里就会出现一个问题,一个容器中出现了 bind mounts,那就可能会出现安全隐患。如下面这个案例,容器在运行时没有使用合适的 flag 去传输 secrets,而是暴力的使用 bind mounts 绑定了 secrets:

# 假设可以访问到容器
# 可以看到这里所有的权限都是 root 权限
/app # ls -la /
total 64
drwxr-xr-x    1 root     root          4096 Apr 30 03:52 .
drwxr-xr-x    1 root     root          4096 Apr 30 03:52 ..
-rwxr-xr-x    1 root     root             0 Apr 30 03:52 .dockerenv
drwxr-xr-x    4 root     root           128 Apr 30 03:38 app

# 这个指令可以查看所有的 mounts
/app # cat /proc/mounts
# 省略若干行,注意到这里的 bind mounts
/run/host_mark/Users /app fakeowner rw,nosuid,nodev,relatime,fakeowner 0 0

/app # ls
image.dockerfile  secrets
/app # ls secrets/
id_rsa
/app # cat secrets/id_rsa
some random text

如果这里真的是使用当前的 secrets 去进行登录的话,那么:

  1. 就能够获取 host machine 的登录信息

  2. 可以利用 bind mounts 的特性,新建一个文件,其中包含自己的登录信息

    因为 bind mounts 同样也会反映到宿主机器上去,因此同样的密钥也会被添加到宿主机器

    换言之,现在黑客就能够使用自己的密钥,顺利的登录宿主机器

这种问题,平时在检测的时候也比较容易发现:

  1. 运行时是否使用了 bind mounts,这里通过 -v <绝对路径>:路径 的方式可以检测出来

    # may need to check the file sharing permissiondocker run
    -p 3000:80
    -d
    --rm
    --name feedback-app
    # bind mounts
    # 区别在于这是绝对路径
    -v "$(pwd):/app"
    feedback-node:volumes
    
  2. docker compose 是否绑定了绝对路径

    server:
    image: "nginx:stable-alpine3.17"
    ports:
      - "8000:80"
    volumes:
      # 这两个都是 bind mounts
      - ./src:/var/www/html:delegated
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    

解决方式就比较简单粗暴了——尽量使用 volume 代替 bind mounts

将 docker api 挂载到容器上

这个实现的安全隐患,和第一点暴露 docker api 比较相似,会这么做的主要原因也是为了方便管理,比如说有一个叫做 Portainer 的容器,可以可视化管理 docker 容器,下面是来自官网教程的动图:

在这里插入图片描述

可以看到,如果是一些做未来会交付出去,给非开发进行管理/维护的项目,就可能会使用这种方法——这也是无法避免一定会要使用这种容器的理由。这种情况下,使用 SSH/TLS/VPN 建立安全的登录是最好的防护方式

另一种解决方式是使用 non-root 用户,这里在官方文档也有介绍,这里不多赘述:https://docs.docker.com/engine/security/rootless/

特权容器

类似的我之前跑过:

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

默认情况下,容器是无法访问宿主机的设备(USB, GPU 等),但是使用 --privileged 这个 flag 可以获取这些权限,除此之外还可以挂载文件系统、越过 FS 的权限管理等,除此之外,设备也可以被 map 到容器上去。

对于这个漏洞的检测方式主要有以下几种:

  1. 特权模式,也就是 --privileged flag

  2. 添加 capabilities,也就是 --cap-add=CAPABILITY_NAME flag

    这里包含的 capability 有以下几个选择:

    • SYS_ADMIN,即系统管理
    • NET_ADMIN,即网络管理
    • SYS_TIME,即系统时间
    • SYS_PTRACE, 即 ptrace,可以追踪一些 process
  3. 添加设备,即 --device flag

kernel 漏洞

这个是与 linux 镜像有关的一些漏洞了,具体可以在这个网站上进行查询:https://www.exploit-db.com/

一些漏洞包括:

在这里插入图片描述

在这里插入图片描述

这个就没什么好说的了吧,就是涉及到了底层用的 linux 的漏洞,linux 服务器的话,就和当前的系统有关

资源管理

默认情况下,容器的运行是没有资源限制的,换言之,一个容器很有可能会耗尽当前服务器上所有的资源。以之前提到的一个 package 为例:everything。如果前端容器 不小心 安装了类似的包,那么就会下载 npm registry 上的所有包

这会使用大量的资源,包括带宽和内存。在没有任何限制的情况下,光是前端容器就能够耗尽服务器的资源。当系统内存不够了,就会宕机,这同样也会影响到运行在同样服务器上的其他容器,从而导致整个项目挂掉

限制的方法有:

  • cpu

    • 使用, --cpu-shares=512

    • quota, --cpu-quota=50000

    • 周期, --cpu-period=100000

  • 内存

    • 大小限制, -m 512m
    • swap, --memory-swap=1g
  • IO

    • block, --blkio-weight=500
    • 读写速度, --device-read-bps /dev/sda:1mb --device-write-bps /dev/sda:1mb
  • 带宽, --net=my_bandwidth_limited_network

reference

  • Protect the Docker daemon socket

  • Run the Docker daemon as a non-root user (Rootless mode)

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

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

相关文章

国内的期权模拟账户怎么申请?

国内的期权模拟账户可以在券商和期权分仓平台处申请开通&#xff0c;期权相比于股票具有杠杆投资、风险控制等新特性。 期权模拟交易客户端能够提供期权的开平仓交易、备兑开仓&#xff0f;平仓、行权等交易指令&#xff0c;下文为大家介绍国内的期权模拟账户怎么申请&#xff…

安卓模拟键盘蓝牙电脑apk

蓝牙连接电脑就可以使用了。 下载地址&#xff1a;点击下载https://download.csdn.net/download/jasonhongcn/89382597

【基础算法总结】模拟算法

模拟算法 1.替换所有的问号2.提莫攻击3.Z 字形变换4.外观数列5.数青蛙 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 模拟算法 —> 比葫芦…

npm发布、更新、删除包

如何将自己开发的依赖包发布到npmjs上供别人使用&#xff1f;五个步骤搞定&#xff01; 实现步骤&#xff1a; 创建自己的工具包项目&#xff0c;进行开发。注册npmjs账号。执行npm login在控制台登录&#xff0c;填写用户信息。执行npm publish发布包。更新及删除。 步骤一…

Leetcode - 周赛399

目录 一&#xff0c;3162. 优质数对的总数 I 二&#xff0c;3163. 压缩字符串 III 三&#xff0c;3164. 优质数对的总数 II 四&#xff0c; 3165. 不包含相邻元素的子序列的最大和 一&#xff0c;3162. 优质数对的总数 I 假设 x 是 nums1 数组中的值&#xff0c;y 是 nums2…

Docker部署SiYuan笔记-Unraid

使用unraid的docker部署SiYuan笔记&#xff0c;简单记录 笔记说明 Siyuan笔记是一款基于markdown语法的笔记工具&#xff0c;具有活跃的社区和多设备支持。大部分功能都是免费&#xff0c;源代码开源&#xff0c;支持插件安装&#xff0c;具有很不错的使用体验。 Docker地址&a…

【应用层】 DNS 域名协议解析

文章目录 DNS(Domain Name System)出现及演化 ⏳DNS 概括&#x1f50d;DNS定义DNS 作用 DNS工作原理⚙️域名解析DNS解析的详细工作流程 DNS域名解析方式&#x1f504;静态DNS域名解析动态DNS域名解析 DNS域名解析过程的深入分析 &#x1f9d0;递归查询迭代查询 公共DNS服务器的…

Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明

Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明 目录 Python 机器学习 基础 之 处理文本数据 【停用词/用tf-idf缩放数据/模型系数/多个单词的词袋/高级分词/主题建模/文档聚类】的简单说明…

AI帮写:探索国内AI写作工具的创新与实用性

随着AI技术的快速发展&#xff0c;AI写作正成为创作的新风口。但是面对GPT-4这样的国际巨头&#xff0c;国内很多小伙伴往往望而却步&#xff0c;究其原因&#xff0c;就是它的使用门槛高&#xff0c;还有成本的考量。 不过&#xff0c;随着GPT技术的火热&#xff0c;国内也涌…

Keras深度学习框架实战(3):EfficientNet实现stanford dog分类

1、通过EfficientNet进行微调以实现图像分类概述 通过EfficientNet进行微调以实现图像分类&#xff0c;是一个使用EfficientNet作为预训练模型&#xff0c;并通过微调&#xff08;fine-tuning&#xff09;来适应特定图像分类任务的过程。一下是对相关重要术语的解释。 Effici…

【气象常用】剖面图

效果图&#xff1a; 主要步骤&#xff1a; 1. 数据准备&#xff1a;我用的era5的散度数据&#xff08;大家替换为自己的就好啦&#xff0c;era5数据下载方法可以看这里【数据下载】ERA5 各高度层月平均数据下载_era5月平均数据-CSDN博客&#xff09; 2. 数据处理&#xff1a…

高考试卷押运车视频监控解决方案

一、引言 高考作为我国教育领域的重要事件&#xff0c;其公正、公平和安全性一直备受社会关注。试卷押运作为高考的重要环节&#xff0c;其安全性直接关系到高考的顺利进行和考生的切身利益。因此&#xff0c;对高考试卷押运车实施视频监控解决方案&#xff0c;对于确保试卷安…

【Pr学习】01新建项目起步

【Pr学习】01新建项目起步 1、新建项目2.序列设置2.1新建序列2.2序列参数讲解2.3自定义设置 3.PR窗口认识3.1 项目窗口3.2 源窗口2.4 保存面板 4.剪辑导入4.1 素材导入4.2 视图切换4.3 时间轴4.4轨道工具4.5 节目窗口素材导入 5.基础操作5.1 取消视频音频链接5.2 单独渲染&…

在不受支持的 Mac 上安装 macOS Sonoma (OpenCore Legacy Patcher v1.5.0)

在不受支持的 Mac 上安装 macOS Sonoma (OpenCore Legacy Patcher v1.5.0) Install macOS on unsupported Macs 请访问原文链接&#xff1a;https://sysin.org/blog/install-macos-on-unsupported-mac/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主…

Hugging Face称检测到对其人工智能模型托管平台的“未经授权访问“

周五下午晚些时候&#xff0c;人工智能初创公司Hugging Face表示&#xff0c;其安全团队在本周早些时候检测到对Spaces的"未经授权访问"&#xff0c;Spaces是Hugging Face用于创建、共享和托管人工智能模型和资源的平台。 Hugging Face 在一篇博文中说&#xff0c;这…

intel深度相机D455的使用

一、D455介绍 Intel RealSense D455 是RealSense D400系列的一部分&#xff0c;这个系列的设备以其高精度和可靠性而闻名。D455相比于之前的型号&#xff08;如D415和D435&#xff09;&#xff0c;提供了更远的感知范围和更高的精度。 二、使用代码 我们先定义一下相关的函数…

深入理解Java中的List集合:解析实例、优化技巧与最佳实践

一&#xff1a;List 集合的基础 1.1 什么是 List 集合&#xff1f; List 集合是 Java 集合框架中的一种有序、可重复的数据结构&#xff0c;它继承自Collection 接口&#xff0c;允许存储多个元素。 与数组不同&#xff0c;List 集合的大小是动态可变的&#xff0c;可以根据…

Elasticsearch:基于多个 kNN 字段对文档进行评分

作者&#xff1a;来自 Elastic Madhusudhan Konda 通过具有多个 kNN 字段的最接近的文档对文档进行评分 Elasticsearch 不仅仅是一个词法&#xff08;文本&#xff09;搜索引擎。 Elasticsearch 是多功能搜索引擎&#xff0c;除了传统的文本匹配之外&#xff0c;还支持 k 最近…

海外高清短视频:四川京之华锦信息技术公司

海外高清短视频&#xff1a;探索世界的新窗口 在数字化时代的浪潮下&#xff0c;海外高清短视频成为了人们探索世界、了解异国风情的新窗口。四川京之华锦信息技术公司这些短视频以其独特的视角、丰富的内容和高清的画质&#xff0c;吸引了无数观众的目光&#xff0c;让人们足…

DI-engine强化学习入门(一)使用强化学习模型控制月球着陆器

控制程序观前提醒&#xff1a;本章内容为训练一个强化学习模型&#xff0c;并使用强化学习模型控制月球着陆器。安装和运行DI-engine示例。 什么是DI-engine? DI-engine 是一个由 OpenDILab 提供的开源强化学习&#xff08;Reinforcement Learning&#xff0c;简称RL&#xf…