【问题标题】:User and file permission configuration in Docker containers (docker-compose version 3)Docker 容器中的用户和文件权限配置(docker-compose 版本 3)
【发布时间】:2017-10-09 14:00:21
【问题描述】:

Docker states 它的容器是

"...默认情况下,非常安全;特别是如果您注意在 容器作为非特权用户(即非 root)”

因此,我尝试了:

  1. 使用适当处理用户执行的官方图像
  2. 避免在生产中挂载主机卷,而是使用COPY

当我 COPY 将代码和配置文件添加到我的容器卷时,所有目录和文件都创建为“...UID 和 GID 为 0”(root 所有权),如文档 here 中所述.

问题: 如果文件和目录由 root 拥有,但正在运行的进程由非 root 用户拥有,例如www-data,是否仍然存在安全风险?例如,php-fpm:

root@7bf71145c18c:/var/www/html# ls -l
total 1220
-rw-rw-r-- 1 root root    5931 May 10 12:28 index.php
drwxrwxr-x 3 root root    4096 May 10 12:28 logs
-rw-rw-r-- 1 root root      28 May 10 12:28 robots.txt

root@7bf71145c18c:/var/www/html# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 14:14 ?        00:00:00 php-fpm: master process (/usr/lo
www-data     5     1  0 14:14 ?        00:00:00 php-fpm: pool www
www-data     6     1  0 14:14 ?        00:00:00 php-fpm: pool www
root         7     0  0 14:19 ?        00:00:00 bash
root        12     7  0 14:19 ?        00:00:00 ps -ef

如果是这样,我想知道如何(以及在​​哪里)正确地 chownchmod 我的文件。根据我的研究,如果您使用的是 docker-compose,这似乎不那么简单,我正在使用 docker-compose YAML 文件(版本 3)和特定于容器的 Dockerfile。似乎当我在容器的 Dockerfile 末尾chown 时,更改不会生效 - 可能是因为卷(在 docker-compose.yml 中定义)是之后创建的。以下是两种配置的一些 sn-ps:

docker-compose.yml:

version: '3'
services:
  fpm:
    build: ./fpm
    container_name: "fpm"
    volumes:
      - data_volume:/var/www/html
    ports:
      - "9000"
    restart: always
volumes:
  data_volume:

./fpm Dockerfile:

FROM php:7-fpm
RUN mkdir -p /var/www/html/
COPY . /var/www/html/
RUN find /var -exec chown www-data:www-data {} \;
RUN find /var -type d -exec chmod 755 {} \;
RUN find /var -type f -exec chmod 644 {} \;

使用不同的 docker-compose 版本,很难对围绕该主题的各种网络文章、错误修复和功能请求进行分类。我希望在这里得到一些明确的方向/答案,面向 docker-compose 版本 3。

【问题讨论】:

    标签: docker permissions docker-compose file-permissions user-permissions


    【解决方案1】:

    问题:如果文件和目录仍然存在安全风险 由root拥有,但正在运行的进程由非root用户拥有, 喜欢 www-data?

    不是真的。您可能只需要确保 php-fpm 对这些文件具有读取权限。

    您正在将/var/www/html 的内容复制到映像中,并在构建时设置所有权/权限(Dockerfile)。还行吧。这是创建图像的常见用例。

    但是您的 docker-compose.ymldata_volume 挂载到正在运行的容器中,替换图像中的 /var/www/html。因此,您在该目录中的任何内容都将被隐藏。相反,您将看到已安装卷的内容。

    您可能需要选择持久化容器数据所需的策略。在大多数情况下,在构建时填充 /var/www/html 可能是可以的。但是,如果您的应用程序在该目录的某处写入数据,那么您可能会考虑更改该路径。当容器被销毁时,任何写入外部挂载卷的数据都将丢失。因此,请确保 yoru 应用程序写入从docker-compose.yml 挂载为卷的目录。

    【讨论】:

    • 您的解释帮助我意识到容器不需要卷;源代码和配置可以在创建时直接复制到镜像中(在 Dockerfiles 中)。那时我还可以设置文件所有权和权限。但是,对于版本 3,将数据(和设置权限)复制到共享的命名卷中的最佳方式是什么?我的 nginx 和 php 容器需要访问相同的文件和文件夹,我不想将相同的数据复制两次到两个不同的图像中。
    • 是的,如果你想在容器之间共享数据,卷是标准的。您还可以从专门用于该任务的其他容器创建和管理卷。您能否更具体地说明共享的内容?
    • 都是服务器端的 PHP 代码。根据我的阅读,PHP 代码只需要被 php-fpm 容器访问,但我发现我的 nginx 容器也需要访问它,否则我会得到 404。
    • joantune(2 月 16 日)在github.com/docker/compose/issues/4379 的解释似乎适用于我的情况。命名卷(在容器中实例化时)将复制原始图像中该路径中任何内容的所有内容(对我来说更重要的是权限)。然后,任何其他容器都可以访问命名卷中的内容。不过,尚不清楚这是否是命名卷的预期用例。我觉得有点好笑。为了安全起见,我现在可能会恢复到 docker-compose 版本 2.1 并使用 volumes_from,因为我没有利用 swarms
    【解决方案2】:

    docker 中的命名卷在其挂载点初始化为映像的内容。之后,除非卷完全为空,否则将不再运行该初始化步骤以避免数据丢失。

    因此,当您第一次创建指向/var/www/htmldata_volume 时,它会获得该目录的副本,包括文件权限。但除非您删除或清空 data_volume,否则您对 Dockerfile 所做的任何更改都只会更新映像,并且卷将使用卷的内容覆盖该目录。

    如果您不需要data_volume 的内容,您可以docker-compose down -v 同时删除容器卷。然后当您再次运行docker-compose up -d 时,将使用具有新权限的文件创建卷。

    如果您确实需要保留 data_volume 的内容,那么您可以挂载卷并在卷本身上运行命令:

    docker run -it --rm -v $(basename $(pwd))_data_volume:/var/www/html busybox
    

    以上假设您与 docker-compose.yml 位于同一文件夹中,并且该目录全为小写字符。否则,将$(basename $(pwd))_data_volume 替换为docker volume ls 中显示的卷名。在上述容器中,您可以运行 find 命令来更新所有权和权限。

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 1970-01-01
      • 2019-11-14
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      • 2021-03-29
      • 2020-09-24
      • 2019-04-14
      相关资源
      最近更新 更多