Docker容器中的用户和文件权限configuration(docker-compose版本3)
Docker 声明它的容器是
“…默认情况下是非常安全的;特别是如果你照顾在容器内运行你的进程作为非特权用户(即非root)”
因此,我试图:
- 使用适当处理用户执行的官方图像
- 避免在生产中安装主机卷,并使用
COPY
当我将代码和configuration文件复制到容器卷中时,所有目录和文件都将创build为“… UID和GID为0”(根拥有者),如文档中所述。
问题:如果文件和目录由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
如果是这样,我想知道如何(以及在哪里)正确chown
和chmod
我的文件。 从我的研究来看,如果你使用的是docker-compose,那么这看起来就不那么简单了 – 我正在使用docker-compose YAML文件(版本3)和容器特定的Dockerfiles。 看起来,当我在一个容器的Dockerfile结尾时,变化不会生效 – 可能是因为在之后创build了卷(在docker-compose.yml中定义)。 以下是两种configuration的片段:
泊坞窗,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版本,很难对各种networking文章,错误修复以及围绕此主题的function请求进行sorting。 我希望在这里得到一些明确的方向/答案,面向docker构成版本3。
问题:如果文件和目录由root拥有,但是运行的进程是由非root用户拥有,如www-data,那么是否仍然存在安全风险?
不是真的。 你可能只需要确保php-fpm已经读取了这些文件的权限。
您正在将/var/www/html
的内容复制到映像中,并在构build时设置所有权/权限(Dockerfile)。 还行吧。 这是创build图像的通常用例。
但是你docker-compose.yml
挂载到正在运行的容器中,从图像中取代/var/www/html
。 所以,无论你在那个目录中都会隐藏起来。 您将看到安装的音量的内容。
您可能想要select持续存储容器数据所需的策略。 在构build时/var/www/html
在大多数情况下可能是可以的。 但是,如果您的应用程序在该目录中的某个位置写入数据,那么您可能会考虑更改该path。 当容器被销毁时,任何写入外挂的数据将会丢失。 所以,请确保yoru应用程序写入从docker-compose.yml
作为卷挂载的目录。
docker中的命名卷将被初始化为映像的挂载点的内容。 之后,除非音量完全没有,否则初始化步骤不会再次运行以避免数据丢失。
所以当你第一次创builddata_volume
指向/var/www/html
,它获得了该目录的一个副本,包括文件权限。 但是,除非您删除或清空data_volume
,否则对data_volume
任何更改都只会更新映像,并且卷将使用该卷的内容覆盖该目录。
如果您不需要data_volume
的内容, data_volume
可以通过data_volume
docker-compose down -v
同时删除容器和卷。 然后,再次运行docker-compose up -d
时,将使用具有新权限的文件创build卷。
如果您确实需要保留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
显示的卷名replace$(basename $(pwd))_data_volume
。 从上面的容器中,你可以运行你的find
命令来更新所有权和权限。