docker-iojs icon indicating copy to clipboard operation
docker-iojs copied to clipboard

Run as a non-privileged user by default

Open pesho opened this issue 10 years ago • 10 comments

This is a proposal for resolving #23. It does two things:

  1. A non-privileged user called app is created in all images. The user is explicitly created with high uid and gid, in order to make collisions with the host improbable.
  2. The default CMD commands are changed to execute as app instead of root (using su -c ...). This matters most for onbuild, which is most likely to use the default command, but is also useful in the other variants (as an example for proper invocation).

I decided not to use USER app for changing the user, because that would have unwanted side effects and would likely break many derivative images. For example, derivatives would have to change back to USER root in order to install additional distro packages.

There is one caveat with this change. Apps can no longer write inside their src directory by default (as it is owned by root). IMHO this is a feature, not a bug - apps should not be able to modify their own source. They should use /home/app for storage instead, or a volume, or another location with explicitly set permissions.

pesho avatar Feb 11 '15 14:02 pesho

/cc the Docker team as well @tianon @yosifkit @jfrazelle

pesho avatar Feb 11 '15 14:02 pesho

// CC @rvagg

There is one caveat with this change. Apps can no longer write inside their src directory by default (as it is owned by root)

When you refer to their source directory, are you referring to /usr/src/app in the ONBUILD container? Would it be safe to have the new app user take ownership of that folder?

retrohacker avatar Feb 11 '15 15:02 retrohacker

hmmm maybe take a look at https://github.com/jfrazelle/irssi for a good way to run as another user, I know personally I'm not a fan of su for CMD, but that's not to say someone from docker might disagree with me :) and like it

jessfraz avatar Feb 11 '15 18:02 jessfraz

While I'm definitely +1 with trying to run as a different user whenever possible, "su" has very odd characteristics that make it generally unsuitable for the task -- for one, it stays resident (so our actual process will be a child of "su", which screws up signals), and for another it does strange things with the TTY.

I'm still in the camp that this probably isn't something we can do automatically for users of language stacks in the general case, and that documenting how to appropriately use USER in a dependent Dockerfile is going to be a more robust solution.

tianon avatar Feb 11 '15 18:02 tianon

The biggest problem I see is for developers. Unless they chmod all their code world readable the container will not be able to read the files. There could be an entrypoint script that chowns or chmods the files to the correct user, but then that hurts users that are bind mounting their code as they would be unable to edit it (or forced to have world readable). I am really with @tianon, that this is a docs problem (https://github.com/joyent/docker-node/issues/1#issuecomment-71889626).

yosifkit avatar Feb 11 '15 18:02 yosifkit

+1 for the solution from @jfrazelle The modification could be (for the onbuild Dockerfile): (edited because it seems COPY cannot set rights on files copied, let me know if I'm wrong)

FROM iojs:1.2.0
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

+ENV HOME /home/user

+RUN useradd --create-home --home-dir $HOME user \
+    && chown -R user:user /usr/src/app

ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app
+ ONBUILD RUN chown -R user:user /usr/src/app
+ ONBUILD USER user

CMD [ "npm", "start" ]

And so the container can read and write the files. @yosifkit

I would prefer make things easier (and by default) for users to run securely application instead of having to dig in the documentation to know how to do it. @tianon

mtparet avatar Feb 14 '15 17:02 mtparet

I think the hardest part here is that this still doesn't cover the developer that wants to bind mount in their code so that they can edit it on their host machine and see changes as they develop using something like node-supervisor (ex: docker run -it --rm -v /my/code:/usr/src/app my-node). That way they do not have to docker stop, docker build, and docker run for every change.

yosifkit avatar Feb 16 '15 18:02 yosifkit

I have another concern: in some secure conscious environment the system administrator remains the only user who is granted access to the docker commands.

The administrator can't keep up with reviewing the changes in the Dockerfiles. So he always runs the containers with a non-root user and enforces that on the command-line: docker run --user app ....

In my case the app user is not granted access to chown and chmod as enforced by SELinux on Redhat.

So I would not be able to take advantage of this image.

Is this something we can address here?

hmalphettes avatar Apr 21 '15 06:04 hmalphettes

For the :onbuild image I think we could chown /usr/src/app to the app user, and let it be up to the person starting the container if they want to run it as --user app or default root (both should work in this case). I do not think it should create any problems for those who wish to continue to run their containers as root. I'll give it a try when I get the time.

Starefossen avatar Apr 21 '15 06:04 Starefossen

@Starefossen ok got it. Thanks.

hmalphettes avatar Apr 21 '15 07:04 hmalphettes