relabel-etc: Split remount into, remount and relabel-etc
Split these into two different binaries we two different resonsibilities. They don't share so much functionality.
Incomplete and untested right now
Hmm, why aren't we doing the relabeling from the initramfs instead? Current kernels allow relabeling before a policy is loaded. This is notably used by Ignition: https://github.com/coreos/ignition/blob/b2ea35258bf5367a3522a4bea7f71063954b740c/internal/exec/util/selinux.go#L80.
From my experience, doing relabeling from the real root causes a lot of issues and quickly becomes a game of whack-a-race condition.
Seems to work at first glance:
# https://gitlab.com/fedora/bootc/examples/-/blob/main/transient-etc/Containerfile
FROM quay.io/centos-bootc/centos-bootc:stream9
# Configure the initramfs, see https://github.com/ostreedev/ostree/blob/main/man/ostree-prepare-root.xml
RUN echo -e '[etc]\ntransient=true' >> /usr/lib/ostree/prepare-root.conf && \
set -x; kver=$(cd /usr/lib/modules && echo *); dracut -vf /usr/lib/modules/$kver/initramfs.img $kver
I bootc install to-disk the resulting image, boot it, add rd.break, and then from the switchroot shell:
$ chroot /sysroot setfiles -vF /etc/selinux/targeted/contexts/files/file_contexts /etc
Relabeled /etc from <no context> to system_u:object_r:etc_t:s0
Relabeled /etc/systemd/system from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/basic.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/default.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/getty.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/graphical.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/local-fs.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/multi-user.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/network-online.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/sockets.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/sysinit.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
Relabeled /etc/systemd/system/timers.target.wants from system_u:object_r:etc_t:s0 to system_u:object_r:systemd_unit_file_t:s0
(Though you'd normally add setfiles to your initrd and use -r /sysroot instead of doing a chroot.)
Relabeling from the initramfs indeed sounds way better. The only thing I'm a little uncertain about is the semantics for how e.g. selinux=0 or other flags for configuring it in the real root are handled. Maybe running setfiles handles this already?
I like the idea of using setfiles or something similar, less code to maintain...
I think selinux=0, etc. is easy to handle in systemd .service file:
ConditionKernelCommandLine=!selinux=0
We may be able to achieve this with zero C code here, just write a well crafted systemd .service file.
Although, I would rather we relabelled from rootfs, even if it meant running this .service file in it's own exclusive time slot.
We put a lot of effort in Automotive for example to make our initramfs super tiny like < 10M .
Ideally we wouldn't relabel on boot at all tbh, it's another thing to do during boot and again we are trying to cut down on doing tasks at boot to make that as fast as possible. Any reason we can't do this at image composition time or shutdown?
/.autorelabel for example seems to perform relabeling on shutdown
Ideally we wouldn't relabel on boot at all tbh, it's another thing to do during boot and again we are trying to cut down on doing tasks at boot to make that as fast as possible. Any reason we can't do this at image composition time or shutdown?
Automotive is using transient etc, this is about the in-memory inodes for the overlayfs. There's no real way to shortcut this today, we have a kind of complex interlock between selinux policy loading vs the mount.
However as far as the cost...slimming down what's in /etc by default will inherently make this cheaper.