podmansh - 在 Podman podmansh
容器中执行登录 shell
摘要
用于启动和管理具有特定 SELinux 配置的 Podman 容器。Podman 是一个开源项目,用于管理容器和容器镜像,与 Docker 功能相似,但不需要守护进程运行。
用于以特定用户的身份运行 Podman 容器,并应用特定的 SELinux 策略。
用户身份管理:脚本以特定用户的身份(在此例中是
fullu
)运行容器,可能还保持了这个用户的 ID(UID)和组 ID(GID)。SELinux 策略配置:通过
PodmanArgs
设置了一系列的 SELinux 安全选项,允许容器在具有 SELinux 嵌套和特定上下文的环境中运行。这确保了容器受到 SELinux 访问控制策略的保护。目录挂载:将用户的
$HOME/data
目录挂载到容器内部,并设置适当的 SELinux 上下文。这样,用户可以在容器内访问和修改这个目录的内容。容器执行命令:脚本启动容器后,执行
sleep infinity
命令,使容器保持运行状态。初始化目录:在容器启动前,确保
$HOME/data
目录存在,这通过ExecStartPre
指令实现。
使用 podmansh
通常,你需要按照以下步骤操作:
安装和配置 Podman:确保你的系统上已经安装了 Podman,并且已经进行了必要的配置。
获取 podmansh 脚本:从项目或文档中获取
podmansh
脚本,并将其放置在适当的位置。配置用户和环境:根据需要创建用户,并设置相关的 SELinux 策略。
运行 podmansh:作为特定用户(例如
fullu
)运行podmansh
脚本或命令,以启动和管理容器。
podmansh
描述
在用户登录系统时,在容器内执行用户 shell。用户将被添加到的容器可以通过 Podman Quadlet 文件进行定义。该用户仅可以访问在 Quadlet 文件中配置的卷和功能。
管理员可以在 /etc/containers/systemd/users
中创建一个 Quadlet,systemd 将在用户登录时为所有用户启动它。管理员可以创建一个包含容器名称 podmansh
的特定 Quadlet,然后允许用户使用登录 shell /usr/bin/podmansh
。这些用户登录 shell 会自动通过 Podman 在 podmansh
容器内部执行。
可选地,管理员可以将 Quadlet 文件放置在 /etc/containers/systemd/users/${UID}
目录中,仅当此 UID 用户登录时,才会执行这些 Quadlet 服务。
用户通过所有安全机制(包括 SELinux)被限制在容器环境中。来自系统的唯一可用信息来自泄露到容器中的卷。
当用户会话启动时,systemd 将自动创建容器。当所有到用户会话的连接都被移除时,systemd 将停止容器。这意味着用户可以多次登录到系统,每个会话都连接到相同的容器。
管理员可以使用卷将主机系统上的特定主机数据暴露给用户,而不会使用户暴露于系统的其他部分。
可以使用 containers.conf
文件中的 podmansh_timeout
选项设置 podmansh 的超时时间。
请注意,podmansh
是一种特定于 Podman 的功能,允许管理员通过 systemd 和 Quadlet 文件为用户创建隔离的登录环境。这有助于限制用户对系统资源的访问,同时确保他们的会话在容器化的安全环境中执行。通过配置适当的卷和功能,管理员可以控制用户可以访问哪些系统资源和数据。
设置
以 root 身份运行,使用 useradd 创建用户登录会话。
# useradd -s /usr/bin/podmansh lockedu
# grep lockedu /etc/passwd
lockedu:x:4008:4008::/home/lockedu:/usr/bin/podmansh
创建一个类似于以下内容的 Podman Quadlet 文件。
完全锁定的容器,无法访问主机操作系统。
# USERID=$(id -u lockedu)
# mkdir -p /etc/containers/systemd/users/${USERID}
# cat > /etc/containers/systemd/users/${USERID}/podmansh.container << _EOF
[Unit]
Description=The podmansh container
After=local-fs.target
[Container]
Image=registry.fedoraproject.org/fedora
ContainerName=podmansh-%i
RemapUsers=keep-id
RunInit=yes
DropCapability=all
NoNewPrivileges=true
ExecStart=/bin/bash
[Install]
WantedBy=default.target
_EOF
请注意,上述 Quadlet 示例做了以下几点设置:
Image
: 指定容器使用的镜像,这里使用了 Fedora 的官方镜像。ContainerName
: 容器名称,其中%i
是一个 systemd 模板单元实例化的占位符,它将被替换为用户的 UID。RemapUsers=keep-id
: 这表示容器内的用户 ID 将与主机上的用户 ID 保持一致。RunInit
: 启用 systemd 初始化系统,这允许容器内部运行 systemd 管理的服务。DropCapability=all
: 删除容器内进程的所有 Linux 功能,增强安全性。NoNewPrivileges=true
: 确保容器内进程不会获得新的权限。ExecStart
: 容器启动后执行的命令,这里使用/bin/bash
作为 shell。
此外,请确保 Quadlet 文件的路径和名称与您的设置相匹配。在这个例子中,我们为特定用户创建了一个 Quadlet 文件,并将其放置在 /etc/containers/systemd/users/${USERID}/
目录下。
创建 Quadlet 文件后,您还需要启用和启动 systemd 用户服务,以便在用户登录时自动运行该容器。这通常涉及使用 systemctl
命令来启用和启动服务。然而,对于使用 podmansh
的情况,您可能不需要手动执行这些步骤,因为 systemd 会在用户登录时自动处理这些操作。
请确保在尝试使用 podmansh
之前,Podman 已经在系统上正确安装和配置,并且用户具有适当的权限来执行所需的操作。同时,也请检查您的发行版是否支持 podmansh
功能,以及是否需要其他特定的配置步骤。
您的要求是在 Podman 容器中允许用户在其用户命名空间内提升为 root 权限,并且能够从其宿主机的实际用户账户中永久读写内容。这通常不是一个推荐的安全做法,因为它破坏了容器化的隔离原则。然而,如果您确实有这样的需求,并且理解潜在的安全风险,可以按照以下步骤进行操作。
首先,确保 Podman 已经安装在您的系统上,并且 podmansh
已经配置为默认的 shell。然后,创建用户并设置相应的 Quadlet 文件。
# useradd -s /usr/bin/podmansh confinedu
# grep confinedu /etc/passwd
confinedu:x:4009:4009::/home/confinedu:/usr/bin/podmansh
接下来,创建 Quadlet 文件,并配置为允许用户在其用户命名空间内获得 root 权限,并且从宿主机的用户目录挂载数据。
# USERID=$(id -u confinedu)
# mkdir -p /etc/containers/systemd/users/${USERID}
# cat > /etc/containers/systemd/users/${USERID}/podmansh.container << '_EOF'
[Unit]
Description=The podmansh container for confinedu
After=local-fs.target
[Container]
Image=registry.fedoraproject.org/fedora
ContainerName=podmansh-%i
RemapUsers=keep-id
RunInit=yes
# Mount the user's home directory from the host into the container
Volume=/home/confinedu:/home/confinedu:Z
# Allow the user to become root within the container
Capability=CAP_SETUID+ep CAP_SETGID+ep CAP_SYS_ADMIN+ep
ExecStart=/bin/bash
[Service]
# Ensure the mount point exists in the container
ExecStartPre=/bin/mkdir -p /home/confinedu/data
[Install]
WantedBy=default.target
_EOF
在这个配置中,Volume
指令挂载了宿主机的 /home/confinedu
到容器的相同位置。这允许用户在容器内直接访问其宿主机的家目录。
Capability
指令赋予了容器内用户一些额外的 Linux 功能,允许用户提升权限。这里包括 CAP_SETUID
, CAP_SETGID
, 和 CAP_SYS_ADMIN
,它们分别允许用户更改进程的用户和组 ID,以及执行某些系统管理任务。
请注意,CAP_SYS_ADMIN
是一个非常强大的功能,它基本上允许用户在容器内执行大多数系统管理任务,包括挂载文件系统、设置网络等。这明显削弱了容器的安全隔离,因此只在完全理解潜在风险的情况下使用。
创建 Quadlet 文件后,您需要重新加载 systemd 的配置,并可能还需要启用和启动相应的 systemd 用户服务。此外,由于这里涉及到敏感操作,请确保仔细审查您的配置,并考虑任何可能的安全影响。在生产环境中,通常不建议允许容器内的用户提升为 root 或拥有过多的 Linux 功能。
在这个例子中,我们创建了一个 Quadlet,其中容器内的用户被允许在具有 SELinux 分离的情况下执行容器,并且能够读取和写入 $HOME/data
目录的内容。SELinux(Security-Enhanced Linux)为 Linux 系统提供了访问控制安全策略,能够限制进程和文件的权限。
首先,我们以 root 用户身份运行,并创建一个新用户 fullu
,其 shell 设置为 /usr/bin/podmansh
。
# useradd -s /usr/bin/podmansh fullu
# grep fullu /etc/passwd
fullu:x:4010:4010::/home/fullu:/usr/bin/podmansh
然后,我们获取该用户的 UID,并创建 Quadlet 文件的目录。
# USERID=$(id -u fullu)
# mkdir -p /etc/containers/systemd/users/${USERID}
接下来,我们创建 Quadlet 文件,并配置 SELinux 相关的选项以及挂载点。
# cat > /etc/containers/systemd/users/${USERID}/podmansh.container << '_EOF'
[Unit]
Description=The podmansh container
After=local-fs.target
[Container]
Image=registry.fedoraproject.org/fedora
ContainerName=podmansh-%i
RemapUsers=keep-id
RunInit=yes
# PodmanArgs 设置了 SELinux 的相关参数,允许嵌套容器和特定的 SELinux 上下文
PodmanArgs=--security-opt=unmask=/sys/fs/selinux \
--security-opt=label=nested \
--security-opt=label=user:container_user_u \
--security-opt=label=type:container_user_t \
--security-opt=label=role:container_user_r \
--security-opt=label=level:s0-s0:c0.c1023
# 挂载用户的 data 目录到容器中
Volume=%h/data:%h:Z
# 设置工作目录为用户的家目录
WorkingDir=%h
# 挂载 SELinux 文件系统到容器中,以便容器内可以访问 SELinux 功能
Volume=/sys/fs/selinux:/sys/fs/selinux
Exec=sleep infinity
[Service]
# 在容器启动前创建 data 目录
ExecStartPre=/usr/bin/mkdir -p %h/data
[Install]
RequiredBy=default.target
_EOF
在这个配置中,PodmanArgs
指令设置了一系列的 SELinux 安全选项,使得容器能够支持 SELinux 嵌套,并指定了特定的 SELinux 用户、类型、角色和级别。这些设置允许容器在 SELinux 的策略控制下运行,同时确保容器内部进程和文件受到适当的访问控制。
Volume
指令用于挂载用户的 data
目录到容器中,并且设置了正确的 SELinux 上下文(:Z
表示重新标记挂载的文件系统以符合容器内的策略)。这允许用户在容器内访问和修改这个目录。
WorkingDir
指令设置了容器的工作目录为用户的家目录,使得用户在容器启动后默认进入该目录。
最后,我们还挂载了宿主机的 /sys/fs/selinux
到容器内,以便容器能够访问 SELinux 的文件系统接口。
创建 Quadlet 文件后,您需要重新加载 systemd 的配置,并可能还需要启用和启动相应的 systemd 用户服务。
注意:SELinux 策略通常需要根据您的具体需求和系统环境进行定制。在实际部署时,您可能需要根据您的 SELinux 策略修改这些选项。此外,SELinux 的配置和管理需要谨慎操作,以避免意外地限制系统或应用程序的功能。
另请参阅
podman-container(1): 这个手册页描述了
containers.conf
文件的格式和内容,该文件通常用于配置容器运行时(如 Podman)的全局设置。podman(1): 这是 Podman 容器引擎的手册页。Podman 是一个用于管理容器的工具,类似于 Docker,但是它不需要守护进程,可以直接作为非特权用户运行。
podman-exec(1): 这个手册页可能描述了如何使用
podman exec
命令在正在运行的容器内执行命令。quadlet(5): 这可能是描述 Quadlet(可能是某种容器或虚拟化技术的配置或定义文件)的手册页。然而,需要注意的是,“quadlet”并不是一个广泛认可或标准的术语,这可能是特定环境或项目中的自定义术语。
历史
文档于 2023 年 5 月由Dan Walsh编译。是 Red Hat 公司的一位知名 SELinux 专家和贡献者。