Ad-hoc file permission change between docker container and host

In this guide, I want to show how you can modify any docker image so that file permissions of file inside a volume can be modified ad-hoc.

Problem: Almost all docker containers have the default file permission of 644 (-rw-r--r--)

  • owner: read and write
  • group: read
  • other: read

Solution: With the help of the deb package inotify-tools (https://github.com/inotify-tools/inotify-tools/wiki) we can monitor filesystem events. With the integrated inotifywait (https://www.man7.org/linux/man-pages/man1/inotifywait.1.html) shell-command we can build a small script that is watching the connected volume inside the container and if files gets "moved in" or "created" inside this folder a chmod 666 is applyed the these files.

Thus, the privileges of the "moved in" or "created" files can be effectively escalated.

In the following example I am using the docker base image: php:apache

version: "3.7"
services:
  web-server:
    build: 
      context: .
      dockerfile_inline: "FROM php:apache\nRUN apt-get update && apt-get install -qqy inotify-tools && apt-get clean autoclean && apt-get autoremove --yes &&  rm -rf /var/lib/{apt,dpkg,cache,log}/\nRUN echo '#!/bin/sh' > /perm.sh && echo 'inotifywait -q -m -e create --format \"%f\" /var/www/test | while read FILENAME' >> /perm.sh && echo 'do' >> /perm.sh && echo '   chmod 666 /var/www/test/$$FILENAME' >> /perm.sh && echo 'done' >> /perm.sh && chmod +x /perm.sh"
    command: sh -c "/bin/sh /perm.sh | apache2-foreground"
    restart: always
    volumes:
      - "/host/test-folder:/var/www/test/"
    ports:
      - "9999:80"

The magic happens inside the long docker_inline command inside the docker-compose.yml.

  • FROM php:apache\n:

    With this command we are setting the docker base image

  • RUN apt-get update && apt-get install -qqy inotify-tools && apt-get clean autoclean && apt-get autoremove --yes && rm -rf /var/lib/{apt,dpkg,cache,log}/\n:

    With this part of the command we are installing inotify-tools inside the docker base image (php:apache)

  • RUN echo '#!/bin/sh' > /perm.sh && echo 'inotifywait -q -m -e create --format \"%f\" /var/www/test | while read FILENAME' >> /perm.sh && echo 'do' >> /perm.sh && echo ' chmod 666 /var/www/test/$$FILENAME' >> /perm.sh && echo 'done' >> /perm.sh && chmod +x /perm.sh:

    With the last part of the docker_inline command we are creating a small sh script (/perm.sh) with the following content:

    #!/bin/sh
    inotifywait -q -m -e create --format "%f" /var/www/test | while read FILENAME
    do
      chmod 666 /var/www/test/$FILENAME
    done

    Please edit the path /var/www/test inside the docker_inline command if you have mounted the volume to another place inside the docker container.

Now with the command: sh -c "/bin/sh /perm.sh | apache2-foreground" command we are starting the /perm.sh script and the apache-webserver at the same time inside the docker container. If you are not using the base image php:apache you need to change apache2-foreground command with the last command inside the docker base image.

You can find a list of all layers inside of a docker base image if you search the docker hub If you have found your image click on the "Tags"-View and click on the tag you are using (In my example apache https://hub.docker.com/layers/library/php/apache/images/sha256-3dd4df7bdf81a042b2f93bf582c7a98f54fd14b7ab7976e3d6e7fef03af73a8c?context=explore

Now you see all layers of the specific base image. In my example the last layer command is CMD ["apache2-foreground"] and so I have used apache2-foreground command inside the docker-compose.yml If the last layer in the docker base image is a ENTRYPOINT command please replace command: sh -c "/bin/sh /perm.sh | ........" with entrypont: sh -c "/bin/sh /perm.sh | ........" in the docker-compose.yml

Previous Post Next Post

Add a comment