diff --git a/api/resource/definitions/files/files.proto b/api/resource/definitions/files/files.proto index 5c14d4c2f7d..832e2f501dd 100755 --- a/api/resource/definitions/files/files.proto +++ b/api/resource/definitions/files/files.proto @@ -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. diff --git a/internal/app/machined/pkg/controllers/cluster/node_identity.go b/internal/app/machined/pkg/controllers/cluster/node_identity.go index c19c3b2d751..9bf4fe88906 100644 --- a/internal/app/machined/pkg/controllers/cluster/node_identity.go +++ b/internal/app/machined/pkg/controllers/cluster/node_identity.go @@ -114,6 +114,7 @@ func (ctrl *NodeIdentityController) Run(ctx context.Context, r controller.Runtim r.(*files.EtcFileSpec).TypedSpec().Contents, err = clusteradapter.IdentitySpec(&localIdentity).ConvertMachineID() r.(*files.EtcFileSpec).TypedSpec().Mode = 0o444 + r.(*files.EtcFileSpec).TypedSpec().SelinuxLabel = "system_u:object_r:etc_machine_id_t:s0" return err }); err != nil { diff --git a/internal/app/machined/pkg/controllers/files/cri_config_parts.go b/internal/app/machined/pkg/controllers/files/cri_config_parts.go index b32e7640188..3d86d0f295c 100644 --- a/internal/app/machined/pkg/controllers/files/cri_config_parts.go +++ b/internal/app/machined/pkg/controllers/files/cri_config_parts.go @@ -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 { diff --git a/internal/app/machined/pkg/controllers/files/cri_registry_config.go b/internal/app/machined/pkg/controllers/files/cri_registry_config.go index ccb15abe30c..9fefd20c779 100644 --- a/internal/app/machined/pkg/controllers/files/cri_registry_config.go +++ b/internal/app/machined/pkg/controllers/files/cri_registry_config.go @@ -119,6 +119,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 { diff --git a/internal/app/machined/pkg/controllers/files/etcfile.go b/internal/app/machined/pkg/controllers/files/etcfile.go index f0e16a03aff..ff23c06a41a 100644 --- a/internal/app/machined/pkg/controllers/files/etcfile.go +++ b/internal/app/machined/pkg/controllers/files/etcfile.go @@ -17,6 +17,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" ) @@ -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) } @@ -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) } diff --git a/internal/app/machined/pkg/controllers/network/etcfile.go b/internal/app/machined/pkg/controllers/network/etcfile.go index 80061ae7e51..fe4ca67cbd5 100644 --- a/internal/app/machined/pkg/controllers/network/etcfile.go +++ b/internal/app/machined/pkg/controllers/network/etcfile.go @@ -147,6 +147,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo 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 { @@ -167,7 +168,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo 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) } @@ -178,6 +179,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo 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 { diff --git a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go index 7fe5a5012b5..772596eff34 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go @@ -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" @@ -484,7 +485,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 @@ -1158,6 +1159,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 diff --git a/pkg/machinery/api/resource/definitions/files/files.pb.go b/pkg/machinery/api/resource/definitions/files/files.pb.go index a0bc6f1764f..8fb333ed87d 100644 --- a/pkg/machinery/api/resource/definitions/files/files.pb.go +++ b/pkg/machinery/api/resource/definitions/files/files.pb.go @@ -27,8 +27,9 @@ type EtcFileSpecSpec struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Contents []byte `protobuf:"bytes,1,opt,name=contents,proto3" json:"contents,omitempty"` - Mode uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"` + Contents []byte `protobuf:"bytes,1,opt,name=contents,proto3" json:"contents,omitempty"` + Mode uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"` + SelinuxLabel string `protobuf:"bytes,3,opt,name=selinux_label,json=selinuxLabel,proto3" json:"selinux_label,omitempty"` } func (x *EtcFileSpecSpec) Reset() { @@ -75,6 +76,13 @@ func (x *EtcFileSpecSpec) GetMode() uint32 { return 0 } +func (x *EtcFileSpecSpec) GetSelinuxLabel() string { + if x != nil { + return x.SelinuxLabel + } + return "" +} + // EtcFileStatusSpec describes status of rendered secrets. type EtcFileStatusSpec struct { state protoimpl.MessageState @@ -128,23 +136,25 @@ var file_resource_definitions_files_files_proto_rawDesc = []byte{ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x41, 0x0a, 0x0f, 0x45, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x66, 0x0a, 0x0f, 0x45, 0x74, 0x63, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, - 0x11, 0x45, 0x74, 0x63, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x53, 0x70, - 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x70, 0x65, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x70, 0x65, 0x63, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x74, 0x0a, 0x28, 0x64, 0x65, 0x76, 0x2e, 0x74, 0x61, 0x6c, - 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, - 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, - 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x23, 0x0a, + 0x0d, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x5f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x22, 0x36, 0x0a, 0x11, 0x45, 0x74, 0x63, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x53, 0x70, 0x65, 0x63, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x70, 0x65, 0x63, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, + 0x70, 0x65, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x74, 0x0a, 0x28, 0x64, 0x65, + 0x76, 0x2e, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, + 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, + 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/machinery/api/resource/definitions/files/files_vtproto.pb.go b/pkg/machinery/api/resource/definitions/files/files_vtproto.pb.go index dc848e4c242..3c9a516e2f7 100644 --- a/pkg/machinery/api/resource/definitions/files/files_vtproto.pb.go +++ b/pkg/machinery/api/resource/definitions/files/files_vtproto.pb.go @@ -49,6 +49,13 @@ func (m *EtcFileSpecSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.SelinuxLabel) > 0 { + i -= len(m.SelinuxLabel) + copy(dAtA[i:], m.SelinuxLabel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.SelinuxLabel))) + i-- + dAtA[i] = 0x1a + } if m.Mode != 0 { i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Mode)) i-- @@ -117,6 +124,10 @@ func (m *EtcFileSpecSpec) SizeVT() (n int) { if m.Mode != 0 { n += 1 + protohelpers.SizeOfVarint(uint64(m.Mode)) } + l = len(m.SelinuxLabel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } n += len(m.unknownFields) return n } @@ -217,6 +228,38 @@ func (m *EtcFileSpecSpec) UnmarshalVT(dAtA []byte) error { break } } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SelinuxLabel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SelinuxLabel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := protohelpers.Skip(dAtA[iNdEx:]) diff --git a/pkg/machinery/resources/files/etcfile_spec.go b/pkg/machinery/resources/files/etcfile_spec.go index c0178a858a1..e509141b3e8 100644 --- a/pkg/machinery/resources/files/etcfile_spec.go +++ b/pkg/machinery/resources/files/etcfile_spec.go @@ -27,8 +27,9 @@ type EtcFileSpec = typed.Resource[EtcFileSpecSpec, EtcFileSpecExtension] // //gotagsrewrite:gen type EtcFileSpecSpec struct { - Contents []byte `yaml:"contents" protobuf:"1"` - Mode fs.FileMode `yaml:"mode" protobuf:"2"` + Contents []byte `yaml:"contents" protobuf:"1"` + Mode fs.FileMode `yaml:"mode" protobuf:"2"` + SelinuxLabel string `yaml:"selinux_label" protobuf:"3"` } // NewEtcFileSpec initializes a EtcFileSpec resource. diff --git a/website/content/v1.9/reference/api.md b/website/content/v1.9/reference/api.md index 84c94f105c3..ed5f071e79b 100644 --- a/website/content/v1.9/reference/api.md +++ b/website/content/v1.9/reference/api.md @@ -2171,6 +2171,7 @@ EtcFileSpecSpec describes status of rendered secrets. | ----- | ---- | ----- | ----------- | | contents | [bytes](#bytes) | | | | mode | [uint32](#uint32) | | | +| selinux_label | [string](#string) | | |