1

I'd like to either use su or sudo -u to switch users to the subuid created by LXC to run a container as unprivileged.

Note:

  • There is no username assigned to the UIDs in which containers are run.
  • Due to the above, I need to be able to switch purely by UID.

I've tried doing as this post instructed, but I get the following:

[user@laptop user]# sudo -u \#100000 id
sudo: unknown user #100000

If It's somehow helpful:

  • I'm using Arch Linux
  • I'm using LXD to manage to container(s)

Does anyone know if there is a way to do this, even if via another command or method?

2 Answers 2

0

As asked in question's body

I'd like to either use su or sudo -u to switch users to the subuid

even if via another command or method?

The setpriv command, part of util-linux is documented as:

In comparison to su(1) and runuser(1), setpriv neither uses PAM, nor does it prompt for a password. It is a simple, non-set-user-ID wrapper around execve(2), and can be used to drop privileges in the same way as setuidgid(8) from daemontools, chpst(8) from runit, or similar tools shipped by other service managers.

So it must be run as root (prepend sudo if needed):

root# setpriv --reuid 100000 id
uid=100000 gid=0(root) groups=0(root)
user$ sudo setpriv --reuid 100000 id
uid=100000 gid=0(root) groups=0(root)

This command has other complementary uses. For example it can also change the capabilities sets of the process.


As asked in question's title

Switch user to subuid running LXC container

Can be done as it's done for a running container: with an user namespace and some help.

One can use the actual underlying setuid-root helper allowing a normal user to run containers: newuidmap (and newgidmap), part of package uidmap which is recommended by packages lxc, lxd or any container technology for non-root users.

$ newuidmap -h 
usage: newuidmap <pid> <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ...

The value 100000 must be part of a range defined in /etc/subuid for the invoking user, even if the user is root: don't use sudo. This part is all done without root privilege (thanks to newuidmap being setuid-root).

So assuming the value 100000 is part of a range defined for the user user in /etc/subuidmap (resp. /etc/subgidmap) one can the run these two parts (using for example two terminals), one can map the user as root and also map 100000 as the current user: user will become root and will be able to affect UID 100000 (and nothing else).

term1:

user$ unshare -U
nobody$ echo $$
42151

term2:

  • use the PID result above
  • replace $(ud -u user) by the actual user's UID like 1000 if needed
  • while at it also map the GID
newuidmap 42151 0 $(id -u user) 1 $(id -u user) 100000 1
newgidmap 42151 0 $(id -g user) 1 $(id -g user) 100000 1

term1 again. Re-exec bash so it updates its knowledge of its own user (just cosmetic): root (within the user namespace). root can now use setpriv to become user 1000 in the namespace seen as user 100000 on the host.

nobody$ exec bash
root# id
uid=0(root) gid=0(root) groups=0(root),65534(nogroup)
root# touch /tmp/mytest
root# setpriv --reuid user --regid user --keep-groups bash
user$ touch /tmp/mytest2
user$ 

With some additional care (as well as additional mappings rather than just 100000), one could even have chroot-ed to the actual container storage to directly affect it, e.g. when the container is not started, if it itself includes the tools required after the chroot (such as mount (but then an additional unshare -m is probably also needed before chroot), setpriv ...). Note: the user 1000 in a typical container might actually map to something else such as 101000 (or 100999 or 101001 ...) if the allowed range starts at 100000.

On term2 (the real host) check the results:

$ ls -ln /tmp/mytest*
-rw-r--r-- 1   1000   1000 0 Sep 22 11:45 /tmp/mytest
-rw-r--r-- 1 100000 100000 0 Sep 22 11:46 /tmp/mytest2
0

I ended up here with a similar problem, trying to access files created by a mapped user in a container.

This is the file I am trying to read:

$ stat -c uid=%u:%U,gid=%g:%G var/log
uid=207347:UNKNOWN,gid=207347:UNKNOWN

If we assume inside the container, the user has $uid and $gid, based on @a-b answer I managed to do it like this:

$ unshare --map-users=auto --map-groups=auto --map-user 0 --map-group 0 setpriv --reuid $uid --regid $gid --clear-groups stat -c uid=%u:%U,gid=%g:%G var/log
uid=41812:UNKNOWN,gid=41812:UNKNOWN

And 41812 is the uid and gid of the file as seen from inside the container.

You must log in to answer this question.

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