Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gid and uid to tmpfs long-form mount options a la the current mode support #278

Open
kf6kjg opened this issue Oct 10, 2022 · 4 comments

Comments

@kf6kjg
Copy link

kf6kjg commented Oct 10, 2022

I'm trying to use Docker Compose TMPFS mounts with a non-root user in a DevContainer setup. Since Docker automatically creates and mounts those as root:root this is currently not possible short of utilizing a VERY permissive mode of 0777.

Like #176 added mode, this proposes adding gid and uid. At the very least, add support for gid - since with gid and mode we can create a workable solution to the problem via setting the gid to the target user's group and setting a mode like 0770.

Additional context:

With the following you should be able to launch and attempt to create a file in the tmpfs mount.

version: "3.7"
services:
  demo:
    command: /bin/bash -l
    image: mcr.microsoft.com/vscode/devcontainers/javascript-node:0-16-bullseye
    user: node
    working_dir: /app
    tmpfs:
      - /app/.build
    volumes:
      - type: bind
        source: .
        target: /app

Example steps:

host-os$ docker-compose run demo
node ➜ /app $ touch .build/test
touch: cannot touch '.build/test': Permission denied
node ➜ /app $ ls -la
total 8
drwxr-xr-x 4 node node  128 Oct 10 17:20 .
drwxr-xr-x 1 root root 4096 Oct 10 17:20 ..
drwxrwxrwt 2 root root   40 Oct 10 17:20 .build
-rw-r--r-- 1 node node  278 Oct 10 17:20 docker-compose.yaml

System info:
MacOS 12.4
Docker Desktop v4.12.0

@kf6kjg
Copy link
Author

kf6kjg commented Oct 10, 2022

Ok so this is weird. Tried some extra experiments and got inconsistent results due to what appears to be a bug when using tmpfs in a bind mount:

Test 1: Non-hidden folders mounted two ways:

version: "3.7"
services:
  demo:
    command: /bin/bash -l
    image: mcr.microsoft.com/vscode/devcontainers/javascript-node:0-16-bullseye
    user: node
    working_dir: /app
    tmpfs:
      - /app/tmpfs_demo
    volumes:
      - type: bind
        source: .
        target: /app
      - type: tmpfs
        target: /app/volume_tempfs_demo

Results:

$ docker-compose run demo
node ➜ /app $ ls -la
total 8
drwxr-xr-x 6 node node  192 Oct 10 17:27 .
drwxr-xr-x 1 root root 4096 Oct 10 17:27 ..
drwxr-xr-x 2 root root   64 Oct 10 17:20 .build
-rw-r--r-- 1 node node  342 Oct 10 17:27 docker-compose.yaml
drwxrwxrwt 2 root root   60 Oct 10 17:27 tmpfs_demo
drwxrwxrwt 2 root root   60 Oct 10 17:27 volume_tempfs_demo
node ➜ /app $ touch tmpfs_demo/test
node ➜ /app $ touch volume_tempfs_demo/test
node ➜ /app $ ls -l tmpfs_demo/
total 0
-rw-r--r-- 1 node node 0 Oct 10 17:27 test

Test 2: Hidden and non-hidden folders mounted two ways each

version: "3.7"
services:
  demo:
    command: /bin/bash -l
    image: mcr.microsoft.com/vscode/devcontainers/javascript-node:0-16-bullseye
    user: node
    working_dir: /app
    tmpfs:
      - /app/tmpfs_demo
      - /app/.tmpfs_hidden_demo
    volumes:
      - type: bind
        source: .
        target: /app
      - type: tmpfs
        target: /app/volume_tempfs_demo
      - type: tmpfs
        target: /app/.volume_hidden_demo

Results:

$ docker-compose run demo
node ➜ /app $ ls -la
total 8
drwxr-xr-x 8 root root  256 Oct 10 17:29 .
drwxr-xr-x 1 root root 4096 Oct 10 17:29 ..
drwxr-xr-x 2 root root   64 Oct 10 17:20 .build
drwxrwxrwt 2 root root   40 Oct 10 17:29 .tmpfs_hidden_demo
drwxrwxrwt 2 root root   40 Oct 10 17:29 .volume_hidden_demo
-rw-r--r-- 1 node node  435 Oct 10 17:28 docker-compose.yaml
drwxr-xr-x 2 root root   40 Oct 10 17:29 tmpfs_demo
drwxr-xr-x 2 root root   40 Oct 10 17:29 volume_tempfs_demo
node ➜ /app $ ls -l tmpfs_demo/
total 0
node ➜ /app $ touch tmpfs_demo/test
touch: cannot touch 'tmpfs_demo/test': Permission denied
node ➜ /app $ touch .tmpfs_hidden_demo/test
node ➜ /app $ ls -l .tmpfs_hidden_demo/
total 0
-rw-r--r-- 1 node node 0 Oct 10 17:37 test

Test 3: Same as previous just doing the same thing again

$ ls -la
total 8
drwxr-xr-x 8 node node  256 Oct 10 17:29 .
drwxr-xr-x 1 root root 4096 Oct 10 17:39 ..
drwxr-xr-x 2 root root   64 Oct 10 17:20 .build
drwxr-xr-x 2 root root   40 Oct 10 17:39 .tmpfs_hidden_demo
drwxr-xr-x 2 root root   40 Oct 10 17:39 .volume_hidden_demo
-rw-r--r-- 1 node node  435 Oct 10 17:28 docker-compose.yaml
drwxr-xr-x 2 root root   40 Oct 10 17:39 tmpfs_demo
drwxr-xr-x 2 root root   40 Oct 10 17:39 volume_tempfs_demo
node ➜ /app $ ls -l tmpfs_demo/
total 0
node ➜ /app $ touch tmpfs_demo/test
touch: cannot touch 'tmpfs_demo/test': Permission denied
node ➜ /app $ ls -l .tmpfs_hidden_demo     
total 0
node ➜ /app $ touch .tmpfs_hidden_demo/test
touch: cannot touch '.tmpfs_hidden_demo/test': Permission denied

Observations

This is interesting. It looks like the process works just fine on a fresh folder, but once the host OS has the folder the permissions get mangled.

As a workaround, attempting to set the mode in the volume mount style fails because the engine doesn't yet have support for that option. e.g.:

version: "3.7"
services:
  demo:
    command: /bin/bash -l
    image: mcr.microsoft.com/vscode/devcontainers/javascript-node:0-16-bullseye
    user: node
    working_dir: /app
    tmpfs:
      - /app/tmpfs_demo
      - /app/.tmpfs_hidden_demo
    volumes:
      - type: bind
        source: .
        target: /app
      - type: tmpfs
        target: /app/volume_tempfs_demo
        tmpfs:
          mode: 0777
      - type: tmpfs
        target: /app/.volume_hidden_demo
        tmpfs:
          mode: 0777

Gives

$ docker-compose run demo
services.demo.volumes.1.tmpfs Additional property mode is not allowed

@EricHripko
Copy link
Collaborator

Hi @kf6kjg 👋 Thank you for sharing this idea. Could you clarify what the concern is (if any) with using a permissive 0777 mode?

@kf6kjg
Copy link
Author

kf6kjg commented Oct 16, 2022

Nothing practical considering this is a container, just principles - assuming the permissions of the corresponding file or folder on the host don't get changed. When searching for solutions before I posted here I did run across someone who's company infosec department had a problem with it, but I'm having trouble finding that comment now.

@FlorianHeigl
Copy link

FlorianHeigl commented Aug 23, 2024

maybe we can simply go with assuming that it never works out well if we skip 1990's bastion host security advice?

or, more specifically it's rarely a great thing to leave a world readable/writeable/executable directory around if you don't need one. but the first bit is the more generalized view and the one i'd try to adhere to more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants