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.
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
@mattmoor any thoughts on this?
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 For example,/etc/passwd and /etc/group for Unix images, and this also raises the question of which number Jib should assign to.
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"]
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.
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).
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>
Should not forget to do something about our Dockerfile generation.
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:
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., https://github.com/GoogleContainerTools/jib/issues/1029#issuecomment-427491999) to update relevant files.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:
<container><user> to some non-root user id.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!
@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.
@chanseokoh Thanks very much! I will have a try
Most helpful comment
1109 fixes this. There is no restriction in specifying the user with
container.useror<container><user>and there will be no validation. Therefore, names can be used, but you should make sure the name is available in/etc/passwdor/etc/group, for example. you may use a pre-configured base image or use some other tricks (e.g., https://github.com/GoogleContainerTools/jib/issues/1029#issuecomment-427491999) to update relevant files.