3

In a self-built Docker container, I want/need to run applications under a specific UID and GID. Trying to use a UID:GID pair that does not exist on the host fails.


Remarks

  • the intended UID:GID(s) do not necessarily exist on the Docker host/ namespace
  • Kernel and dockerd run with user namespaces enabled
  • UID:GID are dictated by hard external requirements, e.g., 26551:1000
  • target UID:GID in the container should not depend on UIDs:GIDs on the host
  • my build user, i.e., my own 'desktop user', has UID:GID = 1000:1000
  • for user namespaces subuid & subgid are within 10000:14095

Minimal demo example: Setup and preparation

Dockerfile: User Creation

Thus, I started to create a user in the container's Dockerfile (ARG+ENV for easier triggering new build stages) - here as 26551:1000 including creating a ${HOME} dir

ARG USERID=26551
ENV runUID=${USERID}
ARG GROUPID=1000
ENV runGID=${GROUPID}
ARG USERNAME='testuser'
ENV runUSER=${USERNAME}
ARG groupNAME='testgroup'
ENV runGROUP=${groupNAME}

RUN groupadd -g ${runGID}  ${runGROUP} && \
    useradd -u ${runUID} -g ${runGID} -ms /bin/bash ${runUSER}  

docker build

As I need to inject sensitive information during the build, I am running with BuildKit

> DOCKER_BUILDKIT=1  docker build  --secret id=foo_file,src=secret/foo.file --progress=plain  . -t testfoo:latest

container context

Navigating in the image as interactive container, the ${HOME} dir belongs to a UID:GID from my 'host-user''s subuid:subgid range

[root@e436d2050f67 /]# grep testuser /etc/passwd
testuser:x:26551:26551::/home/testuser:/bin/bash

[root@e436d2050f67 /]# ls -all /home
total 0
drwxr-xr-x. 1 root  root   16 Aug 16 13:40 .
drwxr-xr-x. 1 root  root  248 Aug 16 13:51 ..
drwx------. 1 12455 12455  64 Aug 16 13:40 testuser

which might be fair enough, as I do not really need ${HOME} (although I wonder how this would work out on other hosts with different subuid/subgid ranges?)


The problem

Switching users does not work

The problem is that, although the user exists in the container's passwd etc. I cannot switch to it; neither via chroot or su(do):

[root@e436d2050f67 /]# chroot --userspec=1000:26551 / id
chroot: failed to set group-ID: Invalid argument

However, switching to my 'host-user' works

[root@e436d2050f67 /]# chroot --userspec=1000:1000 / id
uid=1000 gid=1000 groups=1000

although I have not defined the user in the container but only dockerd would map the UID:GID.

I already tried gosu as alternative but the behaviour is the same, i.e. the user does not 'exist' in the container/the host.

[root@e436d2050f67 /]# gosu 26551:26551 id
error: failed switching to "26551:26551": invalid argument
[root@e436d2050f67 /]# gosu 1000:1000 id
uid=1000 gid=1000 groups=1000

Docker --user

Running the container under a given user fails as again the UID does not exist on the host

> docker run --user=26551 -it testfoo:latest /bin/bash
docker: Error response from daemon: OCI runtime create failed: container_linux.go:345: starting container process caused "setup user: cannot set uid to unmapped user in user namespace": unknown.

Question

How can I run a process in a container under a UID that does not exist on the host, perhaps by mapping the container UID:GID to some subuid:subgid available on the host?


Addendum #1

  • SELinux is disabled
  • the issue seems to be related to what user:groups are actually available in the container

while I have not been able to switch with su or gosu to one of the users/groups defined/created in the container build, I could switch to my host user's UID:GID in the container

[root@5e5137b95434 /]# gosu nobody id
uid=99(nobody) gid=99(nobody) groups=99(nobody)

[root@5e5137b95434 /]# su --group=99 testuser id
su: group 99 does not exist
[root@5e5137b95434 /]# su nobody id
This account is currently not available.

[root@5e5137b95434 /]# su --group=120000 testuser id
su: group 120000 does not exist

[root@5e5137b95434 /]# gosu 26551:26551 id
error: failed switching to "26551:26551": invalid argument

[root@5e5137b95434 /]# cat /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:
adm:x:4:
tty:x:5:
disk:x:6:
lp:x:7:
mem:x:8:
kmem:x:9:
wheel:x:10:
cdrom:x:11:
mail:x:12:
man:x:15:
dialout:x:18:
floppy:x:19:
games:x:20:
tape:x:33:
video:x:39:
ftp:x:50:
lock:x:54:
audio:x:63:
nobody:x:99:
users:x:100:
utmp:x:22:
utempter:x:35:
input:x:999:
systemd-journal:x:190:
systemd-network:x:192:
dbus:x:81:
testgroup:x:26551:

switching to host user, which is not explicitly defined in the container

[root@5e5137b95434 /]# gosu 1000:1000 id
uid=1000 gid=1000 groups=1000
[root@5e5137b95434 /]# gosu 1000:1000 whomai
error: exec: "whomai": executable file not found in $PATH
[root@5e5137b95434 /]# gosu 1000:1000 echo "testfooout" > /home/testuser/1000_1000

> host > ls -all /tmp/foo/1000_1000 
-rw-r--r-- 1 120000 120000 11 Aug 21 10:02 /tmp/foo/1000_1000
> host > id
uid=1000(hartlocal) gid=1000(hartlocal) groups=1000(hartlocal),10(wheel),969(docker)

[root@5e5137b95434 /]# gosu 1000:1000 sleep 600

> host > cat /proc/5737/cmdline 
sleep600
> host > ls -all /proc/5737/cmdline 
-r--r--r-- 1 121000 121000 0 Aug 21 10:04 /proc/5737/cmdline
2
  • 1
    Is blog.dbi-services.com/… discussing the issue you bring up in the question? I'm not quite sure if that discussion fits this problem... – jstarek Aug 20 '19 at 10:03
  • 1
    thanks - but I am already adding a dedicated user (UID/GID) in the build. However, I ttill do not manage to switch the user in the container even when created as home-less system-account. An issue might be that su (& sudo? all binaries running with setuid ) seem to check that the binary belongs to '0' - which might clash in such cases. No idea, how to do user switching then in the container – THX Aug 20 '19 at 13:26
1

answering to my problem

I had not enough subuids/subgids defined for the user namespace.

before

/etc/subuid
/etc/subgid
  dockeruser:120000:10000

and I created an user in the container with UID=26551 - where 26551 lies not within [120000,120000+10000] and thus switching to that user failed.

fix

extending the subuid and subgid range to [200000,200000+100000] and actually include the UID

/etc/subuid
/etc/subgid
  dockeruser:200000:100000

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.