4

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, 2019 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, 2019 at 13:26

1 Answer 1

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
1
  • I'm facing this same issue right now. How does 26551 fall between the range 200000 - 300000?
    – hakskel
    Aug 4 at 14:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .