如何将运行 LXC 容器的用户切换为子用户?

如何将运行 LXC 容器的用户切换为子用户?

我想要使​​用susudo -u将用户切换到 LXC 创建的子 UID,以非特权身份运行容器。

笔记:

  • 没有为运行容器的 UID 分配用户名。
  • 由于上述情况,我需要能够纯粹通过 UID 进行切换。

我试过这样做这个帖子指示,但我得到以下信息:

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

如果它有帮助:

  • 我正在使用 Arch Linux
  • 我正在使用 LXD 来管理容器

有谁知道是否有办法做到这一点,即使通过其他命令或方法?

答案1

正如问题正文中问到的

我想使用susudo -u将用户切换到 subuid

即使通过另一个命令或方法?

setpriv命令的一部分util-linux记录如下:

su与(1)和runuser(1)相比,setpriv既不使用 PAM,也不提示输入密码.这是一个简单,非设置用户 ID 包装器 围绕(2),并且可以像(8)来自、(8)来自或其他服务管理器附带的类似工具execve一样用于删除权限。setuidgiddaemontoolschpstrunit

因此必须以 root 身份运行(sudo如果需要则添加):

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)

此命令还有其他补充用途。例如,它还可以更改进程的功能集。


正如问题标题所问

将运行 LXC 容器的用户切换为子用户

可以像对正在运行的容器那样进行操作:使用用户命名空间和一些帮助。

可以使用实际的底层 setuid-root 帮助程序允许普通用户运行容器:newuidmap(和newgidmap)、uidmap软件包 推荐的软件包的一部分lxclxd或者任何针对非 root 用户的容器技术。

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

值 100000必须是为调用用户定义的范围的一部分/etc/subuid,即使用户是root:不要使用sudo。这部分都是在没有root特权的情况下完成的(感谢newuidmapsetuid-root)。

因此,假设值 100000 是为用户定义的范围的一部分user/etc/subuidmap分别是/etc/subgidmap),可以运行这两个部分(例如使用两个终端),可以将用户映射为 root,也可以将 100000 映射为当前用户:用户将成为 root,并且能够影响 UID 100000(而不会影响其他任何内容)。

术语1:

user$ unshare -U
nobody$ echo $$
42151

期限2:

  • 使用上面的 PID 结果
  • 如果需要,请替换$(ud -u user)为实际用户的 UID,例如 1000
  • 同时它还映射 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。重新执行bash,以便它更新其自身用户的知识(只是表面的):(root在用户命名空间内)。root现在可以使用setpriv成为命名空间中的用户 1000,在主机上被视为用户 100000。

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$ 

通过一些额外的注意(以及额外的映射,而不仅仅是 100000),甚至可以有chroot-ed 到实际的容器存储以直接影响它,例如当容器未启动时,如果它本身包含之后所需的工具chroot(例如mount(但之前unshare -m可能还需要一个额外的工具chroot),setpriv...)。注意:如果允许的范围从 100000 开始,则典型容器中的用户 1000 实际上可能映射到其他东西,例如 101000(或 100999 或 101001...)。

在 term2 (真实主机)上检查结果:

$ 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

答案2

我在这里遇到了类似的问题,尝试访问容器中映射用户创建的文件。

这是我正在尝试读取的文件:

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

如果我们假设在容器内部,用户有 $uid 和 $gid,基于@ab 答案我设法这样做:

$ 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

41812 是从容器内部看到的文件的 uid 和 gid。

相关内容