diff --git a/README.md b/README.md index 34b5b73..fa7502d 100644 --- a/README.md +++ b/README.md @@ -60,15 +60,16 @@ the /etc/defaults/vms folder is deleted from the running VM (this has no effect ### Where to use: Basic examples After installing into a template, simply enable `vm-boot-protect-root` service without configuration. Recommended for the following types of VMs: - o Service VMs: sys-usb and sys-net. - o App VMs: untrusted, personal, banking, vault, etc. This assumes using regular Linux apps without tailored Qubes-specific settings in /rw such as *Firefox, Chromium, Thunderbird, KeePassX, office apps, media playback & editing*, etc. For these and many more, no configuration should be necessary. + * Service VMs: sys-usb and sys-net. + * App VMs: untrusted, personal, banking, vault, etc. This assumes using regular Linux apps without tailored Qubes-specific settings in /rw such as *Firefox, Chromium, Thunderbird, KeePassX, office apps, media playback & editing*, etc. For these and many more, no configuration should be necessary. Examples where `vm-boot-protect-root` requires configuration: sys-vpn (see Notes), Martus and Whonix (needs testing). Note that VMs sys-vpn and sys-firewall are fairly low-risk VMs so there may not be a compelling reason to use the service with them. Examples where -root should *not* be enabled: - o DispVMs. Sensible option is to enable sudo security for DispVM templates; service can be installed into template and left unused. - o Standalone VMs. Plain `vm-boot-protect` makes more sense for these. - o Non-Linux VMs (currently unsupported for any mode) + * DispVMs. Sensible option is to enable sudo security for DispVM templates; service can be installed into template and left unused. + * Whonix VMs. Plain `vm-boot-protect` is best used until Whonix persistence files can be mapped. + * Standalone VMs. Plain `vm-boot-protect` makes more sense for these. + * Non-Linux VMs (currently unsupported for any mode) ### Scope and Limitations @@ -94,6 +95,7 @@ Examples where -root should *not* be enabled: * Currently the service cannot seamlessly handle 'first boot' when the private volume must be initialized. If you enabled the service on a VM before its first startup, on first start the shell will display a notice telling you to restart the VM. Subsequent starts will proceed normally. ## Releases + - v0.8.4 Add protection to /home/user/.config/systemd - v0.8.3 Fix for install script copying to /etc/default/vms - v0.8.2 Working rescue shell. Add sys-net whitelist, sudo config, fixes. - v0.8.0 Adds protection to /rw, file SHA checksums, whitelists, deployment diff --git a/configure-sudo-prompt b/configure-sudo-prompt index 7993c64..fd28f8b 100644 --- a/configure-sudo-prompt +++ b/configure-sudo-prompt @@ -3,19 +3,27 @@ set -e [ `id -u` -eq 0 ] || exit -if [ ! -e /etc/debian_version ]; then - echo "Debian-based template required for autoconfiguration. -See qubes-os.org/doc/vm-sudo for manual instructions." + + +if [ ! -e /etc/sudoers.d/qubes ]; then + echo "The 'qubes-core-agent-passwordless-root' package does not appear" + echo "to be present or configured; sudo autoconfiguration skipped." exit 0 fi +if [ ! -e /etc/debian_version ]; then + echo "Debian-based template required for sudo autoconfiguration. +See https://qubes-os.org/doc/vm-sudo for manual instructions." + exit 1 +fi + echo -e "\n--+ Enable yes/no authentication prompt for sudo +-- Warning: Before opting for this change a backup or clone should me made of this template!" read -p "Configure sudo authentication prompt now? (y/n): " answer if [[ $answer == @(y|Y) ]]; then - mv -fb /etc/pam.d/common-auth /etc/pam.d/common-auth.bak + mv -fb /etc/pam.d/common-auth /etc/pam.d/common-auth~ cat >/etc/pam.d/common-auth <<_EOF auth [success=1 default=ignore] pam_exec.so seteuid /usr/lib/qubes/qrexec-client-vm dom0 qubes.VMAuth /bin/grep -q ^1$ auth requisite pam_deny.so @@ -30,9 +38,9 @@ _EOF sed -ri 's/^(auth[[:space:]]sufficient[[:space:]]pam_permit.so)/#\1/' /etc/pam.d/su mv -f /etc/polkit-1/rules.d/00-qubes-allow-all.rules \ - /etc/polkit-1/rulesd_00-qubes-allow-all.rules.bak + /etc/polkit-1/rulesd_00-qubes-allow-all.rules.bak || true mv -f /etc/polkit-1/localauthority/50-local.d/qubes-allow-all.pkla \ - /etc/polkit-1/localauthority_50-locald_qubes-allow-all.pkla.bak + /etc/polkit-1/localauthority_50-locald_qubes-allow-all.pkla.bak || true echo "Done." diff --git a/default/vms/sys-net.whitelist b/default/vms/sys-net.whitelist index 9007fd2..dbd0208 100644 --- a/default/vms/sys-net.whitelist +++ b/default/vms/sys-net.whitelist @@ -1 +1,2 @@ /rw/config/NM-system-connections/ +/rw/config/suspend-module-blacklist diff --git a/install b/install index cacec2b..45be4da 100644 --- a/install +++ b/install @@ -1,6 +1,6 @@ #!/bin/bash # From https://github.com/tasket/Qubes-VM-hardening -# installer version 0.8.3 +# installer version 0.8.4 set -e [ `id -u` -eq 0 ] || exit diff --git a/vm-boot-protect.service b/vm-boot-protect.service index d9094db..35b2b12 100644 --- a/vm-boot-protect.service +++ b/vm-boot-protect.service @@ -3,9 +3,6 @@ Description=Protect Qubes VM execution environment at startup Documentation=https://github.com/tasket/Qubes-VM-hardening After=qubes-sysinit.service Before=qubes-mount-dirs.service -ConditionPathExists=|/var/run/qubes-service/vm-boot-protect -ConditionPathExists=|/var/run/qubes-service/vm-boot-protect-root -ConditionPathExists=|/var/run/qubes-service/vm-boot-protect-cli DefaultDependencies=false #OnFailure=rescue.target #OnFailureJobMode=replace-irreversibly diff --git a/vm-boot-protect.sh b/vm-boot-protect.sh index 49345fa..749e0e5 100644 --- a/vm-boot-protect.sh +++ b/vm-boot-protect.sh @@ -2,7 +2,7 @@ ## Protect startup of Qubes VMs from /rw content ## ## https://github.com/tasket/Qubes-VM-hardening ## -## Copyright 2017-2018 Christopher Laprise ## +## Copyright 2017-2019 Christopher Laprise ## ## tasket@protonmail.com ## # This file is part of Qubes-VM-hardening. @@ -28,7 +28,7 @@ chfiles=".bashrc .bash_profile .bash_login .bash_logout .profile \ .xprofile .xinitrc .xserverrc .xsession" chdirs="bin .local/bin .config/autostart .config/plasma-workspace/env \ -.config/plasma-workspace/shutdown .config/autostart-scripts" +.config/plasma-workspace/shutdown .config/autostart-scripts .config/systemd" vmname=`qubesdb-read /name` dev=/dev/xvdb @@ -36,7 +36,7 @@ rw=/mnt/rwtmp rwbak=$rw/vm-boot-protect errlog=/var/run/vm-protect-error defdir=/etc/default/vms -version="0.8.2" +version="0.8.4" # Function: Make user scripts immutable. @@ -90,6 +90,10 @@ if ! is_rwonly_persistent; then if qsvc vm-boot-protect; then make_immutable fi + if ! is_template_vm; then + # Keep configs invisible for standalone vms + rm -rf "$defdir" + fi exit 0 # cannot use abort_startup() before this point fi @@ -100,24 +104,25 @@ if qsvc vm-boot-protect-cli; then abort_startup RELOCATE "CLI requested." fi -# Mount private volume in temp location -mkdir -p $rw -if [ -e $dev ] && mount -o ro $dev $rw ; then - echo "Good read-only mount." -else - echo "Mount failed." - # decide if this is initial boot or a bad volume - private_size_512=$(blockdev --getsz "$dev") - if head -c $(( private_size_512 * 512 )) /dev/zero | diff "$dev" - >/dev/null; then - touch /var/run/qubes/VM-BOOT-PROTECT-INITIALIZERW - abort_startup OK "FIRST BOOT INITIALIZATION: PLEASE RESTART VM!" +if qsvc vm-boot-protect || qsvc vm-boot-protect-root; then + # Mount private volume in temp location + mkdir -p $rw + if [ -e $dev ] && mount -o ro $dev $rw ; then + echo "Good read-only mount." else - abort_startup RELOCATE "Mount failed; BAD private volume!" + echo "Mount failed." + # decide if this is initial boot or a bad volume + private_size_512=$(blockdev --getsz "$dev") + if head -c $(( private_size_512 * 512 )) /dev/zero | diff "$dev" - >/dev/null; then + touch /var/run/qubes/VM-BOOT-PROTECT-INITIALIZERW + abort_startup OK "FIRST BOOT INITIALIZATION: PLEASE RESTART VM!" + else + abort_startup RELOCATE "Mount failed; BAD private volume!" + fi fi fi - # Protection measures for /rw dirs: # Activated by presence of vm-boot-protect-root Qubes service. # * Hashes in vms/vms.all.SHA and vms/$vmname.SHA files will be checked. @@ -215,14 +220,17 @@ if qsvc vm-boot-protect-root && is_rwonly_persistent; then echo "Copy files from $defdir/$vmset/rw" cp -af $defdir/$vmset/rw/* $rw fi - done - # Keep configs invisible at runtime... - rm -rf "$defdir" - fi -make_immutable -umount $rw +if qsvc vm-boot-protect || qsvc vm-boot-protect-root; then + make_immutable + umount $rw +fi + +# Keep configs invisible at runtime... +rm -rf "$defdir" + + exit 0