Advertisement
Guest User

ephemeral-pool-qubes-4.0

a guest
Dec 19th, 2019
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 10.40 KB | None | 0 0
  1. #!/bin/bash
  2. # BLAME: brendan.hoar@gmail.com
  3. #TODO
  4. ##RAMDISK SUPPORT
  5. ##By default tmpfs can use up to 50% of dom0 RAM.
  6. ##Short version, if tmpfs has at least 16GB of available RAM, offer it as the potential target of the new encrypted LV.
  7. #
  8. ##/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)
  9. ##Report /etc/grub2/grub.cfg line with dom0_mem=min: and dom0_mem=max: values (extract into variables)
  10. ##Report on real dom0 memory allocation and usage (extract from <where> and <xl or xentop>?)
  11. ##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.
  12. ##Should be faster. :) :) :)
  13. #TODO
  14. ##Determine which VMs go to RAMDISK vs. local encrypted, e.g. templates in RAMDISK but running VMs in encrypted pool.
  15. #TODO
  16. ##List of VMs to copy:
  17. ##1. Differentiated between disposable and normal VMs
  18. ##2. Number of copies of disposable VMs to launch
  19. ##3. autodiscover templates of VMs and copy them as well (due to snapshot-volume issue file location)
  20. ##List of non disposable VMs to copy and launch.
  21. ##List of VMs to create, along with source templates.
  22.  
  23.  
  24. arrayContainsElement ()
  25. {
  26.     local e match="$i"
  27.     shift
  28.     for e; do [[ "$e" == "$match" ]]  && return 0; done
  29.     return 1
  30. }
  31.  
  32. getTemplatesFromVMs ()
  33. {
  34.     inarr=("$@")
  35.     outarr=""
  36.     templateVM=""
  37.     for i in "${inarr[@]}"
  38.     do
  39.         # set templateVM
  40.         # check to see if templateVM is blank
  41.         # else check to see if template already in list
  42.         if [ arrayContainsElement "${templateVM}" "${outarr[@]}" ]
  43.             then
  44.             echo
  45.         else
  46.             echo
  47.             # add templateVM to list
  48.         fi
  49.  
  50.     done
  51. }
  52.  
  53.  
  54. ## -- BEGIN CODE -- ##
  55.  
  56. # Set variables
  57. sourcevg=qubes_dom0
  58. sourcepool=pool00
  59. processid=$$
  60. prefix=eph-${processid}
  61. # We temporarily muck with the default thin pool for voltile volumes
  62. # due to unexpected behavior...dangerous. Must be reset before leaving.
  63. defaultpoolvolatile=$(qubes-prefs default_pool_volatile)
  64.  
  65. #vm #1
  66. sourceVMname1=whonix-ws-15-dvm ### <- change for your needs
  67. targetVMname1=${prefix}-${sourceVMname1}
  68. sourceVMtemplate1=$(qvm-prefs ${sourceVMname1} template)
  69. targetVMtemplate1=${prefix}-${sourceVMtemplate1}
  70.  
  71. #vm #2 - standalone - has no template
  72. sourceVMname2=win7-auto-11 ### <- change for your needs
  73. targetVMname2=${prefix}-${sourceVMname2}
  74. #sourceVMtemplate2=$(qvm-prefs ${sourceVMname2} template)
  75. #targetVMtemplate2=${prefix}-${sourceVMtemplate2}
  76.  
  77. lev1name=${prefix} # shows up in /dev/qubes_dom0/ (and is part of pool00)
  78. lev1size=512 # in GB # replace with value that is %age of source thin pool size.
  79. lev2name=${lev1name}-luks #shows up in /dev/mapper/ (not seen as part of lvm)
  80. lev3name=${lev1name}-vg
  81. lev4name=${lev1name}-thinpool #shows up in LVM as another pool
  82. let lev4size=${lev1size}-1
  83.  
  84. # functions
  85. function pause(){
  86.     read -p "$*"
  87. }
  88.  
  89. function findalltemplatevms(){
  90.     echo "test"
  91. }
  92.  
  93. function findallnetworkvms(){
  94.     echo "test"
  95. }
  96.  
  97. clear
  98. echo ""
  99. echo "Purpose: build ephemeral environment for research and/or handling sensitive data."
  100. echo "  Utilize an unconnected Windows VM for working with data."
  101. echo "  Utilize four disposable whonix VMs for accessing remote data using different personas."
  102. echo "  If local persistance of data is required, I recommend utilizing a luks/veracrypt"
  103. echo "  physical volume attachable via qvm-block."
  104. echo ""
  105. echo "You'll want to modify the script to change $sourceVMname1 and $sourceVMname2 to point to"
  106. echo "the correct VM names."
  107. echo ""
  108. echo "*** Requires LVM thin pool setup, which is the Qubes default ***"
  109. echo ""
  110. echo "This script will:"
  111. echo "1. Create an encrypted pool inside the default pool using an ephemeral key sourced from /dev/urandom"
  112. echo "2. Copy a template-based disposable whonix VM (and it's template) to the new pool: ${sourceVMname1}"
  113. echo "3. Copy a standalone windows VM to the new pool: ${sourceVMname2}"
  114. echo "4. Temporarily change the default pool to the new pool."
  115. echo "5. Start up the VMs. Timing/delays hardcoded based on what worked well on a Thinkpad W520 w/ SSD."
  116. echo "6. Restore the default pool setting."
  117. echo "7. Await exit of all disposable VMs (but not the windows VM, so watch out)."
  118. echo "8. Prompt you to hit keys several times to remove the VMs and remove the encrypted pool"
  119. echo "9. Exit"
  120. echo ""
  121. echo "Should the system be left in an unknown state (e.g. due to a hard reboot or exiting the script early), remember to:"
  122. echo "1. Ensure all disposable and eph- VMs are shut down fully"
  123. echo "2. Manually run: qubes-prefs default_pool lvm"
  124. echo "3. Manually run: qvm-remove <any VMs that start with eph->"
  125. echo "4. Manually run: lvs|grep eph #to find the name of the useless temporary pool"
  126. echo "5. anually run: lvremove qubes_00/eph-xxxx #where xxxx is based on what you saw from output of previous commnand"
  127. echo ""
  128. echo "Press ctrl-c to exit."
  129. echo ""
  130. pause "Press enter to start building the ephemeral environment."
  131.  
  132. # Check for existing config that matches invocation and skip setup
  133.  
  134. # Use naming convention that can be easily rememdied after an unclean shutdown.
  135. # activation/deactivation settings and timing/invocations matter.
  136.  
  137. # Check to be sure both source VMs exist
  138. # TODO - fix this, it doesn't work
  139. if [ "$(qvm-ls --raw-list ${sourceVMname1})" = "${sourceVMname1}" ] || [ "$(qvm-ls --raw-list ${sourceVMname2})" = "${sourceVMname2}"  ] ; then
  140.     echo "Both of the source domains exist!"
  141.     echo "Conitnuing..."
  142. else
  143.     echo "The two VMs to copy to ephemeral environment do not exist:"
  144.     echo "${sourceVMname1}"
  145.     echo "${sourceVMname2}"
  146.     pause "Press any key to exit this script"
  147.     exit
  148. fi
  149.  
  150.  
  151. # Setup
  152. #   Create overallocated thin LV same size as enclosing pool (temp 512GB)
  153. sudo lvcreate -T ${sourcevg}/${sourcepool} -kn -ay -n ${lev1name} -V ${lev1size}G
  154. if [ $? -gt 0 ]; then
  155.     echo "Cannot create temporary thinpool '${lev1name}', aborting."
  156.     pause "Press any key to exit"
  157.     exit
  158. fi
  159.  
  160.  
  161. #   Create LUKS *or* plain crypt Volume on top of this thin LV.
  162. #     Add --keyfile-size= if you want less than 8MB from urandom
  163. #     Utilized random key, enable discards, determine correct block size (4K? LV TP cluster size?), option to drop on dismount?
  164. sudo cryptsetup open --allow-discards --type plain --key-file /dev/urandom /dev/${sourcevg}/${lev1name} ${lev2name}
  165. #   Set up PV using entire LUKS or loop device.
  166. sudo pvcreate /dev/mapper/${lev2name}
  167. #   Set up VG using this single PV.sudo vgcreate ${lev3name} /dev/mapper/${lev2name}
  168. #   Set up thinpool LV using entire VG.
  169. sudo lvcreate --type thin-pool --name ${lev4name} --size ${lev4size}G ${lev3name}
  170.  
  171. # create qvm-pool object
  172. qvm-pool -a ${lev4name} lvm_thin -o volume_group=${lev3name},thin_pool=${lev4name},revisions_to_keep=3
  173.  
  174. # somewhat risky hack due needed to prevent volatile from being created on default pool...change the default pool and later change it back!
  175. qubes-prefs default_pool_volatile "${lev4name}"
  176.  
  177.  
  178. #   Copy DispVMTemplate AppVM to new thinpool via qubes tools.
  179. #      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.
  180. #  THIS IS VERY SLOW, dd is used without any bs option
  181. echo "Cloning Template(s)"
  182. time qvm-clone -P "${lev4name}" "${sourceVMtemplate1}" "${targetVMtemplate1}" &
  183.  
  184. echo "Cloning VM(s)"
  185. time qvm-clone -P "${lev4name}" "${sourceVMname1}" "${targetVMname1}" &
  186. time qvm-clone -P "${lev4name}" "${sourceVMname2}" "${targetVMname2}" &
  187.  
  188. wait < <(jobs -p)
  189.  
  190. echo "Adjusting template pointers for ephemeral VMs..."
  191. qvm-prefs "$targetVMname1" template "$targetVMtemplate1"
  192. qvm-prefs "$targetVMname1" qrexec_timeout 600
  193.  
  194. echo "Fixup windows memory stuff"
  195. qvm-prefs "$targetVMname2" memory 4096
  196. qvm-prefs "$targetVMname2" maxmem 4096
  197. qvm-prefs "$targetVMname2" maxmem 0
  198.  
  199. echo "Running VM(s)"
  200. #   Start dispVM in new thinpool.
  201. qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
  202. sleep 10
  203. qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
  204. sleep 25
  205. qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
  206. sleep 25
  207. qvm-run --service --dispvm="${targetVMname1}" -- qubes.StartApp+xfce4-terminal &
  208. sleep 25
  209. qvm-start "${targetVMname2}" &
  210.  
  211. sleep 120
  212. #reset default pool back to normal...
  213. qubes-prefs default_pool_volatile "${defaultpoolvolatile}"
  214.  
  215. wait < <(jobs -p)
  216. date -Iseconds
  217.  
  218. # insert monitoring/wait here instead of BS pause
  219. #
  220. pause "All disposable VMs halted. Please check to be sure non-disposable VMs are halted before pressing a key to continue."
  221. pause "If the secondary VM is still running, I will shut it down when you press a key and will continue..."
  222. qvm-shutdown --wait ${targetVMname2}
  223. pause "Are you sure everything is shut down? Press a key to tear down the ephemeral storage volumes & wipe the session."
  224.  
  225. echo ""
  226. echo "Removing VMs/templates and shutting down ephemeral environment..."
  227.  
  228. # Shutdown
  229. #   Ensure VM is no longer running. Use wait loop around qvm-ls ${targetVMname} looking at status and/or parseing output.
  230. #   Remove DispVMTemplate AppVM from thinpool via qubes tools.
  231. qvm-remove -f "${targetVMname1}"
  232. qvm-remove -f "${targetVMname2}"
  233. qvm-remove -f "${targetVMtemplate1}"
  234.  
  235. # All volumes in temporary pool should be gone.
  236. remainingVMs=$(sudo lvs --noheadings -S pool_lv=${lev4name})
  237. until [ "${remainingVMs}" = "" ]
  238. do
  239.     echo "There are still VMs in the pool!!!"
  240.     echo "VM LV list:"
  241.         echo "${remainingVMs}"
  242.     pause "Please remove these manually using qvm-remove -f vmname"
  243.     sleep 2
  244.     remainingVMs=$(sudo lvs --noheadings -S pool_lv=${lev4name})
  245. done
  246.  
  247. if [ "${remainingVMs}" = "" ] ; then
  248.     echo "All VMs/templates have been removed"
  249. fi
  250.  
  251. #  Return default thin pool for volatile back to main pool
  252. qubes-prefs default_pool_volatile "${defaultpoolvolatile}"
  253. #   Remove qubes pool
  254. echo "Removing ephemeral qubes pool"
  255. qvm-pool -r ${lev4name}
  256. #   Remove thinpool
  257. echo "Removing ephemeral LVM pool"
  258. sudo lvremove -f ${lev3name}/${lev4name}
  259. #   Remove VG
  260. echo "Removing ephemeral VG"
  261. sudo vgremove ${lev3name}
  262. #   Remove PV
  263. echo "Removing ephemeral PV"
  264. sudo pvremove /dev/mapper/${lev2name}
  265. #   Remove LUKS volume
  266. echo "Removing ephemeral LUKS volume"
  267. sudo cryptsetup close ${lev2name}
  268. #   Remove overallocated thin LV
  269. sudo blkdiscard /dev/${sourcevg}/${lev1name} # needs testing
  270. echo "Removing overallocated thin LV"
  271. sudo lvremove -f ${sourcevg}/${lev1name}
  272.  
  273. # end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement