0

I am messing around with Docker user namespace remapping: https://docs.docker.com/engine/security/userns-remap/

I have enabled Docker user namespace remapping by modifying /etc/docker/daemon.json. Content currently looks like this:

{
  "userns-remap": "default"
}

I have restarted the Docker daemon. The default dockremap user was created as promised by the docs:

user@host:~$ id dockremap
uid=125(dockremap) gid=134(dockremap) groups=134(dockremap)

There's also an entry in /etc/subuid:

dockremap:165536:65536

Now, I have a folder with a shared file that I wish to bind-mount inside a container to make it available for reading. On the host OS the file has the following owner and permission setup:

-rwxrwx--- 1 dockremap dockremap 0 april 8 19:19 shared_file.txt

The file should NOT be world-writable. My actual intention is to safely share a file with some secret information inside it between the host OS and a container.

The parent directory is world-writable if it makes any difference:

drwxrwxrwx 3 dockremap dockremap 4,0K april 8 19:20 .

I bind-mount this into an Alpine container like so:

docker run --rm -it -w /work -v $(pwd)/shared_file.txt:/work/shared_file.txt remaptest ls -lah

I now expect the file to be owned by root with UID 0 inside the container and thus be available for reading. Instead, it is owned by nobody and not readable by root:

-rwxrwx--- 1 nobody nobody 0 Apr 8 16:19 shared_file.txt

nobody inside the container has the following ids:

/work # id nobody
uid=65534(nobody) gid=65534(nobody) groups=65534(nobody)

Do I have wrong expectations about how user namespace remapping and bind-mount file system permissions work together or are there something wrong here? I have tested this out on two different PCs. One of them running Ubuntu and the other one running Mint.

I also tested with a Ubuntu-based container instead of an Alpine-based one, but the results were pretty much the same. I could of course modify the Dockerfile that is used to build the image, but I am under the impression that the way I'm doing this above should work.

The actual Dockerfile I want to use this with comes from a Docker Hub and I wouldn't want to mess with how it is set up.

fatihyildizhan
  • 8,614
  • 7
  • 64
  • 88
xtrom0rt
  • 183
  • 1
  • 11

1 Answers1

2

Let me start off by saying that in my own very limited experience I have found user namespace mapping to be a particularly tough subject to understand, especially when using docker. I personally feel, like it's almost by design to have wrong expectations. But still it's a powerful tool.

What is happening?

In your case, I'd try mounting $(pwd) into the container as /work (instead of just the file) and run a touch /work/test.txt. On your host you will see that this file is created by a user with uid 165536 whe you run ls -lan $(pwd). This is as stated in your hosts /etc/subuid file, but I agree it's not necessarily what you'd expect.

What can be done?

To address this, I'd change or prepend the mapping in /etc/subuid. For example, you could add a line before dockremap:165536:65536, stating dockremap:125:1. Since the uid of dockremap on your host is 125 and you just want to map this one uid, this line should do the trick.

Now, if you do the touch test again with a new file, you will see that your file is owned by 125 (aka dockremap) on the host and by 0 (aka root) in the container.

Further reading

I can recommend this post: https://www.jujens.eu/posts/en/2017/Jul/02/docker-userns-remap/

Thomas Ebert
  • 447
  • 6
  • 15