简体   繁体   中英

User and file permission configuration in Docker containers (docker-compose version 3)

Docker states that its containers are

"...by default, quite secure; especially if you take care of running your processes inside the containers as non-privileged users (ie, non-root)"

As a result, I've tried to:

  1. Use official images that handle user execution appropriately
  2. Avoid mounting host volumes in production, and using COPY instead

When I COPY code and configuration files to my container volumes, all of the directories and files are created "...with a UID and GID of 0" (root ownership), as stated in the documentation here .

Question: Are there still security risks if the files and directories are owned by root but the running process is owned by a non-root user, like www-data ? For example, with 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

If so, I'm wondering how (and where) to correctly chown and chmod my files. From my research, this seems less straightforward if you're using docker-compose, which I am - I'm using both a docker-compose YAML file (version 3) in conjunction with container-specific Dockerfiles. It seems that when I chown at the end of a container's Dockerfile, the changes don't go into effect - probably because the volume (which is defined in docker-compose.yml) is created afterwards. Here's some snippets of both configurations:

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 {} \;

With the different docker-compose versions, it's hard to sort through the various web articles, bug fixes, and feature requests surrounding this topic. I'm hoping to get some definitive direction/answers here, geared toward docker-compose version 3.

Question: Are there still security risks if the files and directories are owned by root but the running process is owned by a non-root user, like www-data?

Not really. You might just need to make sure that php-fpm has read permission to these files.

You are copying the contents of /var/www/html into the image and setting ownership/permissions at build time (Dockerfile). This is OK. That's the usual use case for creating images.

But your docker-compose.yml mounts data_volume into the running container, replacing the /var/www/html from the image. So, whatever you had in that directory will be hidden. You will see the contents of the mounted volume, instead.

You might want to choose what strategy you need to persist container data. Populating /var/www/html at build time is probably OK for most of the time. But, if your application writes data somewhere in that directory, then you might consider changing that path. When the container is destroyed, any data written to outisde mounted volumes will be lost. So, make sure yoru app writes to a directory that is mounted as a volume from docker-compose.yml .

Named volumes in docker are initialized to the contents of the image at their mount point. After that, unless the volume is completely empty, that initialization step is never run again to avoid data loss.

So when you first created data_volume pointing to /var/www/html , it got a copy of that directory, including the file permissions. But unless you delete or empty the data_volume , any changes you make to the Dockerfile will only update the image and the volume will overlay that directory with the contents of the volume.

If you don't need the contents of data_volume , you can docker-compose down -v to both remove the container and the volumes. Then when you run docker-compose up -d again, the volume will be created with the files with the new permissions.

If you do need the contents of data_volume to be preserved, then you can mount the volume and run the commands on the volume itself:

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

The above assumes you are in the same folder as your docker-compose.yml and the directory is all lower case characters. Otherwise, replace $(basename $(pwd))_data_volume with the volume name shown in docker volume ls . From inside the above container, you can run your find commands to update ownership and permissions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM