我想要使用su
或sudo -u
将用户切换到 LXC 创建的子 UID,以非特权身份运行容器。
笔记:
- 没有为运行容器的 UID 分配用户名。
- 由于上述情况,我需要能够纯粹通过 UID 进行切换。
我试过这样做这个帖子指示,但我得到以下信息:
[user@laptop user]# sudo -u \#100000 id
sudo: unknown user #100000
如果它有帮助:
- 我正在使用 Arch Linux
- 我正在使用 LXD 来管理容器
有谁知道是否有办法做到这一点,即使通过其他命令或方法?
答案1
正如问题正文中问到的
我想使用
su
或sudo -u
将用户切换到 subuid
即使通过另一个命令或方法?
这setpriv
命令的一部分util-linux
记录如下:
su
与(1)和runuser
(1)相比,setpriv
既不使用 PAM,也不提示输入密码.这是一个简单,非设置用户 ID 包装器 围绕(2),并且可以像(8)来自、(8)来自或其他服务管理器附带的类似工具execve
一样用于删除权限。setuidgid
daemontools
chpst
runit
因此必须以 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
软件包 推荐的软件包的一部分lxc
,lxd
或者任何针对非 root 用户的容器技术。
$ newuidmap -h
usage: newuidmap <pid> <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ...
值 100000必须是为调用用户定义的范围的一部分/etc/subuid
,即使用户是root
:不要使用sudo
。这部分都是在没有root
特权的情况下完成的(感谢newuidmap
setuid-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。