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