From ecdb763ba2802c80a565ea35b6a5456b7bad33fd Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Fri, 12 Apr 2024 20:10:52 -0400 Subject: [PATCH] Allow logging in to rescue/emergency shell as root In Qubes OS guests, the console is _always_ the Xen console. There are _never_ untrusted entities with access to this under _any_ circumstances. The only supported way to get access to this from a VM is the admin.vm.Console service, which is (by design) equivalent to root access in the destination VM. Other consoles, such as a USB serial console, are not supported as domU consoles under Qubes OS. Therefore, set SYSTEMD_SULOGIN_FORCE=1 to tell systemd-sulogin-shell to pass --force to sulogin(8). Since the root account is locked in Qubes VMs, this causes sulogin(8) to allow login as root without a password. Use TTYPath= to enforce that the console is, in fact, the Xen console and not some other console, in case the assumption in the previous paragraph turns out false for some reason. This will break if the Xen drivers are not included in the guest kernel config, but an HVM guest with Qubes tools but no Xen drivers is not a supported configuration. --- Makefile | 2 +- boot/Makefile | 5 +++- boot/dracut-qubes.conf | 4 +++ boot/module-setup.sh | 10 +++++++ debian/qubes-core-agent.install | 3 ++ rpm_spec/core-agent.spec.in | 29 +++++++++++++++++++- vm-systemd/emergency.service.d/30_qubes.conf | 5 ++++ vm-systemd/rescue.service.d/30_qubes.conf | 5 ++++ 8 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 boot/module-setup.sh create mode 100644 vm-systemd/emergency.service.d/30_qubes.conf create mode 100644 vm-systemd/rescue.service.d/30_qubes.conf diff --git a/Makefile b/Makefile index 9848a8e8..7eadef04 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ SYSTEM_DROPINS += systemd-random-seed.service SYSTEM_DROPINS += tor.service tor@default.service SYSTEM_DROPINS += systemd-timesyncd.service SYSTEM_DROPINS += systemd-logind.service -SYSTEM_DROPINS += sysinit.target +SYSTEM_DROPINS += sysinit.target emergency.service rescue.service ifeq ($(ENABLE_SELINUX),1) SYSTEM_DROPINS += selinux-autorelabel.target selinux-autorelabel.service endif diff --git a/boot/Makefile b/boot/Makefile index c9b4123f..32a678b4 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -1,11 +1,14 @@ LIBDIR ?= /usr/lib SYSCONFDIR ?= /etc GRUBCONFDIR ?= $(SYSCONFDIR)/default -DRACUTCONFDIR ?= $(LIBDIR)/dracut/dracut.conf.d GRUBCFGNAME ?= grub.qubes +DRACUTDIR ?= $(LIBDIR)/dracut +DRACUTCONFDIR ?= $(DRACUTDIR)/dracut.conf.d +DRACUTMODDIR ?= $(DRACUTDIR)/modules.d .PHONY: install install: install -D -m 0644 grub.qubes $(DESTDIR)$(GRUBCONFDIR)/$(GRUBCFGNAME) install -D -m 0644 dracut-qubes.conf $(DESTDIR)$(DRACUTCONFDIR)/30-qubes.conf + install -D -m 0755 module-setup.sh $(DESTDIR)$(DRACUTMODDIR)/99qubes/module-setup.sh diff --git a/boot/dracut-qubes.conf b/boot/dracut-qubes.conf index ea6d6b69..ceeaa0a9 100644 --- a/boot/dracut-qubes.conf +++ b/boot/dracut-qubes.conf @@ -19,5 +19,9 @@ omit_dracutmodules+=" tpm2-tss " # drivers, and none of the boot screen is visible in a qube anyway omit_dracutmodules+=" plymouth " +# Include Qubes OS-specific module to enable passwordless login on the Xen +# console as root. +force_add_dracutmodules+=" qubes " + # Exclude microcode, as VM cannot load it anyway, saves over 10MB of space early_microcode="no" diff --git a/boot/module-setup.sh b/boot/module-setup.sh new file mode 100644 index 00000000..1278c2f5 --- /dev/null +++ b/boot/module-setup.sh @@ -0,0 +1,10 @@ +depends () { +} + +install () { + if [ -h /lib ]; then + inst_multiple /usr/lib/systemd/system/rescue.service.d/30_qubes.conf /usr/lib/systemd/system/emergency.service.d/30_qubes.conf + else + inst_multiple /lib/systemd/system/rescue.service.d/30_qubes.conf /lib/systemd/system/emergency.service.d/30_qubes.conf + fi +} diff --git a/debian/qubes-core-agent.install b/debian/qubes-core-agent.install index 3015aa9f..bf77c13e 100644 --- a/debian/qubes-core-agent.install +++ b/debian/qubes-core-agent.install @@ -107,6 +107,8 @@ lib/systemd/system/sysinit.target.d/30_qubes.conf lib/systemd/system/systemd-timesyncd.service.d/30_qubes.conf lib/systemd/system/systemd-logind.service.d/30_qubes.conf lib/systemd/resolved.conf.d/30_resolved-no-mdns-or-llmnr.conf +lib/systemd/system/rescue.service.d/30_qubes.conf +lib/systemd/system/emergency.service.d/30_qubes.conf usr/lib/sysctl.d/20-qubes-core.conf usr/lib/systemd/user/tracker-extract-3.service.d/30_qubes.conf usr/lib/systemd/user/tracker-miner-fs-3.service.d/30_qubes.conf @@ -139,6 +141,7 @@ usr/bin/qvm-connect-tcp usr/bin/qvm-sync-clock usr/lib/environment.d/60-gnome-software-fix.conf usr/lib/dracut/dracut.conf.d/30-qubes.conf +usr/lib/dracut/modules.d/99qubes/module-setup.sh usr/lib/python3/dist-packages/qubesagent-*.egg-info/* usr/lib/python3/dist-packages/qubesagent/* usr/lib/qubes-bind-dirs.d/30_cron.conf diff --git a/rpm_spec/core-agent.spec.in b/rpm_spec/core-agent.spec.in index 143dc02f..eacadb48 100644 --- a/rpm_spec/core-agent.spec.in +++ b/rpm_spec/core-agent.spec.in @@ -134,6 +134,7 @@ Requires: sed Requires: util-linux Requires: e2fsprogs Requires: hostname +Requires: (%{name}-dracut if dracut) # for Qubes Manager VM updater Requires: xterm # for qubes-desktop-run @@ -373,6 +374,19 @@ switching from user to root. Since all the user data in a VM is accessible already from normal user account, there is not much more to guard there. Qubes VMs are single user systems. +%package dracut +Summary: Dracut configuration needed in Qubes OS +License: GPL +Group: Qubes +Requires: dracut +Requires: qubes-core-agent = %{version} + +%description dracut +Dracut configuration useful for Qubes OS. This enables +passwordless login in rescue and emergency modes. Unlike the +configuration in qubes-kernel-vm-support, it isn't needed to +boot a VM, but it does make recovery of broken VMs easier. + %package thunar Summary: Thunar support for Qubes VM tools Requires: Thunar @@ -521,6 +535,10 @@ sed -i \ $RPM_BUILD_ROOT/etc/yum.repos.d/qubes-*.repo %endif +install -D -m 0644 boot/dracut-qubes.conf $RPM_BUILD_ROOT/usr/lib/dracut/dracut.conf.d/30-qubes.conf +install -D -m 0644 boot/grub.qubes $RPM_BUILD_ROOT/etc/default/grub.qubes +install -D -m 0755 boot/module-setup.sh $RPM_BUILD_ROOT/usr/lib/dracut/modules.d/99qubes/module-setup.sh + %if ! %with_sysvinit rm -rf $RPM_BUILD_ROOT/etc/init.d/qubes-* $RPM_BUILD_ROOT/etc/sysconfig/modules/qubes-core.modules %endif @@ -1026,7 +1044,7 @@ rm -f %{name}-%{version} /usr/lib/qubes/resize-rootfs /usr/lib/qubes/set-default-text-editor /usr/lib/qubes/tinyproxy-wrapper -/usr/lib/dracut/dracut.conf.d/30-qubes.conf + /usr/lib/environment.d/60-gnome-software-fix.conf %dir /usr/lib/qubes/init /usr/lib/qubes/init/bind-dirs.sh @@ -1096,6 +1114,11 @@ rm -f %{name}-%{version} /usr/share/caja-python/extensions/qvm_dvm_caja.py* %endif +%files dracut +/usr/lib/dracut/dracut.conf.d/30-qubes.conf +%dir /usr/lib/dracut/modules.d/99qubes +/usr/lib/dracut/modules.d/99qubes/module-setup.sh + %files nautilus /usr/share/nautilus-python/extensions/qvm_copy_nautilus.py* /usr/share/nautilus-python/extensions/qvm_move_nautilus.py* @@ -1304,6 +1327,10 @@ The Qubes core startup configuration for SystemD init. %dir %_unitdir/sysinit.target.d %_unitdir/sysinit.target.d/30_qubes.conf %dir %_userunitdir/*.service.d +%dir %_unitdir/rescue.service.d +%dir %_unitdir/emergency.service.d +%_unitdir/emergency.service.d/30_qubes.conf +%_unitdir/rescue.service.d/30_qubes.conf %_userunitdir/tracker-extract-3.service.d/30_qubes.conf %_userunitdir/tracker-miner-fs-3.service.d/30_qubes.conf %_userunitdir/tracker-miner-fs-control-3.service.d/30_qubes.conf diff --git a/vm-systemd/emergency.service.d/30_qubes.conf b/vm-systemd/emergency.service.d/30_qubes.conf new file mode 100644 index 00000000..edca8f42 --- /dev/null +++ b/vm-systemd/emergency.service.d/30_qubes.conf @@ -0,0 +1,5 @@ +[Service] +# Ensure that the console is the secure Xen console, +# not e.g. a serial console that is exposed to the outside world. +TTYPath=/dev/hvc0 +Environment=SYSTEMD_SULOGIN_FORCE=1 diff --git a/vm-systemd/rescue.service.d/30_qubes.conf b/vm-systemd/rescue.service.d/30_qubes.conf new file mode 100644 index 00000000..edca8f42 --- /dev/null +++ b/vm-systemd/rescue.service.d/30_qubes.conf @@ -0,0 +1,5 @@ +[Service] +# Ensure that the console is the secure Xen console, +# not e.g. a serial console that is exposed to the outside world. +TTYPath=/dev/hvc0 +Environment=SYSTEMD_SULOGIN_FORCE=1