diff --git a/ic-os/components/early-boot/relabel-machine-id/guestos/relabel-machine-id.sh b/ic-os/components/early-boot/relabel-machine-id/guestos/relabel-machine-id.sh index 5227c8b287b..951b8ef05e9 100755 --- a/ic-os/components/early-boot/relabel-machine-id/guestos/relabel-machine-id.sh +++ b/ic-os/components/early-boot/relabel-machine-id/guestos/relabel-machine-id.sh @@ -2,4 +2,5 @@ # machine-id is set up in initramfs and bind-mounted over to the rootfs. Since # policy is not loaded in initramfs yet, it has wrong security context. +systemd-machine-id-setup --commit restorecon -v /etc/machine-id diff --git a/ic-os/components/early-boot/relabel-machine-id/relabel-machine-id.sh b/ic-os/components/early-boot/relabel-machine-id/relabel-machine-id.sh index 7adda9e3e1c..676977661f7 100755 --- a/ic-os/components/early-boot/relabel-machine-id/relabel-machine-id.sh +++ b/ic-os/components/early-boot/relabel-machine-id/relabel-machine-id.sh @@ -4,4 +4,5 @@ # over to the rootfs. Since policy is not loaded in initramfs yet, it has # wrong security context. Fix this up, but ignore failures (this will not # work on first boot). +systemd-machine-id-setup --commit restorecon -v /etc/machine-id || true diff --git a/ic-os/components/init/bootstrap-ic-node/guestos/bootstrap-ic-node.sh b/ic-os/components/init/bootstrap-ic-node/guestos/bootstrap-ic-node.sh index c84b7d5ed19..c8e2d111e91 100755 --- a/ic-os/components/init/bootstrap-ic-node/guestos/bootstrap-ic-node.sh +++ b/ic-os/components/init/bootstrap-ic-node/guestos/bootstrap-ic-node.sh @@ -171,7 +171,7 @@ while [ ! -f /boot/config/CONFIGURED ]; do fi # Fix up permissions. This is actually the wrong place. - chown ic-replica.nogroup -R /var/lib/ic/data + chown ic-replica:nogroup -R /var/lib/ic/data if [ "${DEV}" != "" ]; then umount /mnt diff --git a/ic-os/components/init/setup-encryption/guestos/setup-encryption.service b/ic-os/components/init/setup-encryption/guestos/setup-encryption.service index 21289438497..71d7ee03624 100644 --- a/ic-os/components/init/setup-encryption/guestos/setup-encryption.service +++ b/ic-os/components/init/setup-encryption/guestos/setup-encryption.service @@ -3,11 +3,11 @@ Description=Set up encrypted storage on first boot DefaultDependencies=no After=boot-config.mount Requires=boot-config.mount -Before=systemd-cryptsetup@vda10\x2dcrypt.service +Before=cryptsetup-pre.target +Wants=cryptsetup-pre.target [Install] WantedBy=local-fs.target -RequiredBy=systemd-cryptsetup@vda10\x2dcrypt.service [Service] Type=oneshot diff --git a/ic-os/components/misc/guestos/crypttab b/ic-os/components/misc/guestos/crypttab index 28c8b90f03a..b0b8264d509 100644 --- a/ic-os/components/misc/guestos/crypttab +++ b/ic-os/components/misc/guestos/crypttab @@ -1 +1 @@ -vda10-crypt /dev/vda10 /boot/config/store.keyfile luks2,discard +vda10-crypt /dev/vda10 /boot/config/store.keyfile luks,discard diff --git a/ic-os/components/networking/generate-network-config/guestos/generate-network-config.service b/ic-os/components/networking/generate-network-config/guestos/generate-network-config.service index a2438589810..33f6fc57ef4 100644 --- a/ic-os/components/networking/generate-network-config/guestos/generate-network-config.service +++ b/ic-os/components/networking/generate-network-config/guestos/generate-network-config.service @@ -1,6 +1,7 @@ [Unit] Description=Generate network config After=bootstrap-ic-node.service +Requires=bootstrap-ic-node.service Before=systemd-networkd.service [Install] diff --git a/ic-os/components/selinux/filebeat/filebeat.te b/ic-os/components/selinux/filebeat/filebeat.te index a80d09c5eb9..2a456d9509b 100644 --- a/ic-os/components/selinux/filebeat/filebeat.te +++ b/ic-os/components/selinux/filebeat/filebeat.te @@ -41,6 +41,7 @@ init_daemon_domain(filebeat_t, filebeat_exec_t) # Allow filebeat to perform its primary function, namely to read # the journal files. systemd_read_journal_files(filebeat_t) +systemd_watch_journal_dirs(filebeat_t) # It wants to send the logs to remote host, allow unrestricted TCP for # this for now. Maybe this can be reasonably constrained more tightly. @@ -56,6 +57,7 @@ corenet_all_recvfrom_unlabeled(filebeat_t) # Read generic etc files (e.g. nsswitch.conf) files_read_etc_files(filebeat_t) +files_read_etc_runtime_files(filebeat_t) # Read CA certificate miscfiles_read_generic_certs(filebeat_t) @@ -124,6 +126,7 @@ require { search_dirs_pattern(filebeat_t, bin_t, bin_t) # Allow to read `/sys/fs/cgroup/unified/system.slice/filebeat.service/cgroup.controllers` +require { type cgroup_t; } fs_read_cgroup_files(filebeat_t) allow filebeat_t cgroup_t:dir read; diff --git a/ic-os/components/selinux/ic-node/ic-node.te b/ic-os/components/selinux/ic-node/ic-node.te index ba93005d723..3feaab8fc3b 100644 --- a/ic-os/components/selinux/ic-node/ic-node.te +++ b/ic-os/components/selinux/ic-node/ic-node.te @@ -322,6 +322,7 @@ allow ic_canister_sandbox_t ic_canister_mem_t : file { map read write getattr }; allow ic_replica_t ic_canister_mem_t : file { map read write getattr }; # Wants to read its own control group. Should deny that. +require { type cgroup_t; } dontaudit ic_canister_sandbox_t cgroup_t : dir { search }; dontaudit ic_canister_sandbox_t cgroup_t : file { open read getattr }; diff --git a/ic-os/components/selinux/manageboot/manageboot.te b/ic-os/components/selinux/manageboot/manageboot.te index f6ca4bf9c9a..c1a5d472c57 100644 --- a/ic-os/components/selinux/manageboot/manageboot.te +++ b/ic-os/components/selinux/manageboot/manageboot.te @@ -22,7 +22,7 @@ application_domain(ic_manageboot_t, ic_manageboot_exec_t) # write upgrades into partition). Allow entering sudo, and return # to the original domain when sudo re-executes the script (so # it is now running same domain, but with root privileges). -sudo_role_template(ic_manageboot, system_r, ic_manageboot_t) +sudo_role_template(ic_manageboot, ic_manageboot_t, ic_manageboot_exec_t, system_r) domtrans_pattern(ic_manageboot_sudo_t, ic_manageboot_exec_t, ic_manageboot_t) # Under certain circumstances, sudo signals its children. allow ic_manageboot_sudo_t ic_manageboot_t : process { signal }; @@ -123,7 +123,7 @@ allow ic_manageboot_t ic_manageboot_t : unix_stream_socket { connect create geta # Allow searching runtime process directories (/var/run which is symlinked to /run). # It is not perfectly clear what/why it is doing that, but it is harmless # enough. May to to forbid it and see if it still works. -files_search_pids(ic_manageboot_t) +files_search_runtime(ic_manageboot_t) # Allow reading /opt/ic/share/version.txt -read_files_pattern(ic_manageboot_t, usr_t, usr_t) \ No newline at end of file +read_files_pattern(ic_manageboot_t, usr_t, usr_t) diff --git a/ic-os/components/selinux/misc-fixes/misc-fixes.te b/ic-os/components/selinux/misc-fixes/misc-fixes.te index d10be1c1cd3..3ebfe2d2fbd 100644 --- a/ic-os/components/selinux/misc-fixes/misc-fixes.te +++ b/ic-os/components/selinux/misc-fixes/misc-fixes.te @@ -15,12 +15,16 @@ permissive unconfined_t; require { type lvm_t; } # Note that "cryptsetup" is also running as lvm_t. +require { type initrc_t, initrc_runtime_t; } +allow lvm_t initrc_t : sem rw_sem_perms; # cryptsetup needs to create /run/cryptsetup: This is its lockfile directory to # track which devices, which is the lockfile directory tracking devices on # which operations are in progress -require { type var_run_t; } +require { type var_run_t, initrc_runtime_t; } create_dirs_pattern(lvm_t, var_run_t, var_run_t) +manage_dirs_pattern(lvm_t, initrc_runtime_t, initrc_runtime_t) +manage_files_pattern(lvm_t, initrc_runtime_t, initrc_runtime_t) # lvm cryptsetup needs to manage its own cryptographic keys allow lvm_t lvm_t : key manage_key_perms; diff --git a/ic-os/components/selinux/systemd-fixes/systemd-fixes.te b/ic-os/components/selinux/systemd-fixes/systemd-fixes.te index 74ce4a9d88b..8e25d3ed91c 100644 --- a/ic-os/components/selinux/systemd-fixes/systemd-fixes.te +++ b/ic-os/components/selinux/systemd-fixes/systemd-fixes.te @@ -119,6 +119,13 @@ list_dirs_pattern(systemd_tmpfiles_t, unlabeled_t, unlabeled_t) # A tempfile is used as part of setting up machine-id read_files_pattern(systemd_tmpfiles_t, tmpfs_t, tmpfs_t) +############################################################################### +# systemd-generator + +# systemd_generator_t is missing this permission, and it blocks ssh +require { type systemd_generator_t; } +init_delete_runtime_files(systemd_generator_t) + ############################################################################### # udev @@ -146,6 +153,12 @@ systemd_connect_userdb(local_login_t) # ssh also needs access to userdb systemd_connect_userdb(sshd_t) +############################################################################### +# systemd-notify + +require { type systemd_runtime_notify_t; } +allow sshd_t systemd_runtime_notify_t : sock_file write_sock_file_perms; + ############################################################################### # pcscd diff --git a/ic-os/guestos/context/Dockerfile b/ic-os/guestos/context/Dockerfile index 558be824084..b58fac48b86 100644 --- a/ic-os/guestos/context/Dockerfile +++ b/ic-os/guestos/context/Dockerfile @@ -32,14 +32,14 @@ RUN sed -e '/.*pam_motd.so.*/d' -i /etc/pam.d/login && \ # but this is per system (so backups are not persisted across upgrades) # and thus not very useful, and /etc is read-only. # So simply suppress generating backups. -RUN sed -e 's/\(backup *= *\)1/\10/' -e 's/\(archive *= *\)1/\10/' -i /etc/lvm/lvm.conf +RUN sed -e 's/\(# \)\?\(backup *= *\)[01]/\20/' -e 's/\(# \)\?\(archive *= *\)[01]/\20/' -i /etc/lvm/lvm.conf # Deactivate systemd userdb. We don't use it. RUN sed -e 's/ *systemd//' -i /etc/nsswitch.conf # Clear files that may lead to indeterministic build. RUN apt-get clean && \ - find /usr/lib/python3.8 -name "*.pyc" | xargs rm && \ + find /usr/lib/python3.12 -name "*.pyc" | xargs rm && \ find /usr/lib/python3 -name "*.pyc" | xargs rm && \ find /usr/share/python3 -name "*.pyc" | xargs rm && \ truncate --size 0 /etc/machine-id @@ -96,6 +96,7 @@ RUN \ RUN systemctl enable \ chrony \ nftables \ + ssh \ systemd-networkd \ systemd-networkd-wait-online \ systemd-resolved \ @@ -111,10 +112,6 @@ RUN systemctl disable \ fstrim.service \ fstrim.timer -# Clear additional files that may lead to indeterministic build. -RUN find /usr/local/share/fonts -name .uuid | xargs rm && \ - find /usr/share/fonts -name .uuid | xargs rm - # ------ GUESTOS WORK -------------------------------------------- # Divert symbolic link for dynamically generated nftables @@ -129,19 +126,8 @@ RUN mkdir -p /var/lib/ic/backup \ # Create two mount points for temporary use during setup of "var" partition RUN mkdir -p /mnt/var_old /mnt/var_new -# Add user/group entries specified here: /usr/lib/sysusers.d/systemd.conf E.g., systemd-timesync/coredump. -## `systemd-sysusers` does not honor the SOURCE_DATE_EPOCH env var. -## With `podman --timestamp=0` each file gets written with timestamp of the Unix epoch. -## When systemd-sysusers writes the shadow entry for these users, the 2nd field in the row (# days since the epoch) is set to (today - unix epoch). -## This is not reproducible. -## Reset the passwords to the locked password ("!!"). `usermod` honors SOURCE_DATE_EPOCH (set in the base dockerfile). This removes the password timestamp. -## Why not use `faketime`? Doesn't work with `podman --timestamp=0`. -RUN systemd-sysusers && \ - usermod -p '!!' systemd-timesync && \ - usermod -p '!!' systemd-coredump - # Set /bin/sh to point to /bin/bash instead of the default /bin/dash -RUN echo "set dash/sh false" | debconf-communicate && dpkg-reconfigure -fnoninteractive dash +RUN ln -sf /bin/bash /usr/bin/sh # Group accounts to which parts of the runtime state are assigned such that # user accounts can be granted individual access rights. diff --git a/ic-os/guestos/context/docker-base.dev b/ic-os/guestos/context/docker-base.dev index bc4770b78b1..0f80960a58b 100644 --- a/ic-os/guestos/context/docker-base.dev +++ b/ic-os/guestos/context/docker-base.dev @@ -1 +1 @@ -ghcr.io/dfinity/guestos-base-dev@sha256:bd3cc2296731e78191dbf8a989b5809e102230de5fe509548e944632a97bd5cb +ghcr.io/dfinity/guestos-base-dev@sha256:44a7c40d4844d1f8e89e6bc57398c1a98fb03d37cbb354df30ce7a1888773dc4 diff --git a/ic-os/guestos/context/docker-base.prod b/ic-os/guestos/context/docker-base.prod index e527445d911..e42220484ac 100644 --- a/ic-os/guestos/context/docker-base.prod +++ b/ic-os/guestos/context/docker-base.prod @@ -1 +1 @@ -ghcr.io/dfinity/guestos-base@sha256:0a485d2d033df5aa7efd4ccbaad432c29d18f0f165cdcbeed5d49790c0d16340 +ghcr.io/dfinity/guestos-base@sha256:3811f91a3cd09f7fbf1b431578a19c7aa328fafa8ebd9a7819d0fb51454bf7fc diff --git a/rs/tests/driver/src/driver/group.rs b/rs/tests/driver/src/driver/group.rs index 86a26dffee3..9b0012a3b76 100644 --- a/rs/tests/driver/src/driver/group.rs +++ b/rs/tests/driver/src/driver/group.rs @@ -1108,6 +1108,12 @@ async fn stream_journald_from_cursor( cursor, stream.write_all(b"Accept: application/json\n").await ); + unwrap_or_return!( + cursor, + stream + .write_all(format!("Host: {ipv6}:19531\n").as_bytes()) + .await + ); unwrap_or_return!( cursor, stream diff --git a/rs/tests/driver/src/util.rs b/rs/tests/driver/src/util.rs index 03cc9e7cee4..831d8ddf5be 100644 --- a/rs/tests/driver/src/util.rs +++ b/rs/tests/driver/src/util.rs @@ -1477,7 +1477,9 @@ impl LogStream { // Use plaintext instead of json, because some messages are too large for the journal json serializer stream - .write_all(b"GET /entries?follow HTTP/1.1\n\r\n\r") + .write_all( + format!("GET /entries?follow HTTP/1.1\r\nHost:{ip_addr}:19531\r\n\r\n").as_bytes(), + ) .await?; let bf = BufReader::new(stream);