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

Create images with a built-in non-root user #1029

Closed
cjvogel1972 opened this issue Sep 24, 2018 · 12 comments
Closed

Create images with a built-in non-root user #1029

cjvogel1972 opened this issue Sep 24, 2018 · 12 comments
Assignees
Milestone

Comments

@cjvogel1972
Copy link

Description of the issue:
Best practices for Docker containers is to run them as a non-root user. As Jib works now, there is no way to specify a built-in non-root user. Google distroless gives an example of how to do this using Bazel.

I saw your answer for issue #631, but that I don't think that limits the security risk. In Docker, you have to remember to add the --user in the run command. You Kubernetes security context answer helps, but it still requires you to remember to set the configuration.

I just think it would be good if the tool gives the option to build the user ID into the image. Just as an example, where I work, neither solution would work because we have security software that inspects the image and prevents its use if there is not a user ID built into the image. I would love to use Jib at work, but until the user ID is baked into the image, it won't be possible.

Expected behavior:
It would be good to add to the jib/to closure an option for specifying a user and group to run the container as.

@coollog
Copy link
Contributor

coollog commented Sep 25, 2018

Hi @cjvogel1972 , thanks for suggesting this and providing the detailed explanation! We'll look into adding this option @GoogleContainerTools/java-tools

We will probably add a <container><user>/jib.container.user parameter that will accept the user/group in the forms Dockerfiles accept currently: user, uid, user:group, uid:gid, uid:group, user:gid

@coollog coollog added this to the 0.10.1 milestone Sep 25, 2018
@patflynn
Copy link
Contributor

@mattmoor any thoughts on this?

@chanseokoh
Copy link
Member

chanseokoh commented Sep 25, 2018

UPDATE: specifying names will work just as much as numbers work; there's no need to translate names to numbers at image build time. Names will be set in the container configuration JSON as-is, and it's a fair game at runtime whether a name works or not, which is also the case with Dockerfile as in the example below. And many times, nobody may be an acceptable user, as almost all Linux distros have it.


I suggest initially we support only numbers, unlike the Dockerfile spec. Almost all the time, supporting names would require modifying /etc/passwd and /etc/group for Unix images, and this also raises the question of which number Jib should assign to. For example,

FROM ubuntu
USER chanseok
CMD ls
$ docker build -t user-test .
$ docker run --rm user-test
docker: Error response from daemon: linux spec user: unable to find user chanseok: no matching entries in passwd file.

One way to make this work with Dockerfile is

FROM ubuntu
RUN groupadd --non-unique --gid 23456 awesomegroup
RUN useradd --non-unique --system --uid 12345 --gid 23456 chanseok
USER chanseok
ENTRYPOINT ["cat", "/etc/group", "/etc/passwd"]

@cjvogel1972
Copy link
Author

Where I work, we run our containers with real generic IDs and groups. And we use the real UID and GID associated with them. We add the information to the image through either useradd/groupadd or by appending the information to /etc/passwd and /etc/group. I agree that starting with numbers would be a good start. However, if you do allow user and group names, there should be a way to specify the UID and GID that go with them.

@ST-DDT
Copy link

ST-DDT commented Oct 2, 2018

A configurable user would indeed be very nice. I need a "fixed" uid because some of my applications need to mount a kubernetes volumes and I have to setup the access privileges according to the user of the docker image (if it is a non root user).

@coollog
Copy link
Contributor

coollog commented Oct 2, 2018

So the current plan will be to add the <container><user>/jib.container.user parameter to only accept user/group ID numbers in the form: uid/uid:gid

Example:

<container>
  ...
  <user>1000</user>
</container>

@chanseokoh chanseokoh self-assigned this Oct 5, 2018
@chanseokoh
Copy link
Member

Should not forget to do something about our Dockerfile generation.

@briandealwis
Copy link
Member

briandealwis commented Oct 5, 2018

Interested people can include custom /etc/passwd and /etc/group as src/main/jib/etc/passwd and src/main/jib/etc/group.

$ docker run -it --rm --entrypoint /busybox/sh gcr.io/distroless/java:debug
/ # cat /etc/passwd
root:x:0:0:user:/home:/bin/bash
/ # cat /etc/group
root:x:0:

@chanseokoh
Copy link
Member

#1109 fixes this. There is no restriction in specifying the user with container.user or <container><user> and there will be no validation. Therefore, names can be used, but you should make sure the name is available in /etc/passwd or /etc/group, for example. you may use a pre-configured base image or use some other tricks (e.g., #1029 (comment)) to update relevant files.

@fzyzcjy
Copy link

fzyzcjy commented Oct 2, 2020

Hi, sorry that I am new to docker and k8s. I wonder what steps to do to follow the security best practices?

My naive thought:

  1. Set <container><user> to some non-root user id.
  2. Create that non-root user, by providing my own base image with things like the following?
RUN groupadd --non-unique --gid 23456 awesomegroup
RUN useradd --non-unique --system --uid 12345 --gid 23456 chanseok
USER chanseok

IMHO the best practice said everywhere is to use non-root user. So jib may have some built-in methods to do so. But I did not find the doc.

Thanks very much!

@chanseokoh
Copy link
Member

chanseokoh commented Oct 2, 2020

@fzyzcjy almost all Linux distros have the nobody "user", so often setting <container><user>nobody will work as a simple configuration. Note that usually nobody doesn't have a home directory, and some applications may not work as expected or to their full potential unless they can write files to the user's home directory (e.g., writing cache files to ~/.cache/...). In that case, you may actually want to find a suitable and usable user in the base image and set <container><user> to that user (and generally speaking, may want to consider mounting a volume in k8s for example, if an application writes something to a disk). Sometimes, you may have to create a new user (for example, a custom base image prepared in advance, or adding /etc/passwd and /etc/group with Jib's <extraDirectories> feature as explained here) to do this.

All in all, choosing and selecting the right user depends on what users are defined in your base image and how your application will work as a non-root user.

@fzyzcjy
Copy link

fzyzcjy commented Oct 3, 2020

@chanseokoh Thanks very much! I will have a try

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

7 participants