0

We have interesting problem using Dockerfile. We have base image which doesn't have shell (it was removed by security reason) and we can use only Dockerfile directives in our app Docker file. And also we want to run it in the non-root mode.

In the base image we have set of groups with different permissions. For example:

  • g1 - group which has access to /var/log
  • g2 - group which has access to /var/run/docker.sock

These groups are defined in the base image.

I want to have ability to run docker container using non-root user and assign my user to these two groups inside my app container which is based on the base image.

I found that USER directive we can specify user and group which will be used for running container (for example USER app:g1).

Dockerfile looks like this:

# some code before FROM base:1.0 USER app:g1 CMD ["./app"] 

But I want to assign my user to two or more groups inside the Dockerfile of the app image.

Notes I can't modify base image, only the app image. And I have these groups on the host machine.

Notes 2 --group-add flag for docker run is not an option for me, because container is started by some internal software, which I don't manage.

Can I do this? If yes - how?

I tried to specify group names in the USER directive via comma, but it doesn't work (I believe it shouldn't work because it's not documented, I just tried :)).

6
  • I think these are harming and really blocking constraints with no additional security. Can you use COPY in your dockerfile? I want to have ability to run docker container using non-root user I do not follow, inside the container you want to run docker containers, so docker-in-docker? Commented Dec 19, 2022 at 12:21
  • To run container in the non-root mode makes container a little bit safer if someone get access inside the container he/she can make less harm if container is running under non-root user. And access to /var/run/docker.sock is needed to get info about other docker containers which are running on the host. How COPY directive will help me in this case? Commented Dec 19, 2022 at 12:34
  • get info about other docker containers which are running on the host So you do not want to run docker-in-docker, but access the docker outside the container. So are teh groups g1 and g2 inside or outside the container? Do you know them by name or do you know them by gid? How COPY directive will help me in this case? You can COPY busybox and run shell inside. You can COPY prepared /etc/shadow and /etc/groups and change groups inside the container. Do you can use RUN from dockerfile? How is this policy enforced, do you use automated tools? Commented Dec 19, 2022 at 13:01
  • So, these groups g1 and g2 and user app are created on the host OS and inside the base image with same ids (group id and user id). I can't use RUN directive because there is no shell for my app Docker container. I tried using COPY directive to override /etc/shadow and /etc/groups and it works for me like a charm, thanks a lot. Could be some issue with this approach (I mean overriding files) inside the Docker container? One disadvantage which I can see that somebody can easily corrupt /etc/group or /etc/passwd and it would be hard to find the issue. Commented Dec 19, 2022 at 13:59
  • RUN directive because there is no shell for my app Docker Yes, so you can COPY busybox /bin and then RUN busybox any_command and install busybox and have all the commands. Also, not having shell is not really an issue, anyway you can do RUN ["executable", "args"] and execute groupadd or usermod. Could be some issue The issue is the lack of synchronization with base image. I do not understand the sentence with corrupting, it's as easy to corrupt as it was. Copy it with COPY --chown=root:root so it's owned by root. Commented Dec 19, 2022 at 15:08

1 Answer 1

2

Those two directories look like things that you might expect to be bind-mounted from the host. This means you can't specify the user or group IDs in the Dockerfile, since they'll vary depending on the specific host you're running on.

There is a docker run --group-add option that can assign additional groups to the main container process. The linked example suggests the group IDs are looked up in the container's /etc/groups file so you might need to specify numeric group IDs. The non-standard stat(1) command can help you find these

docker run \ -v "$PWD/logs:/var/log" \ -v /var/run/docker.sock:/var/run/docker.sock \ --add-group $(stat -c %g /var/log) \ --add-group $(stat -c %g /var/run/docker.sock) \ ... 

(On my local MacOS system, the BSD stat(1) takes a -f option rather than -c.)

Also consider that, if you have access to the host's Docker socket, you can all but trivially root the entire host (imagine running a new container as root that bind-mounts the host's /etc/shadow file to reset host-root's password, or /etc/crontab to run some command at the next minute boundary). Consider docker run -u 0 to run this container as root as well, which would bypass the other filesystem-permission considerations.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks David. Yes, you're right - it's mounted directories. But I have created users and groups with the same ids on the host and the inside the base image. The thing there that --group-add flag for docker run is not an option for me, because container is started by some internal software, which I don't manage. Is there any other options to assign multiple groups to user?
Dockerfile USER only takes a single group ID, so I don't think there's a way to do this in the image. You also can't guarantee that the specific numeric gids in the image will match the host where it's running, though it's possible to make them match up in individual cases.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.