如果 Linux 容器(LXC 容器)被称为“非特权”,这意味着什么?
答案1
非特权 LXC 容器是那些利用用户命名空间(用户名)。即允许将主机上的一系列 UID 映射到命名空间的内核功能里面其中UID为0的用户可以再次存在。
与我最初对非特权 LXC 容器的看法相反,这并不意味着容器必须由非特权主机用户拥有。这只是一种可能。
相关的是:
- 为主机用户定义一系列从属 UID 和 GID (
usermod [-v|-w|--add-sub-uids|--add-sub-gids]
) - ...并且该范围映射到容器配置中 (
lxc.id_map = ...
)
因此,甚至root
可以拥有非特权容器,因为主机上容器进程的有效 UID 最终将位于映射定义的范围内。
但是,root
您必须首先定义从属 ID。与通过 创建的用户不同adduser
,root
默认情况下不会定义一系列从属 ID。
另请记住,您提供的完整范围可供您使用,因此您可以拥有 3 个具有以下配置行的容器(仅显示 UID 映射):
lxc.id_map = u 0 100000 100000
lxc.id_map = u 0 200000 100000
lxc.id_map = u 0 300000 100000
注意:根据评论,最近的版本称之为lxc.idmap
!
假设root
拥有 100000 到 400000 之间的从属 UID。我发现的所有文档都建议每个容器使用 65536 个从属 ID,但有些使用 100000 是为了使其更易于人类阅读。
换句话说:您不必为每个容器分配相同的范围。
拥有超过 40 亿 (~ 2^32
) 个可能的从属 ID,这意味着您在向主机用户处理从属范围时可以很慷慨。
由 root 拥有和运行的非特权容器
把它再擦一遍。非特权 LXC 来宾不需要由主机上的非特权用户运行。
使用从属 UID/GID 映射配置容器,如下所示:
lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000
root
如果主机上的用户拥有给定的从属 ID 范围,则可以让您更好地限制来宾。
然而,在这种情况下有一个重要的额外优势(是的,我已经验证它有效):您可以在系统启动时自动启动容器。
通常,当您在网上搜索有关 LXC 的信息时,您会被告知无法自动启动非特权 LXC 来宾。但是,默认情况下,这仅适用于那些不在系统范围容器存储中的容器(通常类似于/var/lib/lxc
)。如果它们是(这通常意味着它们是由 root 创建并由 root 启动的),那就完全是另外一个故事了。
lxc.start.auto = 1
一旦将其放入容器配置中,就会很好地完成这项工作。
获得正确的权限和配置
我自己在这个问题上遇到了一些困难,所以我在这里添加了一个部分。
除了lxc.include
通常通过名称/usr/share/lxc/config/$distro.common.conf
($distro
发行版名称在哪里)包含的配置片段之外,您还应该检查/usr/share/lxc/config/$distro.userns.conf
您的系统上是否也有 a 并包含它。例如:
lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf
进一步添加从属 ID 映射:
lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535
这意味着主机 UID 100000 是root
里面LXC guest 的用户命名空间。
现在请确保权限正确。如果您的来宾的姓名存储在环境变量中,$lxcguest
您将运行以下命令:
# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
这应该允许您在第一次尝试可能给出一些与权限相关的错误后运行容器。
答案2
为了跟进 0xC0000022L(其解决方案对我来说效果很好),我写了一个增加-uid-gid.plperl 脚本来自动执行必要的所有权更改,以便正确映射 LXC 容器内的文件。
如果没有它,使用此建议的设置,LXC 容器 rootfs 中属于主主机上的 0/root 的文件将在 LXC 容器本身内映射到 65534/nobody。要映射到 LXC 容器内的 0/root,它们必须属于主机上的 100000。
这是在这里描述的https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/并且脚本可以直接在gitlab上获取https://gitlab.com/yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl