Advertisement
Guest User

Untitled

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