mirror of
https://github.com/siderolabs/talos.git
synced 2025-08-10 00:27:05 +02:00
Part of: #9127 Label executables and processes, build, load and manage SELinux policy, enable audit support. Labeling filesystems, devices and runtime files will be done in further changes, see the full PR. Signed-off-by: Dmitry Sharshakov <dmitry.sharshakov@siderolabs.com>
147 lines
3.7 KiB
Go
147 lines
3.7 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
//go:build integration_api
|
|
|
|
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/siderolabs/go-pointer"
|
|
"github.com/siderolabs/go-procfs/procfs"
|
|
|
|
"github.com/siderolabs/talos/internal/integration/base"
|
|
"github.com/siderolabs/talos/pkg/machinery/client"
|
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
|
)
|
|
|
|
// SELinuxSuite ...
|
|
type SELinuxSuite struct {
|
|
base.APISuite
|
|
|
|
ctx context.Context //nolint:containedctx
|
|
ctxCancel context.CancelFunc
|
|
}
|
|
|
|
// SuiteName ...
|
|
func (suite *SELinuxSuite) SuiteName() string {
|
|
return "api.SELinuxSuite"
|
|
}
|
|
|
|
// SetupTest ...
|
|
func (suite *SELinuxSuite) SetupTest() {
|
|
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 15*time.Second)
|
|
|
|
if suite.Cluster == nil || suite.Cluster.Provisioner() != base.ProvisionerQEMU {
|
|
suite.T().Skip("skipping SELinux test since provisioner is not qemu")
|
|
}
|
|
}
|
|
|
|
// TearDownTest ...
|
|
func (suite *SELinuxSuite) TearDownTest() {
|
|
if suite.ctxCancel != nil {
|
|
suite.ctxCancel()
|
|
}
|
|
}
|
|
|
|
func (suite *SELinuxSuite) getLabel(nodeCtx context.Context, pid int32) string {
|
|
r, err := suite.Client.Read(nodeCtx, filepath.Join("/proc", strconv.Itoa(int(pid)), "attr/current"))
|
|
suite.Require().NoError(err)
|
|
|
|
value, err := io.ReadAll(r)
|
|
suite.Require().NoError(err)
|
|
|
|
suite.Require().NoError(r.Close())
|
|
|
|
return string(bytes.TrimSpace(value))
|
|
}
|
|
|
|
// TestProcessLabels reads labels of system processes from procfs
|
|
// to ensure SELinux labels for processes are correctly set
|
|
//
|
|
//nolint:gocyclo
|
|
func (suite *SELinuxSuite) TestProcessLabels() {
|
|
nodes := suite.DiscoverNodeInternalIPs(suite.ctx)
|
|
|
|
for _, node := range nodes {
|
|
nodeCtx := client.WithNode(suite.ctx, node)
|
|
cmdline := suite.ReadCmdline(nodeCtx)
|
|
|
|
seLinuxEnabled := pointer.SafeDeref(procfs.NewCmdline(cmdline).Get(constants.KernelParamSELinux).First()) != ""
|
|
if !seLinuxEnabled {
|
|
suite.T().Skip("skipping SELinux test since SELinux is disabled")
|
|
}
|
|
|
|
r, err := suite.Client.Processes(nodeCtx)
|
|
suite.Require().NoError(err)
|
|
|
|
for _, msg := range r.Messages {
|
|
procs := msg.Processes
|
|
|
|
for _, p := range procs {
|
|
switch p.Command {
|
|
case "systemd-udevd":
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelUdevd,
|
|
)
|
|
case "dashboard":
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelDashboard,
|
|
)
|
|
case "containerd":
|
|
if strings.Contains(p.Args, "/system/run/containerd") {
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelSystemRuntime,
|
|
)
|
|
} else {
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelPodRuntime,
|
|
)
|
|
}
|
|
case "init":
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelMachined,
|
|
)
|
|
case "kubelet":
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelKubelet,
|
|
)
|
|
case "apid":
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelApid,
|
|
)
|
|
case "trustd":
|
|
suite.Require().Contains(
|
|
suite.getLabel(nodeCtx, p.Pid),
|
|
constants.SelinuxLabelTrustd,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: test for file labels
|
|
// TODO: test labels for unconfined system extensions, pods
|
|
// TODO: test for no avc denials in dmesg
|
|
// TODO: start a pod and ensure access to restricted resources is denied
|
|
|
|
func init() {
|
|
allSuites = append(allSuites, new(SELinuxSuite))
|
|
}
|