Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # BLAME: brendan.hoar@gmail.com
- #TODO
- ##RAMDISK SUPPORT
- ##By default tmpfs can use up to 50% of dom0 RAM.
- ##Short version, if tmpfs has at least 16GB of available RAM, offer it as the potential target of the new encrypted LV.
- #
- ##/dev/shm vs create your own tmpfs mount (both swap and can return unused space) vs create your own ramfs (no swap, does not return unused space)
- ##Report /etc/grub2/grub.cfg line with dom0_mem=min: and dom0_mem=max: values (extract into variables)
- ##Report on real dom0 memory allocation and usage (extract from <where> and <xl or xentop>?)
- ##If thresholds are met, ask user if they wish to utilize encrypted LVM thin on RAMDISK instead of encrypted LVM thin on existing LVM pooI love the thoughts on thel.
- ##Should be faster. :) :) :)
- #TODO
- ##Determine which VMs go to RAMDISK vs. local encrypted, e.g. templates in RAMDISK but running VMs in encrypted pool.
- #TODO
- ##List of VMs to copy:
- ##1. Differentiated between disposable and normal VMs
- ##2. Number of copies of disposable VMs to launch
- ##3. autodiscover templates of VMs and copy them as well (due to snapshot-volume issue file location)
- ##List of non disposable VMs to copy and launch.
- ##List of VMs to create, along with source templates.
- arrayContainsElement ()
- {
- local e match="$i"
- shift
- for e; do [[ "$e" == "$match" ]] && return 0; done
- return 1
- }
- getTemplatesFromVMs ()
- {
- inarr=("$@")
- outarr=""
- templateVM=""
- for i in "${inarr[@]}"
- do
- # set templateVM
- # check to see if templateVM is blank
- # else check to see if template already in list
- if [ arrayContainsElement "${templateVM}" "${outarr[@]}" ]
- then
- echo
- else
- echo
- # add templateVM to list
- fi
- done
- }
- ## -- BEGIN CODE -- ##
- # Set variables
- sourcevg=qubes_dom0
- sourcepool=pool00
- processid=$$
- prefix=eph-${processid}
- # We temporarily muck with the default thin pool for voltile volumes
- # due to unexpected behavior...dangerous. Must be reset before leaving.
- defaultpoolvolatile=$(qubes-prefs default_pool_volatile)
- #vm #1
- sourceVMname1=whonix-ws-15-dvm ### <- change for your needs
- targetVMname1=${prefix}-${sourceVMname1}
- sourceVMtemplate1=$(qvm-prefs ${sourceVMname1} template)
- targetVMtemplate1=${prefix}-${sourceVMtemplate1}
- #vm #2 - standalone - has no template
- sourceVMname2=win7-auto-11 ### <- change for your needs
- targetVMname2=${prefix}-${sourceVMname2}
- #sourceVMtemplate2=$(qvm-prefs ${sourceVMname2} template)
- #targetVMtemplate2=${prefix}-${sourceVMtemplate2}
- lev1name=${prefix} # shows up in /dev/qubes_dom0/ (and is part of pool00)
- lev1size=512 # in GB # replace with value that is %age of source thin pool size.
- lev2name=${lev1name}-luks #shows up in /dev/mapper/ (not seen as part of lvm)
- lev3name=${lev1name}-vg
- lev4name=${lev1name}-thinpool #shows up in LVM as another pool
- let lev4size=${lev1size}-1
- # functions
- function pause(){
- read -p "$*"
- }
- function findalltemplatevms(){
- echo "test"
- }
- function findallnetworkvms(){
- echo "test"
- }
- clear
- echo ""
- echo "Purpose: build ephemeral environment for research and/or handling sensitive data."
- echo " Utilize an unconnected Windows VM for working with data."
- echo " Utilize four disposable whonix VMs for accessing remote data using different personas."
- echo " If local persistance of data is required, I recommend utilizing a luks/veracrypt"
- echo " physical volume attachable via qvm-block."
- echo ""
- echo "You'll want to modify the script to change $sourceVMname1 and $sourceVMname2 to point to"
- echo "the correct VM names."
- echo ""
- echo "*** Requires LVM thin pool setup, which is the Qubes default ***"
- echo ""
- echo "This script will:"
- echo "1. Create an encrypted pool inside the default pool using an ephemeral key sourced from /dev/urandom"
- echo "2. Copy a template-based disposable whonix VM (and it's template) to the new pool: ${sourceVMname1}"
- echo "3. Copy a standalone windows VM to the new pool: ${sourceVMname2}"
- echo "4. Temporarily change the default pool to the new pool."
- echo "5. Start up the VMs. Timing/delays hardcoded based on what worked well on a Thinkpad W520 w/ SSD."
- echo "6. Restore the default pool setting."
- echo "7. Await exit of all disposable VMs (but not the windows VM, so watch out)."
- echo "8. Prompt you to hit keys several times to remove the VMs and remove the encrypted pool"
- echo "9. Exit"
- echo ""
- echo "Should the system be left in an unknown state (e.g. due to a hard reboot or exiting the script early), remember to:"
- echo "1. Ensure all disposable and eph- VMs are shut down fully"
- echo "2. Manually run: qubes-prefs default_pool lvm"
- echo "3. Manually run: qvm-remove <any VMs that start with eph->"
- echo "4. Manually run: lvs|grep eph #to find the name of the useless temporary pool"
- echo "5. anually run: lvremove qubes_00/eph-xxxx #where xxxx is based on what you saw from output of previous commnand"
- echo ""
- echo "Press ctrl-c to exit."
- echo ""
- pause "Press enter to start building the ephemeral environment."
- # Check for existing config that matches invocation and skip setup
- # Use naming convention that can be easily rememdied after an unclean shutdown.
- # activation/deactivation settings and timing/invocations matter.
- # Check to be sure both source VMs exist
- # TODO - fix this, it doesn't work
- if [ "$(qvm-ls --raw-list ${sourceVMname1})" = "${sourceVMname1}" ] || [ "$(qvm-ls --raw-list ${sourceVMname2})" = "${sourceVMname2}" ] ; then
- echo "Both of the source domains exist!"
- echo "Conitnuing..."
- else
- echo "The two VMs to copy to ephemeral environment do not exist:"
- echo "${sourceVMname1}"
- echo "${sourceVMname2}"
- pause "Press any key to exit this script"
- exit
- fi
- # Setup
- # Create overallocated thin LV same size as enclosing pool (temp 512GB)
- sudo lvcreate -T ${sourcevg}/${sourcepool} -kn -ay -n ${lev1name} -V ${lev1size}G
- if [ $? -gt 0 ]; then
- echo "Cannot create temporary thinpool '${lev1name}', aborting."
- pause "Press any key to exit"
- exit
- fi
- # Create LUKS *or* plain crypt Volume on top of this thin LV.
- # Add --keyfile-size= if you want less than 8MB from urandom
- # Utilized random key, enable discards, determine correct block size (4K? LV TP cluster size?), option to drop on dismount?
- sudo cryptsetup open --allow-discards --type plain --key-file /dev/urandom /dev/${sourcevg}/${lev1name} ${lev2name}
- # Set up PV using entire LUKS or loop device.
- sudo pvcreate /dev/mapper/${lev2name}
- # Set up VG using this single PV.sudo vgcreate ${lev3name} /dev/mapper/${lev2name}
- # Set up thinpool LV using entire VG.
- sudo lvcreate --type thin-pool --name ${lev4name} --size ${lev4size}G ${lev3name}
- # create qvm-pool object
- qvm-pool -a ${lev4name} lvm_thin -o volume_group=${lev3name},thin_pool=${lev4name},revisions_to_keep=3
- # somewhat risky hack due needed to prevent volatile from being created on default pool...change the default pool and later change it back!
- qubes-prefs default_pool_volatile "${lev4name}"
- # Copy DispVMTemplate AppVM to new thinpool via qubes tools.
- # Note: Separate thin pool for template and appvm is documented as working in qubes, but launching DVM from AppVM has to be in the same pool.
- # THIS IS VERY SLOW, dd is used without any bs option
- echo "Cloning Template(s)"
- time qvm-clone -P "${lev4name}" "${sourceVMtemplate1}" "${targetVMtemplate1}" &
- echo "Cloning VM(s)"
- time qvm-clone -P "${lev4name}" "${sourceVMname1}" "${targetVMname1}" &
- time qvm-clone -P "${lev4name}" "${sourceVMname2}" "${targetVMname2}" &
- wait < <(jobs -p)
- echo "Adjusting template pointers for ephemeral VMs..."
- qvm-prefs "$targetVMname1" template "$targetVMtemplate1"
- qvm-prefs "$targetVMname1" qrexec_timeout 600
- echo "Fixup windows memory stuff"
- qvm-prefs "$targetVMname2" memory 4096
- qvm-prefs "$targetVMname2" maxmem 4096
- qvm-prefs "$targetVMname2" maxmem 0
- echo "Running VM(s)"
- # Start dispVM in new thinpool.
- qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
- sleep 10
- qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
- sleep 25
- qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
- sleep 25
- qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
- sleep 25
- qvm-start "${targetVMname2}" &
- sleep 120
- #reset default pool back to normal...
- qubes-prefs default_pool_volatile "${defaultpoolvolatile}"
- wait < <(jobs -p)
- date -Iseconds
- # insert monitoring/wait here instead of BS pause
- #
- pause "All disposable VMs halted. Please check to be sure non-disposable VMs are halted before pressing a key to continue."
- pause "If the secondary VM is still running, I will shut it down when you press a key and will continue..."
- qvm-shutdown --wait ${targetVMname2}
- pause "Are you sure everything is shut down? Press a key to tear down the ephemeral storage volumes & wipe the session."
- echo ""
- echo "Removing VMs/templates and shutting down ephemeral environment..."
- # Shutdown
- # Ensure VM is no longer running. Use wait loop around qvm-ls ${targetVMname} looking at status and/or parseing output.
- # Remove DispVMTemplate AppVM from thinpool via qubes tools.
- qvm-remove -f "${targetVMname1}"
- qvm-remove -f "${targetVMname2}"
- qvm-remove -f "${targetVMtemplate1}"
- # All volumes in temporary pool should be gone.
- remainingVMs=$(sudo lvs --noheadings -S pool_lv=${lev4name})
- until [ "${remainingVMs}" = "" ]
- do
- echo "There are still VMs in the pool!!!"
- echo "VM LV list:"
- echo "${remainingVMs}"
- pause "Please remove these manually using qvm-remove -f vmname"
- sleep 2
- remainingVMs=$(sudo lvs --noheadings -S pool_lv=${lev4name})
- done
- if [ "${remainingVMs}" = "" ] ; then
- echo "All VMs/templates have been removed"
- fi
- # Return default thin pool for volatile back to main pool
- qubes-prefs default_pool_volatile "${defaultpoolvolatile}"
- # Remove qubes pool
- echo "Removing ephemeral qubes pool"
- qvm-pool -r ${lev4name}
- # Remove thinpool
- echo "Removing ephemeral LVM pool"
- sudo lvremove -f ${lev3name}/${lev4name}
- # Remove VG
- echo "Removing ephemeral VG"
- sudo vgremove ${lev3name}
- # Remove PV
- echo "Removing ephemeral PV"
- sudo pvremove /dev/mapper/${lev2name}
- # Remove LUKS volume
- echo "Removing ephemeral LUKS volume"
- sudo cryptsetup close ${lev2name}
- # Remove overallocated thin LV
- sudo blkdiscard /dev/${sourcevg}/${lev1name} # needs testing
- echo "Removing overallocated thin LV"
- sudo lvremove -f ${sourcevg}/${lev1name}
- # end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement