[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 权限的

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

这是之前 curl 的 socket 的结果

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

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 有警告的:

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

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

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

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

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

不安全的配置

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

  • docker cli

    ❯  安装了类似的包,那么就会下载 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

06-01 19:22