使用 LXC 和 userns 为非特权用户提供从属 GID/UID?

0xC*_*22L 7 shadow lxc 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
Run Code Online (Sandbox Code Playgroud)

非特权容器内的文件归“内部”john所有,现在归主机 101000 所有,归“内部”root所有的文件归 100000。

通常,这些范围不会分配给主机上的任何名称。

问题:

  1. 是否可以在主机上为这些各自的 UID/GID 创建一个用户,以便为ls朋友们提供更有意义的输出?
  2. 有没有办法让“拥有”用户的主机用户可以访问这些文件/文件夹,即john在我们的情况下?如果是这样,在从属范围内的那些有效用户和用户“所有者”之间创建共享组并相应地设置权限的唯一明智方法是?好吧,或者 ACL,很明显。

Whi*_*olf 2

  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
Run Code Online (Sandbox Code Playgroud)

有关无法访问的主目录的警告是正常的并且是预期的:这是/nonexistent不存在的实际目的。

  1. 有没有办法使“拥有”用户的主机用户(即我们的例子中的约翰)可以访问这些文件/文件夹?如果是这样,创建一个在下属范围内的有效用户和用户“所有者”之间共享的组并相应地设置权限是唯一明智的方法吗?嗯,显然是 ACL。

在我看来,这确实值得单独提出一个问题。

由于容器的内容由与容器所有者 UID 不同的 UID 拥有,因此他无法访问该内容。我可以想象子用户的这条规则有一个例外,但目前我不知道(我前段时间创建了一个相关问题,但还没有答案)。

文件/etc/subuid/etc/subgid当前仅由 (1) 使用来newuidmap允许或拒绝给定进程从一个 UID/GID 切换到另一个 UID/GID。它没有赋予牧场所有者任何其他权利。

因此,针对此类问题的解决方案应根据具体情况进行设计。但要注意 ACL 的想法:假设您在容器的文件上放置了一些 ACL,以允许主机的 UID 1000 读取它们,这意味着容器的 UID 1000 的容器用户也将拥有相同级别的权限...