当使用 userns 时(在我的例子中通过 LXC),您将一系列从属 GID 和 UID 分配给非特权用户。请参阅资源:subuid(5)
,subgid(5)
,newuidmap(1)
,newgidmap(1)
,user_namespaces(7)
。
然后可以使用该范围并将通过用户名映射到系统帐户。
假设我们有john
一个 UID(和 GID)为 1000 的(主机)系统帐户。分配的 GID 和 UID 范围是 100000..165536。
/etc/subgid
因此,和分别存在一个条目/etc/subuid
:
john:100000:65536
非特权容器内由“内部”拥有的文件john
现在将由主机上的 101000 拥有,而由“内部”拥有的文件root
将由 100000 拥有。
通常这些范围不会分配给主机上的任何名称。
问题:
- 是否可以在主机上为这些各自的 UID/GID 创建一个用户,以便为
ls
朋友提供更有意义的输出? - 有没有办法使“拥有”用户的主机用户可以访问这些文件/文件夹,即
john
在我们的例子中?如果是这样,创建一个在下属范围内的有效用户和用户“所有者”之间共享的组并相应地设置权限是唯一明智的方法吗?嗯,显然是 ACL。
答案1
- 是否可以在主机上为相应的 UID/GID 创建一个用户,以便为 ls 和朋友提供更有意义的输出?
是的,没关系。但是,您必须确保此类用户对主机系统中的任何内容无权:
- 禁用访问或密码,
- 没有可用的登录 shell,
- 没有可写的主目录。
还请确保不要在您的用户名中创建任何重复的内容。
这是一个示例脚本,使用来宾/etc/passwd
和/etc/group
文件在主机系统中创建相应的用户。所有名称均以容器名称为前缀,并且所有 ID 均使用给定值增加以匹配容器的 UID:
#! /bin/sh
# Path to guest's `/etc' directory.
guest_etc=/var/lib/lxc/mycontainer/rootfs/etc
# Guest's name, used as login prefix and inside GECOS field.
guest_name=mycontainer
# Increment to be applied to UIDs and GIDs (= range start).
uid_incr=100000
gid_incr=$uid_incr
guest_passwd=${guest_etc}/passwd
guest_group=${guest_etc}/group
exec <$guest_group
while IFS=":" read name pass gid null; do
gid_new=$( expr $gid + $gid_incr )
if ! getent group $gid_new >/dev/null; then
addgroup --system --gid $gid_new "${guest_name}_${name}"
fi
done
exec <$guest_passwd
while IFS=":" read login pass uid gid gecos null; do
uid_new=$( expr $uid + $uid_incr )
gid_new=$( expr $gid + $gid_incr )
if ! getent passwd $uid_new >/dev/null; then
adduser --system --home /nonexistent --no-create-home \
--shell /bin/nologin --uid $uid_new --gid $gid_new \
--gecos "\"$guest_name container user (${gecos})\"" \
"${guest_name}_${login}"
fi
done
有关无法访问的主目录的警告是正常的并且是预期的:这是/nonexistent
不存在的实际目的。
- 有没有办法使“拥有”用户的主机用户(即我们的例子中的约翰)可以访问这些文件/文件夹?如果是这样,创建一个在下属范围内的有效用户和用户“所有者”之间共享的组并相应地设置权限是唯一明智的方法吗?嗯,显然是 ACL。
在我看来,这确实值得单独提出一个问题。
由于容器的内容由与容器所有者 UID 不同的 UID 拥有,因此他无法访问该内容。我可以想象子用户的这条规则有一个例外,但目前我不知道(我已经创建了一个相关的问题前段时间,但还没有答案)。
文件/etc/subuid
和/etc/subgid
当前仅由 (1) 使用newuidmap
来允许或拒绝给定进程从一个 UID/GID 切换到另一个 UID/GID。它没有赋予牧场所有者任何其他权利。
因此,应根据具体情况设计解决方案。但要注意 ACL 的想法:假设您在容器的文件上放置了一些 ACL,以允许主机的 UID 1000 读取它们,这意味着容器的 UID 1000 的容器用户也将拥有相同级别的权限...