diff --git a/README.md b/README.md index ff862a9..b6300b0 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,10 @@ Leverage Qubes template non-persistence to fend off malware at VM startup: Lock- **Deployment** files are copied _recursively_ from ../vms/vms.all/rw/ and ../vms/$vmname/rw/ dirs. Example is to place the .bashrc file in /etc/default/vms/vms.all/rw/home/user/.bashrc for deployment to /rw/home/user/.bashrc. Once copying is complete, the /etc/defaults/vms folder is deleted from the running VM (this has no effect on the original in the template). + **rc files** are sh script fragments sourced from ../vms/vms.all.rc and ../vms/$vmname.rc. They run near the beginning of the vm-boot-protect service before mounting /rw, and can be used to override variable definitions like `privdirs` as well as the `vm_boot_finish` function which runs near the end before dismount. Another use for rc files is to run threat detection tools such as antivirus. + + **Tags** may be defined with all of the above features so that you are not limited to specifying them for either all VMs or specifically-named VMs. Simply configure them as you would acccording to the above directions, but place the files under the '@tags' subdir instead. For example '/etc/default/vms/@tags/special.whitelist' defines a whitelist for the tag 'special'. A tag can be activated for one or more VMs by adding a Qubes service prefixed with `vm-boot-tag-` (i.e. vm-boot-tag-special) to the VMs. + ### 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: @@ -82,6 +86,8 @@ Examples where -root should *not* be enabled: ### Notes + * The /rw/home directory can be added to `privdirs` so it is quarrantined much like /rw/config, /rw/binddirs and /rw/usrlocal. The easiest way to configure this is to define `privdirs_add=/rw/home` in an rc file or a drop-in for the vm-boot-protect.service. But in the case of /rw/home, the /rw/home/user folder will be repopulated automatically from OS defaults (usually in /etc/skel) before whitelists are applied. For an example, see the `ibrowse` tag which quarrantines home while whitelisting Firefox bookmarks. + * A bug in v0.8.4 will erase anything in '/etc/default/vms' when booting into the template. For proper future operation with sys-net or other VMs you may have customized in that path, updating Qubes-VM-hardening to the latest version (using the install script) is recommended, along with restoring any custom files @@ -98,6 +104,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.9.0 Add tags and rc files, protect more home scripts, support home quarrantine - v0.8.5 Fix template detection, /etc/default/vms erasure - v0.8.4 Add protection to /home/user/.config/systemd - v0.8.3 Fix for install script copying to /etc/default/vms diff --git a/default/vms/@tags/ibrowse.rc b/default/vms/@tags/ibrowse.rc new file mode 100644 index 0000000..b26ec82 --- /dev/null +++ b/default/vms/@tags/ibrowse.rc @@ -0,0 +1 @@ +privdirs_add="/rw/home" diff --git a/default/vms/@tags/ibrowse.whitelist b/default/vms/@tags/ibrowse.whitelist new file mode 100644 index 0000000..9f17a0f --- /dev/null +++ b/default/vms/@tags/ibrowse.whitelist @@ -0,0 +1,3 @@ +/rw/home/user/.mozilla/firefox/profile.default/places.sqlite +/rw/home/user/.mozilla/firefox/profile.default/places.sqlite-shm +/rw/home/user/.mozilla/firefox/profile.default/places.sqlite-wal diff --git a/default/vms/@tags/network.whitelist b/default/vms/@tags/network.whitelist new file mode 100644 index 0000000..dbd0208 --- /dev/null +++ b/default/vms/@tags/network.whitelist @@ -0,0 +1,2 @@ +/rw/config/NM-system-connections/ +/rw/config/suspend-module-blacklist diff --git a/default/vms/@tags/usb.rc b/default/vms/@tags/usb.rc new file mode 100644 index 0000000..b26ec82 --- /dev/null +++ b/default/vms/@tags/usb.rc @@ -0,0 +1 @@ +privdirs_add="/rw/home" diff --git a/default/vms/sys-net.whitelist b/default/vms/sys-net.whitelist deleted file mode 100644 index dbd0208..0000000 --- a/default/vms/sys-net.whitelist +++ /dev/null @@ -1,2 +0,0 @@ -/rw/config/NM-system-connections/ -/rw/config/suspend-module-blacklist diff --git a/default/vms/sys-net.whitelist b/default/vms/sys-net.whitelist new file mode 120000 index 0000000..0fec9b6 --- /dev/null +++ b/default/vms/sys-net.whitelist @@ -0,0 +1 @@ +@tags/network.whitelist \ No newline at end of file diff --git a/vm-boot-protect.sh b/vm-boot-protect.sh index ab1b1c5..bee816b 100755 --- a/vm-boot-protect.sh +++ b/vm-boot-protect.sh @@ -29,16 +29,16 @@ rw=/mnt/rwtmp rwbak=$rw/vm-boot-protect errlog=/var/run/vm-protect-error defdir=/etc/default/vms -version="0.9.0b" +version="0.9.0" # Define sh, bash, X and desktop init scripts in /home/user # to be protected chfiles=${chfiles:-".bashrc .bash_profile .bash_login .bash_logout .profile \ .pam_environment .xprofile .xinitrc .xserverrc .Xsession .xsession .xsessionrc"} -chfiles_add="" +chfiles_add=${chfiles_add:-""} chdirs=${chdirs:-"bin .local/bin .config/autostart .config/plasma-workspace/env \ .config/plasma-workspace/shutdown .config/autostart-scripts .config/systemd"} -chdirs_add="" +chdirs_add=${chdirs_add:-""} # Define dirs to apply quarrantine / whitelists privdirs=${privdirs:-"/rw/config /rw/usrlocal /rw/bind-dirs"} @@ -112,14 +112,6 @@ abort_startup() { } -# Run rc file commands if they exist -for rcbase in vms.all $tags $vmname; do - if [ -e "$defdir/$rcbase.rc" ]; then - . "$defdir/$rcbase.rc" - fi -done - - echo >$errlog # Clear if qsvc vm-boot-protect-cli; then @@ -145,7 +137,6 @@ if qsvc vm-boot-protect || qsvc vm-boot-protect-root; then # Don't bother with root protections in template or standalone if ! is_rwonly_persistent; then - vm_boot_finish make_immutable exit 0 fi @@ -161,6 +152,13 @@ fi if qsvc vm-boot-protect-root && is_rwonly_persistent; then + # Run rc file commands if they exist + for rcbase in vms.all $tags $vmname; do + if [ -e "$defdir/$rcbase.rc" ]; then + . "$defdir/$rcbase.rc" + fi + done + # Check hashes checkcode=0 for sha_base in $vmname $tags vms.all; do @@ -187,7 +185,8 @@ if qsvc vm-boot-protect-root && is_rwonly_persistent; then # Files mutable for del/copy operations cd $rw/home/user - chattr -R -f -i $chfiles $chfiles_add $chdirs $chdirs_add $privdirs $privdirs_add + chattr -R -f -i $chfiles $chfiles_add $chdirs $chdirs_add $privdirs $privdirs_add \ + $rwbak/BAK-* cd /root @@ -202,7 +201,7 @@ if qsvc vm-boot-protect-root && is_rwonly_persistent; then mv "$bakdir" "$origdir" fi if [ -e "$bakdir" ]; then - chattr -R -i "$bakdir" + #chattr -R -i "$bakdir" rm -rf "$bakdir" fi mv "$rw/$subdir" "$bakdir" @@ -215,7 +214,6 @@ if qsvc vm-boot-protect-root && is_rwonly_persistent; then rm -rf /home/user $rw/home/user mount --bind $rw/home /home mkhomedir_helper user - #mv /home/user $rw/home umount /home ;; esac @@ -258,6 +256,8 @@ if qsvc vm-boot-protect-root && is_rwonly_persistent; then fi done + vm_boot_finish + fi # Keep configs invisible at runtime... @@ -265,7 +265,6 @@ rm -rf "$defdir" if qsvc vm-boot-protect || qsvc vm-boot-protect-root; then echo "Preparing for unmount" - vm_boot_finish make_immutable umount $rw fi