maintain selinux attributes into the erofs build
This commit is contained in:
@@ -95,7 +95,7 @@ jobs:
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
qemu-system-x86 qemu-utils libguestfs-tools linux-image-generic \
|
||||
erofs-utils cryptsetup-bin jq systemd-ukify systemd-boot-efi \
|
||||
buildah shellcheck
|
||||
buildah shellcheck attr
|
||||
sudo chmod 0644 /boot/vmlinuz-* 2>/dev/null || true
|
||||
|
||||
-
|
||||
|
||||
@@ -52,7 +52,8 @@ shellcheck --exclude=SC1091,SC2154 files/dracut/95dot1x-macsec/*.sh scripts/*.sh
|
||||
Build-host deps: qemu-kvm, libguestfs-tools (+ a kernel for its supermin
|
||||
appliance), erofs-utils, cryptsetup, jq, systemd-ukify **and systemd-boot-efi**
|
||||
(the latter ships the `linuxx64.efi.stub` ukify needs), sbsigntools,
|
||||
buildah (or docker).
|
||||
buildah (or docker), **attr** (`getfattr` — `extract-artifacts.sh` asserts the
|
||||
SELinux labels survived the export; an unlabeled enforcing root denies login).
|
||||
|
||||
## Architecture invariants — do not violate these
|
||||
|
||||
|
||||
+24
-2
@@ -99,9 +99,19 @@ is the tmpfs overlay), fleet-generic (no per-host state).
|
||||
e.g. a tightly-constrained kiosk session + documented deviation — when
|
||||
hardening lands.
|
||||
|
||||
## [~] 5. Deploy & validate the end-to-end boot path (open-network test)
|
||||
## [x] 5. Deploy & validate the end-to-end boot path (open-network test)
|
||||
|
||||
In progress. Stand up `serving/` (dnsmasq + nginx + SPDK) per
|
||||
✅ **DONE (2026-06-15).** Full chain validated on QEMU/Proxmox: UEFI HTTP boot →
|
||||
initramfs → DHCP → `nvmf-connect.service` auto-connects the NVMe/TCP subsystem →
|
||||
two namespaces (data + verity hash) appear by pinned UUID → `systemd-veritysetup`
|
||||
maps `/dev/mapper/root` → uncompressed erofs mounts → `systemd.volatile=overlay`
|
||||
→ multi-user. Booted with `rd.dot1x=0` (open network) and the IP discovery
|
||||
address. See bench findings below for the full list of fixes. Remaining cleanup
|
||||
to leave the lab-test posture (now unblocked): revert the hardcoded IP to the
|
||||
`nvme.fleet.lab` DNS name, and re-enable security (`DISABLE_DOT1X=false`) — the
|
||||
secure path needs the same connect trigger over macsec0 (see ⚠ note below).
|
||||
|
||||
Original task: stand up `serving/` (dnsmasq + nginx + SPDK) per
|
||||
[serving/README.md](../serving/README.md), rebuild the UKI with
|
||||
`nvmet_traddr=nvme.fleet.lab` (now a Packer var — older UKIs have the literal
|
||||
`NVMET_TRADDR` placeholder and won't connect), then boot a UEFI HTTP-boot client
|
||||
@@ -185,6 +195,18 @@ boot LAN.
|
||||
`systemd.verity_root_data=`/`systemd.verity_root_hash=` by-id devices with no
|
||||
offset. Touches `extract-artifacts.sh`, `build-oci.sh` (artifact list +
|
||||
SHA256SUMS), `serving/spdk-setup.sh` (2nd bdev/namespace), and invariant #9.
|
||||
- **SELinux labels must survive into the erofs.** It booted to multi-user but
|
||||
`root`/`packer-build-only` login was accepted then the session was killed
|
||||
instantly. Cause: kickstart sets `selinux --enforcing`, but the build dropped
|
||||
`security.selinux` xattrs (`virt-tar-out` + plain `tar -xpf` don't carry
|
||||
them), so the enforcing target denied the login session on an unlabeled root
|
||||
— and a read-only erofs can't autorelabel. Confirmed by booting with
|
||||
`enforcing=0` (SMBIOS-injected) → login worked. **Fixed:** export via
|
||||
`guestfish tar-out … selinux:true xattrs:true acls:true`, restore with
|
||||
`tar --xattrs --xattrs-include='*' --acls --selinux`, and a `getfattr`
|
||||
build-time assertion that `/usr/bin/bash` is labeled before `mkfs.erofs`
|
||||
(mkfs.erofs preserves xattrs). Needs `attr` on the build host. The image now
|
||||
boots **enforcing**.
|
||||
**⚠ The secure path has the same dependency on the
|
||||
(absent) nvmf autoconnect** — when 802.1X is re-enabled, the macsec0 path
|
||||
must likewise drive `connect-all` (or the network-manager port #1 must wire
|
||||
|
||||
@@ -37,7 +37,7 @@ ROOT_HASH_UUID=${ROOT_HASH_UUID:-f1ee7000-0000-4000-8000-000000000002}
|
||||
ROOT_DATA_DEV="/dev/disk/by-id/nvme-uuid.${ROOT_DATA_UUID}"
|
||||
ROOT_HASH_DEV="/dev/disk/by-id/nvme-uuid.${ROOT_HASH_UUID}"
|
||||
|
||||
for bin in virt-copy-out virt-tar-out virt-ls mkfs.erofs veritysetup jq; do
|
||||
for bin in virt-copy-out virt-ls guestfish mkfs.erofs veritysetup jq getfattr; do
|
||||
command -v "$bin" >/dev/null || { echo "ERROR: $bin not found on build host" >&2; exit 1; }
|
||||
done
|
||||
|
||||
@@ -54,12 +54,29 @@ virt-copy-out -a "$QCOW2" "/boot/$KERNEL" "/boot/initramfs-generic.img" "$OUT/"
|
||||
mv "$OUT/$KERNEL" "$OUT/vmlinuz"
|
||||
mv "$OUT/initramfs-generic.img" "$OUT/initramfs.img"
|
||||
|
||||
echo "==> Exporting root tree"
|
||||
virt-tar-out -a "$QCOW2" / "$WORK/rootfs.tar"
|
||||
echo "==> Exporting root tree (preserving SELinux labels + xattrs)"
|
||||
# SELinux labels MUST survive into the erofs, or the enforcing target denies the
|
||||
# login session — you authenticate, then logind kills the session, and a
|
||||
# read-only erofs can't autorelabel to fix itself. guestfish tar-out with
|
||||
# selinux:true/xattrs:true captures security.selinux; the extraction restores it
|
||||
# (--xattrs), and mkfs.erofs preserves xattrs into the image. (The old
|
||||
# virt-tar-out + plain `tar -xpf` dropped the labels — that was the login bug.)
|
||||
guestfish --ro -a "$QCOW2" -i \
|
||||
tar-out / "$WORK/rootfs.tar" numericowner:true xattrs:true selinux:true acls:true
|
||||
mkdir "$WORK/root"
|
||||
tar -C "$WORK/root" --numeric-owner -xpf "$WORK/rootfs.tar"
|
||||
tar -C "$WORK/root" --numeric-owner --xattrs --xattrs-include='*' --acls --selinux \
|
||||
-xpf "$WORK/rootfs.tar"
|
||||
rm -rf "$WORK/root/boot/"* "$WORK/rootfs.tar" # diskless hosts don't need /boot
|
||||
|
||||
# Fail loudly if labels didn't make it — shipping an unlabeled enforcing image
|
||||
# boots but denies all logins (the symptom we just chased down).
|
||||
if ! getfattr -h -n security.selinux "$WORK/root/usr/bin/bash" >/dev/null 2>&1; then
|
||||
echo "ERROR: SELinux label missing on /usr/bin/bash in the extracted tree." >&2
|
||||
echo " An enforcing boot would deny login. Check guestfish/tar xattr flags." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "==> SELinux labels preserved (bash: $(getfattr -h --only-values -n security.selinux "$WORK/root/usr/bin/bash" 2>/dev/null))"
|
||||
|
||||
echo "==> Building reproducible erofs image"
|
||||
# UNCOMPRESSED on purpose: the target Rocky 9 kernel's erofs is built without
|
||||
# CONFIG_EROFS_FS_ZIP, so mounting a compressed image fails at boot with
|
||||
|
||||
Reference in New Issue
Block a user