diff --git a/files/system/etc/selinux/targeted/contexts/files/file_contexts.local b/files/system/etc/selinux/targeted/contexts/files/file_contexts.local new file mode 100644 index 0000000..541fc38 --- /dev/null +++ b/files/system/etc/selinux/targeted/contexts/files/file_contexts.local @@ -0,0 +1,2 @@ +/nix(/.*)? system_u:object_r:bin_t:s0 +/var/lib/nix-store(/.*)? system_u:object_r:bin_t:s0 diff --git a/files/system/etc/systemd/system/nix-daemon.service.d/selinux.conf b/files/system/etc/systemd/system/nix-daemon.service.d/selinux.conf new file mode 100644 index 0000000..1b14e8b --- /dev/null +++ b/files/system/etc/systemd/system/nix-daemon.service.d/selinux.conf @@ -0,0 +1,5 @@ +[Service] +# Run the daemon unconfined to avoid SELinux denials on the Nix store binaries. +SELinuxContext=system_u:system_r:unconfined_service_t:s0 +ExecStart= +ExecStart=/usr/bin/nix-daemon-wrapper.sh --daemon diff --git a/files/system/usr/bin/mount-nix.sh b/files/system/usr/bin/mount-nix.sh index 2dc3a43..b580557 100755 --- a/files/system/usr/bin/mount-nix.sh +++ b/files/system/usr/bin/mount-nix.sh @@ -14,6 +14,13 @@ copy_seed_store() { fi } +sync_missing_store() { + # Ensure any baked store paths exist in /var without clobbering user additions. + if command -v rsync >/dev/null 2>&1; then + rsync -aH --ignore-existing /usr/share/nix-store/store/ /var/lib/nix-store/store/ + fi +} + ensure_system_profile() { local seed_profile="/usr/share/nix-store/var/nix/profiles/system" local target_profile="/var/lib/nix-store/var/nix/profiles/system" @@ -21,7 +28,7 @@ ensure_system_profile() { mkdir -p /var/lib/nix-store/var/nix/profiles if { [ ! -e "$target_profile" ] || [ -L "$target_profile" ] && [ ! -e "$(readlink -f "$target_profile")" ]; } \ - && [ -e "$seed_profile" ]; then + && { [ -e "$seed_profile" ] || [ -L "$seed_profile" ]; }; then cp -a "$seed_profile" "$target_profile" fi } @@ -32,9 +39,14 @@ if ! mountpoint -q /nix; then fi ensure_system_profile + sync_missing_store mount --bind /var/lib/nix-store /nix - mount -o remount,bind,exec /nix + # Force an executable SELinux context on the bind mount so systemd can exec nix-daemon. + # Use a permissive fallback if the label option is rejected. + if ! mount -o remount,bind,exec,context=system_u:object_r:bin_t:s0 /nix 2>/dev/null; then + mount -o remount,bind,exec /nix + fi # Ensure daemon paths exist and labels are sane. if command -v systemd-tmpfiles >/dev/null 2>&1; then diff --git a/files/system/usr/bin/nix-daemon-wrapper.sh b/files/system/usr/bin/nix-daemon-wrapper.sh new file mode 100644 index 0000000..bf2cf58 --- /dev/null +++ b/files/system/usr/bin/nix-daemon-wrapper.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +exec /nix/var/nix/profiles/system/bin/nix-daemon "$@"