Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: SELinux bring-up #9127

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .kres.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,14 @@ spec:
environment:
IMAGE_REGISTRY: registry.dev.siderolabs.io
SHORT_INTEGRATION_TEST: yes
- name: save-support
conditions:
- always
artifactStep:
type: upload
artifactName: talos-support
disableExecutableListGeneration: true
artifactPath: ~/.talos/support.zip
- name: save-talos-logs
conditions:
- always
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ COPY --chmod=0644 hack/containerd.toml /rootfs/etc/containerd/config.toml
COPY --chmod=0644 hack/cri-containerd.toml /rootfs/etc/cri/containerd.toml
COPY --chmod=0644 hack/cri-plugin.part /rootfs/etc/cri/conf.d/00-base.part
COPY --chmod=0644 hack/udevd/80-net-name-slot.rules /rootfs/usr/lib/udev/rules.d/
COPY --chmod=0644 hack/udevd/xx-selinux.rules /rootfs/usr/lib/udev/rules.d/
COPY --chmod=0644 hack/lvm.conf /rootfs/etc/lvm/lvm.conf
RUN <<END
ln -s /usr/share/zoneinfo/Etc/UTC /rootfs/etc/localtime
Expand Down Expand Up @@ -798,6 +799,7 @@ COPY --chmod=0644 hack/containerd.toml /rootfs/etc/containerd/config.toml
COPY --chmod=0644 hack/cri-containerd.toml /rootfs/etc/cri/containerd.toml
COPY --chmod=0644 hack/cri-plugin.part /rootfs/etc/cri/conf.d/00-base.part
COPY --chmod=0644 hack/udevd/80-net-name-slot.rules /rootfs/usr/lib/udev/rules.d/
COPY --chmod=0644 hack/udevd/xx-selinux.rules /rootfs/usr/lib/udev/rules.d/
COPY --chmod=0644 hack/lvm.conf /rootfs/etc/lvm/lvm.conf
RUN <<END
ln -s /usr/share/zoneinfo/Etc/UTC /rootfs/etc/localtime
Expand Down
1 change: 1 addition & 0 deletions api/resource/definitions/block/block.proto
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ message LocatorSpec {
// MountSpec is the spec for volume mount.
message MountSpec {
string target_path = 1;
string selinux_label = 2;
}

// PartitionSpec is the spec for volume partitioning.
Expand Down
1 change: 1 addition & 0 deletions api/resource/definitions/files/files.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ option java_package = "dev.talos.api.resource.definitions.files";
message EtcFileSpecSpec {
bytes contents = 1;
uint32 mode = 2;
string selinux_label = 3;
}

// EtcFileStatusSpec describes status of rendered secrets.
Expand Down
1 change: 1 addition & 0 deletions hack/test/e2e-qemu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -257,5 +257,6 @@ case "${TEST_MODE:-default}" in
;;
esac

"${TALOSCTL}" --nodes 172.20.1.2,172.20.1.3 support -O ~/.talos/support.zip

destroy_cluster
23 changes: 23 additions & 0 deletions hack/udevd/xx-selinux.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
SUBSYSTEM=="block",SECLABEL{selinux}="system_u:object_r:block_device_t:s0"
SUBSYSTEM=="hidraw",SECLABEL{selinux}="system_u:object_r:hidraw_device_t:s0"
SUBSYSTEM=="tty",SECLABEL{selinux}="system_u:object_r:tty_device_t:s0"
SUBSYSTEM=="rtc",SECLABEL{selinux}="system_u:object_r:rtc_device_t:s0"
SUBSYSTEM=="mtd",SECLABEL{selinux}="system_u:object_r:mtd_device_t:s0"
SUBSYSTEM=="misc",SECLABEL{selinux}="system_u:object_r:misc_device_t:s0"
SUBSYSTEM=="tpm",SECLABEL{selinux}="system_u:object_r:tpm_device_t:s0"
SUBSYSTEM=="tpmrm",SECLABEL{selinux}="system_u:object_r:tpm_device_t:s0"
SUBSYSTEM=="drm",SECLABEL{selinux}="system_u:object_r:drm_device_t:s0"
SUBSYSTEM=="drm_dp_aux_dev",SECLABEL{selinux}="system_u:object_r:drm_device_t:s0"
SUBSYSTEM=="video4linux",SECLABEL{selinux}="system_u:object_r:v4l_device_t:s0"
SUBSYSTEM=="mem",SECLABEL{selinux}="system_u:object_r:mem_device_t:s0"
SUBSYSTEM=="ptp",SECLABEL{selinux}="system_u:object_r:ptp_device_t:s0"

KERNEL=="watchdog",SECLABEL{selinux}="system_u:object_r:wdt_device_t:s0"
KERNEL=="watchdog*",SECLABEL{selinux}="system_u:object_r:wdt_device_t:s0"
KERNEL=="tun",SECLABEL{selinux}="system_u:object_r:tun_device_t:s0"
KERNEL=="null",SECLABEL{selinux}="system_u:object_r:null_device_t:s0"
KERNEL=="zero",SECLABEL{selinux}="system_u:object_r:null_device_t:s0"
KERNEL=="kmsg",SECLABEL{selinux}="system_u:object_r:kmsg_device_t:s0"
KERNEL=="kvm",SECLABEL{selinux}="system_u:object_r:kvm_device_t:s0"
KERNEL=="random",SECLABEL{selinux}="system_u:object_r:random_device_t:s0"
KERNEL=="urandom",SECLABEL{selinux}="system_u:object_r:random_device_t:s0"
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func (ctrl *UserDiskConfigController) Run(ctx context.Context, r controller.Runt
Match: partitionIdxMatch(resolvedDevicePath, idx+1),
}

// TODO: does this need a SELinux label?
vc.TypedSpec().Mount = block.MountSpec{
TargetPath: part.MountPoint(),
}
Expand Down
9 changes: 6 additions & 3 deletions internal/app/machined/pkg/controllers/block/volume_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ func (ctrl *VolumeConfigController) manageEphemeral(config cfg.Config) func(vc *
}

vc.TypedSpec().Mount = block.MountSpec{
TargetPath: constants.EphemeralMountPoint,
TargetPath: constants.EphemeralMountPoint,
SelinuxLabel: "system_u:object_r:ephemeral_t:s0",
}

vc.TypedSpec().Locator = block.LocatorSpec{
Expand All @@ -254,7 +255,8 @@ func (ctrl *VolumeConfigController) manageStateConfigPresent(config cfg.Config)
return func(vc *block.VolumeConfig) error {
vc.TypedSpec().Type = block.VolumeTypePartition
vc.TypedSpec().Mount = block.MountSpec{
TargetPath: constants.StateMountPoint,
TargetPath: constants.StateMountPoint,
SelinuxLabel: "system_u:object_r:system_state_t:s0",
}

vc.TypedSpec().Provisioning = block.ProvisioningSpec{
Expand Down Expand Up @@ -293,7 +295,8 @@ func (ctrl *VolumeConfigController) manageStateNoConfig(encryptionMeta *runtime.
return func(vc *block.VolumeConfig) error {
vc.TypedSpec().Type = block.VolumeTypePartition
vc.TypedSpec().Mount = block.MountSpec{
TargetPath: constants.StateMountPoint,
TargetPath: constants.StateMountPoint,
SelinuxLabel: "system_u:object_r:system_state_t:s0",
}

match := labelVolumeMatchAndNonEmpty(constants.StatePartitionLabel)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func (ctrl *NodeIdentityController) Run(ctx context.Context, r controller.Runtim

r.TypedSpec().Contents, err = clusteradapter.IdentitySpec(&localIdentity).ConvertMachineID()
r.TypedSpec().Mode = 0o444
r.TypedSpec().SelinuxLabel = "system_u:object_r:etc_machine_id_t:s0"

return err
}); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func (ctrl *CRIConfigPartsController) Run(ctx context.Context, r controller.Runt

spec.Contents = out
spec.Mode = 0o600
spec.SelinuxLabel = "system_u:object_r:k8s_conf_t:s0"

return nil
}); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.R

spec.Contents = criRegistryContents
spec.Mode = 0o600
spec.SelinuxLabel = "system_u:object_r:k8s_conf_t:s0"

return nil
}); err != nil {
Expand Down
14 changes: 10 additions & 4 deletions internal/app/machined/pkg/controllers/files/etcfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"go.uber.org/zap"
"golang.org/x/sys/unix"

"github.com/siderolabs/talos/internal/pkg/selinux"
"github.com/siderolabs/talos/pkg/machinery/resources/files"
)

Expand Down Expand Up @@ -133,7 +134,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo

logger.Debug("writing file contents", zap.String("dst", dst), zap.Stringer("version", spec.Metadata().Version()))

if err = UpdateFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode); err != nil {
if err = UpdateFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode, spec.TypedSpec().SelinuxLabel); err != nil {
return fmt.Errorf("error updating %q: %w", dst, err)
}

Expand Down Expand Up @@ -194,11 +195,16 @@ func createBindMount(src, dst string, mode os.FileMode) (err error) {

// UpdateFile is like `os.WriteFile`, but it will only update the file if the
// contents have changed.
func UpdateFile(filename string, contents []byte, mode os.FileMode) error {
func UpdateFile(filename string, contents []byte, mode os.FileMode, selinuxLabel string) error {
oldContents, err := os.ReadFile(filename)
if err == nil && bytes.Equal(oldContents, contents) {
return nil
return selinux.SetLabel(filename, selinuxLabel)
}

return os.WriteFile(filename, contents, mode)
err = os.WriteFile(filename, contents, mode)
if err != nil {
return err
}

return selinux.SetLabel(filename, selinuxLabel)
}
4 changes: 3 additions & 1 deletion internal/app/machined/pkg/controllers/network/etcfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _
func(r *files.EtcFileSpec) error {
r.TypedSpec().Contents = renderResolvConf(pickNameservers(hostDNSCfg, resolverStatus), hostnameStatusSpec, cfgProvider)
r.TypedSpec().Mode = 0o644
r.TypedSpec().SelinuxLabel = "system_u:object_r:dns_conf_t:s0"

return nil
}); err != nil {
Expand All @@ -170,7 +171,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _
return fmt.Errorf("error creating pod resolv.conf dir: %w", err)
}

err = efiles.UpdateFile(ctrl.PodResolvConfPath, conf, 0o644)
err = efiles.UpdateFile(ctrl.PodResolvConfPath, conf, 0o644, "system_u:object_r:dns_conf_t:s0")
if err != nil {
return fmt.Errorf("error writing pod resolv.conf: %w", err)
}
Expand All @@ -181,6 +182,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _
func(r *files.EtcFileSpec) error {
r.TypedSpec().Contents, err = ctrl.renderHosts(hostnameStatus.TypedSpec(), nodeAddressStatus.TypedSpec(), cfgProvider)
r.TypedSpec().Mode = 0o644
r.TypedSpec().SelinuxLabel = "system_u:object_r:hosts_conf_t:s0"

return err
}); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
func (c *Config) Install(opts options.InstallOptions) (*options.InstallResult, error) {
var installResult *options.InstallResult

// TODO: label /boot
err := mount.PartitionOp(
opts.BootDisk,
[]mount.Spec{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import (
"golang.org/x/sys/unix"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"

efiles "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/files"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/emergency"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime/v1alpha1/bootloader/grub"
Expand Down Expand Up @@ -148,6 +149,21 @@ func SetupSystemDirectory(runtime.Sequence, any) (runtime.TaskExecutionFunc, str
if err = os.MkdirAll(p, 0o700); err != nil {
return err
}

var label string

switch p {
case constants.SystemEtcPath:
label = "system_u:object_r:system_etc_t:s0"
case constants.SystemVarPath:
label = "system_u:object_r:system_var_t:s0"
default: // /system/state is another mount
label = ""
}

if err = selinux.SetLabel(p, label); err != nil {
return err
}
}

for _, p := range []string{constants.SystemRunPath} {
Expand Down Expand Up @@ -436,7 +452,7 @@ func OSRelease() (err error) {
return err
}

return os.WriteFile(filepath.Join(constants.SystemEtcPath, "os-release"), contents, 0o644)
return efiles.UpdateFile(filepath.Join(constants.SystemEtcPath, "os-release"), contents, 0o644, "system_u:object_r:etc_os_release_t:s0")
}

// createBindMount creates a common way to create a writable source file with a
Expand Down Expand Up @@ -855,6 +871,7 @@ func SetupSharedFilesystems(runtime.Sequence, any) (runtime.TaskExecutionFunc, s
return func(ctx context.Context, logger *log.Logger, r runtime.Runtime) (err error) {
targets := []string{"/", "/var", "/etc/cni", "/run"}
for _, t := range targets {
// TODO: SELinux label?
if err = unix.Mount("", t, "", unix.MS_SHARED|unix.MS_REC, ""); err != nil {
return err
}
Expand Down Expand Up @@ -1002,6 +1019,7 @@ func MountUserDisks(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) {
volumeStatus.TypedSpec().MountLocation,
volumeConfig.TypedSpec().Mount.TargetPath,
volumeStatus.TypedSpec().Filesystem.String(),
mountv2.WithSelinuxLabel(volumeConfig.TypedSpec().Mount.SelinuxLabel),
))
}

Expand Down Expand Up @@ -1154,6 +1172,7 @@ func injectCRIConfigPatch(ctx context.Context, st state.State, content []byte) e
etcFileSpec := resourcefiles.NewEtcFileSpec(resourcefiles.NamespaceName, constants.CRICustomizationConfigPart)
etcFileSpec.TypedSpec().Mode = 0o600
etcFileSpec.TypedSpec().Contents = content
etcFileSpec.TypedSpec().SelinuxLabel = "system_u:object_r:k8s_conf_t:s0"

if err := st.Create(ctx, etcFileSpec); err != nil {
return err
Expand Down
2 changes: 2 additions & 0 deletions internal/pkg/mount/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func SystemPartitionMount(ctx context.Context, r runtime.Runtime, logger *log.Lo
return fmt.Errorf("error getting volume config %q: %w", label, err)
}

opts = append(opts, mountv2.WithSelinuxLabel(volumeConfig.TypedSpec().Mount.SelinuxLabel))

mountpoint := mountv2.NewPoint(
volumeStatus.TypedSpec().MountLocation,
volumeConfig.TypedSpec().Mount.TargetPath,
Expand Down
26 changes: 23 additions & 3 deletions internal/pkg/mount/v2/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/siderolabs/go-retry/retry"
"golang.org/x/sys/unix"

"github.com/siderolabs/talos/internal/pkg/selinux"
"github.com/siderolabs/talos/pkg/machinery/constants"
)

Expand All @@ -29,8 +30,9 @@ type Point struct {
flags uintptr
data string

shared bool
extraDirs []string
shared bool
extraDirs []string
selinuxLabel string
}

// NewPointOption is a mount point option.
Expand Down Expand Up @@ -84,6 +86,13 @@ func WithExtraDirs(dirs ...string) NewPointOption {
}
}

// WithSelinuxLabel sets the mount SELinux label.
func WithSelinuxLabel(label string) NewPointOption {
return func(p *Point) {
p.selinuxLabel = label
}
}

// NewPoint creates a new mount point.
func NewPoint(source, target, fstype string, opts ...NewPointOption) *Point {
p := &Point{
Expand Down Expand Up @@ -290,14 +299,25 @@ func (p *Point) Move(newTarget string) error {
}

func (p *Point) mount() error {
return unix.Mount(p.source, p.target, p.fstype, p.flags, p.data)
if err := unix.Mount(p.source, p.target, p.fstype, p.flags, p.data); err != nil {
return err
}

if p.selinuxLabel != "" {
fmt.Printf("relabeling mount %s to %s\n", p.target, p.selinuxLabel)

return selinux.SetLabel(p.target, p.selinuxLabel)
}

return nil
}

func (p *Point) unmount(printer func(string, ...any)) error {
return SafeUnmount(context.Background(), printer, p.target)
}

func (p *Point) share() error {
// TODO: SELinux label?
return unix.Mount("", p.target, "", unix.MS_SHARED|unix.MS_REC, "")
}

Expand Down
23 changes: 23 additions & 0 deletions internal/pkg/selinux/policy/file_contexts
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
/.extra(/.*)? system_u:object_r:extra_t:s0
/bin(/.*)? system_u:object_r:bin_t:s0
/etc(/.*)? system_u:object_r:etc_t:s0
/lib(/.*)? system_u:object_r:lib_t:s0
/usr(/.*)? system_u:object_r:usr_t:s0
/sbin(/.*)? system_u:object_r:sbin_exec_t:s0
/etc/cri(/.*)? system_u:object_r:k8s_conf_t:s0
/etc/lvm(/.*)? system_u:object_r:lvm_conf_t:s0
/etc/pki(/.*)? system_u:object_r:ssl_certificates_t:s0
/etc/ssl(/.*)? system_u:object_r:ssl_certificates_t:s0
/usr/bin(/.*)? system_u:object_r:bin_t:s0
/usr/etc(/.*)? system_u:object_r:udev_conf_t:s0
/usr/lib(/.*)? system_u:object_r:lib_t:s0
/usr/sbin(/.*)? system_u:object_r:sbin_exec_t:s0
/etc/selinux(/.*)? system_u:object_r:selinux_conf_t:s0
/opt/cni/bin(/.*)? system_u:object_r:cri_plugin_bin_t:s0
/usr/libexec(/.*)? system_u:object_r:bin_t:s0
/lib/firmware(/.*)? system_u:object_r:firmware_t:s0
/usr/lib/udev(/.*)? system_u:object_r:udev_exec_t:s0
/etc/containerd(/.*)? system_u:object_r:k8s_conf_t:s0
/opt/containerd(/.*)? system_u:object_r:opt_containerd_t:s0
/usr/share/zoneinfo(/.*)? system_u:object_r:timezone_t:s0
/usr/lib/udev/rules.d(/.*)? system_u:object_r:udev_rules_t:s0
/etc/ca-certificates(/.*)? system_u:object_r:ssl_certificates_t:s0
/usr/share/ca-certificates(/.*)? system_u:object_r:ssl_certificates_t:s0
/usr/local/share/ca-certificates(/.*)? system_u:object_r:ssl_certificates_t:s0
/ system_u:object_r:rootfs_t:s0
/bin/runc system_u:object_r:containerd_exec_t:s0
/sbin/init -- system_u:object_r:init_exec_t:s0
/sbin/udevadm -l system_u:object_r:udev_exec_t:s0
/etc/localtime system_u:object_r:timezone_t:s0
/sbin/poweroff system_u:object_r:init_exec_t:s0
/sbin/shutdown system_u:object_r:init_exec_t:s0
/sbin/modprobe -- system_u:object_r:modprobe_exec_t:s0
Expand Down
Binary file modified internal/pkg/selinux/policy/policy.33
Binary file not shown.
Loading
Loading