mirror of
https://github.com/containers/podman.git
synced 2025-06-22 18:08:11 +08:00
Add support for confined users
The original SELinux support in Docker and Podman does not follow the default SELinux rules for how label transitions are supposed to be handled. Containers always switch their user and role to system_u:system_r, rather then maintain the collers user and role. For example unconfined_u:unconfined_r:container_t:s0:c1,c2 Advanced SELinux administrators want to confine users but still allow them to create containers from their role, but not allow them to launch a privileged container like spc_t. This means if a user running as container_user_u:container_user_r:container_user_t:s0 Ran a container they would get container_user_u:container_user_r:container_t:s0:c1,c2 If they run a privileged container they would run it with: container_user_u:container_user_r:container_user_t:s0 If they want to force the label they would get an error podman run --security-opt label=type:spc_t ... Should fail. Because the container_user_r can not run with the spc_t. SELinux rules would also prevent the user from forcing system_u user and the sytem_r role. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com> Signed-off-by: Chris Evich <cevich@redhat.com>
This commit is contained in:

committed by
Chris Evich

parent
78b850c48b
commit
5b7dce8a3d
@ -21,6 +21,7 @@ import (
|
||||
"github.com/containers/podman/v4/pkg/util"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/selinux/go-selinux"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -301,12 +302,38 @@ func GenRlimits(ulimits []string) ([]specs.POSIXRlimit, error) {
|
||||
return rlimits, nil
|
||||
}
|
||||
|
||||
func currentLabelOpts() ([]string, error) {
|
||||
label, err := selinux.CurrentLabel()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if label == "" {
|
||||
return nil, nil
|
||||
}
|
||||
con, err := selinux.NewContext(label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []string{
|
||||
fmt.Sprintf("label=user:%s", con["user"]),
|
||||
fmt.Sprintf("label=role:%s", con["role"]),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions, args []string) error {
|
||||
rtc, err := config.Default()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rtc.Containers.EnableLabeledUsers {
|
||||
defSecurityOpts, err := currentLabelOpts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.SecurityOpt = append(defSecurityOpts, c.SecurityOpt...)
|
||||
}
|
||||
// validate flags as needed
|
||||
if err := validate(c); err != nil {
|
||||
return err
|
||||
|
@ -19,9 +19,22 @@ function check_label() {
|
||||
# warning line about dup devices. Ignore it.
|
||||
remove_same_dev_warning
|
||||
local context="$output"
|
||||
run id -Z
|
||||
user=$(secon -u $output)
|
||||
role=$(secon -r $output)
|
||||
|
||||
is "$context" ".*_u:system_r:.*" "SELinux role should always be system_r"
|
||||
|
||||
case "$args" in
|
||||
# Containers that run automatically without SELinux transitions, run
|
||||
# with the current role.
|
||||
*--privileged*| *--pid=host* | *--ipc=host* | *"--security-opt label=disable"*)
|
||||
is "$context" "$user:$role:.*" "Non SELinux separated containers role should always be the current user and role"
|
||||
;;
|
||||
# Containers that are confined or force the spc_t type default
|
||||
# to running with the system_r role.
|
||||
*)
|
||||
is "$context" ".*_u:system_r:.*" "SELinux separated containers role should always be system_r"
|
||||
;;
|
||||
esac
|
||||
# e.g. system_u:system_r:container_t:s0:c45,c745 -> "container_t"
|
||||
type=$(cut -d: -f3 <<<"$context")
|
||||
is "$type" "$1" "SELinux type"
|
||||
@ -46,9 +59,18 @@ function check_label() {
|
||||
|
||||
# FIXME #19376 - container-selinux broken -- bats test_tags=distro-integration
|
||||
@test "podman selinux: privileged container" {
|
||||
check_label "--privileged" "spc_t"
|
||||
}
|
||||
|
||||
@test "podman selinux: privileged --userns=host container" {
|
||||
check_label "--privileged --userns=host" "spc_t"
|
||||
}
|
||||
|
||||
# bats test_tags=distro-integration
|
||||
@test "podman selinux: --ipc=host container" {
|
||||
check_label "--ipc=host" "spc_t"
|
||||
}
|
||||
|
||||
# bats test_tags=distro-integration
|
||||
@test "podman selinux: init container" {
|
||||
check_label "--systemd=always" "container_init_t"
|
||||
@ -311,4 +333,26 @@ function check_label() {
|
||||
assert "$output" =~ "${SELINUXMNT}" "Mount SELinux file system readwrite"
|
||||
}
|
||||
|
||||
@test "podman EnableLabeledUsers" {
|
||||
skip_if_no_selinux
|
||||
|
||||
overrideConf=$PODMAN_TMPDIR/containers.conf
|
||||
cat >$overrideConf <<EOF
|
||||
[Containers]
|
||||
label_users=true
|
||||
EOF
|
||||
|
||||
run id -Z
|
||||
user=$(secon -u $output)
|
||||
role=$(secon -r $output)
|
||||
CONTAINERS_CONF_OVERRIDE=$overrideConf run_podman run $IMAGE cat /proc/self/attr/current
|
||||
level=$(secon -l $output)
|
||||
id -Z
|
||||
is "$output" "$user:$role:container_t:$level" "Confined label Correctly"
|
||||
|
||||
CONTAINERS_CONF_OVERRIDE=$overrideConf run_podman run --rm --name label --security-opt label=role:system_r $IMAGE cat /proc/self/attr/current
|
||||
level=$(secon -l $output)
|
||||
is "$output" "$user:system_r:container_t:$level" "Confined with role override label Correctly"
|
||||
}
|
||||
|
||||
# vim: filetype=sh
|
||||
|
Reference in New Issue
Block a user