Problem
For a docker image (alpine based) that is supposed to run as non-root I have two requirements:
- I have to mount a FUSE filesystem inside the docker container
- The users of the docker image are able to set the UID/GID of the docker
user with
docker run --user {uid}:{gid}
FUSE's fusermount
command requires a valid entry for the user in /etc/passwd
, otherwise it won't mount the filesystem. Given that I don't know the the UID/GID of the user at build time I can't call adduser
at build time. And I can't do it at runtime either, as the user then doesn't have the appropriate privileges.
Solutions found
So far I have found two solutions that both feel not appropriate/secure
1. Make /etc/passwd writable
When adding chmod 555 /etc/passwd
to the Dockerfile I can then do at runtime
echo "someuser:x:${my_uid}:$(id -g)::/tmp:/sbin/nologin" >> /etc/passwd
This does the job for fusermount. Unfortunately I did not find a way to make change the passwd file back to read-only at runtime and without that I have security concerns that someone might be able to misuse this to gain root rights back. While I could not find a simple way to use the open passwd file for some exploit (while I was able to add/modify password & configurations directly in /etc/passwd for all users and then change users via login
, alpine did not allow this for user root (neither via login
nor via su
). But I guess there are folk out there more clever than me, and somehow the whole solution feels like a quite dirty hack. Does anyone have specific ideas how a writeable passwd file inside a container could be used for getting inappropriate rights inside the container?
2. Replace requirement #2 with two additional environment variables
By introducing DUID and DGID as environment variables and set USER to some newly added non-root user inside the Dockerfile I found a solution with the help of sudo & /etc/sudoers: In a launch script that I use as entrypoint I can call sudo adduser/addgroup for the given DUID/DGID and then launch the actual program with the user specified via sudo -u someuser someprog
.
Except for the fact that the whole setup became quite ugly, I disliked the fact the user's of my docker image could no longer use the regular docker run --user
option, as this would break the sudo configuration.