Skip to main content

Infra Witch for Freedom of the Press Foundation, bad watercolour artist, board gamer, diagnosed caffeine addict, excessive incense user. Nonbinary & intersex person.
Contact details »

gpg key id: 0xBD1C746B

Pronouns: they/them/their

ketudb

git.mania.systems/ketudb

gitlab.com/ketudb

 

Qubes + Tails + Persistence = Hax

8 min read

For the large part, when I want to use Tor, I run Whonix - because it's integrated very nicely into Qubes which is my daily driver for both work and personal projects. But, lately, Whonix is looking awfully fashy. Maybe they're not, but if they're not, they're certainly not handling it well.

And if you know me, that's reason enough to want to delete my Whonix templates & virtual machines. But I needed a good alternative - Tails is my goto when I'm not using Qubes. Tails has never worked quite right on Qubes - requiring you to boot from a CD image or external USB disk. Typically, persistence hasn't worked, which isn't great for a Tor-based workstation VM.

I've now managed to get a fully virtualised (as in, no USB disk) Tails AppVM on Qubes with persistence. All of this was tested against Qubes R4.0 with Tails 4.8

Unfortunately, there are still caveats - the most important of which is that it requires manual network configuration each boot. If you make careful use of the pause/continue AppVM functions in Qubes, you can make this significantly less annoying. The setup process to get this working at all is also a bit of a pain in the ass.

Making it go.

Caveats

  • You'll need to set an administration password every boot so that you can configure the IP address.
    • You can probably due the same through the GUI without an administration password, but I haven't tested this.
  • The networking will need to be manually configured each boot
    • Qubes doesn't use DHCP, but rather a set of custom scripts to dynamically pass in network configuration. Tails doesn't support this out of the box. We may be able to script this, but I need to investigate how static the IP and gateway addresses are in Qubes.
  • You're running it in a virtual machine, so it's gonna whine about that.
  • It can't support Qubes' seamless mode, so the entire Tails desktop will be run in it's own window.

Create a Tails USB device

Use dd to create a Tails USB disk on a different computer.

  1. Use a different computer
  2. Download the Tails USB image
  3. Insert a USB disk
  4. Write it to the USB device with sudo dd if=tails-amd64-[version].img of=/dev/[USB device] bs=1M status=progress
    • Substitute [ version ] above with the Tails version - e.g. 4.8
    • Substitue [ USB device ] above with the USB device of your thumbdrive - sudo dmesg can help you find out, usually something like sdb
  5. Remove the USB disk once it's done.

Create a standalone HVM virtual machine

Create the AppVM, making sure to allocate it enough RAM to run, and enough disk space (Private storage in Qubes terms) that your persistent partition will be comfortable.

  1. In Qube manager, create a new Qube.
  2. Name it (tails), it give it a colour.
  3. For Networking choose your sys-firewall Qube.
  4. Set type to Empty standalone
  5. Untick install system from device
  6. Tick launch settings after creation
  7. Create it and the settings dialogue should open
  8. The Private storage max size option will dictate how big your persistent storage is. I kept mine at 2GB - beware, changing it later will be a headache.
  9. Under the Advanced tab, bump Initial memory to at least 1GB - I recommend a minimum of 2. Too low and Tails will fail to boot with a GDM error.
  10. Save that.

(Now comes the fun part)

Wedge tails into the disk image by abusing dd and qvm-run

Run dd on sys-usb via qvm-run to dump out the Tails USB disk, pipe it to dd in dom0 and have it write it to the LVM partition that serves as your Tails AppVM's root disk.

  1. Insert the USB disk that you wrote Tails to earlier.
  2. Use qvm-block to find the device's name in your sys-usb qube - usually something like sda
  3. Open a dom0 terminal
  4. We're going to image the Tails disk into the LVM partition that serves as the VM's boot disk: qvm-run --pass-io --user=root sys-usb "dd if=/dev/[USB Device]" | sudo dd of=/dev/qubes_dom0/vm-tails-root-snap status=progress
    • Substitue [ USB device ] above with the device's name from step 2.
    • If you didn't name your Qube tails when you created the Qube, the of= parameter above will be different - tails would be replaced with the qube name.
  5. You can remove the USB disk once it's done.

Get it booted

Start the AppVM, and edit the boot configuration so that it no longer believes it's on live media and doesn't support persistence. Add in a sudo password in the Tails greeter and go to the desktop.

  1. Start the Qube. It'll display the boot process in a window.
  2. When the SYSLINUX boot menu appears, press tab before the timer counts down
  3. Use your home/end/delete/backspace keys & your arrow keys to find and delete the live-media= parameter (and it's value!) as well as the nopersistence option.
  4. Press enter to finish booting.
  5. When you get to the TAILS greeter, click the + at the bottom and choose Administration password. Enter a password twice and click Add.
  6. Click Start Tails to get to the Tails desktop.
  7. Ignore the rather obvious virtual machine warning.

Fix the boot options permanently

Remount the partition with the syslinux boot options as read-write, edit the boot options to make the manual boot option changes from the last section permanent. Save & remount as read-only again.

  1. From the Applications menu, System tools submenu, open a Terminal.
  2. Run sudo su to become an administrator and enter the administration password from step 5 of the boot process.
  3. Run mount -o remount,rw /lib/live/mount/medium
  4. Run nano /lib/live/mount/medium/syslinux/live.cfg
  5. Use your home/end/delete/backspace keys & your arrow keys to find and delete the live-media= parameter (and it's value!) as well as the nopersistence option. These will appear twice in the file.
  6. Press ctrl+o then enter to save and ctrl+x to exit.
  7. Run nano /lib/live/mount/medium/syslinux/live64.cfg
  8. Repeat steps 5 & 6, then continue to 9.
  9. Run mount -o remount,ro /lib/live/mount/medium

Creating a persistent volume the hard way

Create a GPT volume label your Private storage disk (xvdb), and then create a partition to fill it. Encrypt it, then format the encrypted partition as ext4. Note that the volume name matters (TailsData). Then mount the new partition, copy the home directory structure in, set all the ownership and permissions where they need to be, and create the persistent storage configuration file.

  1. From the Applications menu, System tools submenu, open a Terminal.
  2. Partition your disk by typing and pressing enter after each:
    1. sudo su
    2. enter your administration password from step 5 of the booting process
    3. parted /dev/xvdb
    4. mklabel gpt
    5. q
    6. parted -a optimal /dev/xvdb mkpart TailsData ext4 0% 100%
  3. Create the encrypted partition by typing and press enter after each:
    (If you get an error on step e below, shut down Tails, restart the Qube and follow steps 5-7 on the booting process above. Repeat steps a and b below, then re-attempt step e)
    1. cryptsetup luksFormat /dev/xvdb1
    2. YES
    3. enter your chosen disk encryption password
    4. enter it again
    5. cryptsetup luksOpen /dev/xvdb1 tails_persist
    6. enter your disk encryption password again
    7. mkfs.ext4 /dev/disk/by-id/dm-name-tails_persist
  4. Setup the persistent storage and permissions:
    1. mount /dev/disk/by-id/dm-name-tails_persist /mnt
    2. cd /mnt
    3. chown root:root .
    4. chmod 0775 .
    5. setfacl -m -u tails-persistence-setup:rwx .
    6. touch persistence.conf
    7. chown tails-persistence-setup:tails-persistence-setup persistence.conf
    8. chmod 0600 persistence.conf
    9. cp -r /etc/skel amnesia
    10. chown -R amnesia:amnesia amnesia
    11. echo "/home/amnesia source=amnesia" > persistence.conf
    12. cd
    13. umount /mnt
    14. cryptsetup luksClose tails_persist

First real boot

This will have to be done each time you boot your Tails VM.

Restart your AppVM, and you should be able to decrypt the persistent volume in the greeter. You'll also want to set the sudo password again, while you're here.

  1. Shut down Tails again, and then restart the Qube
  2. When it boots, the greeter should detect the persistent volume - enter your disk encryption password and click Unlock.
  3. When you get to the TAILS greeter, click the + at the bottom and choose Administration password. Enter a password twice and click Add.
  4. Click Start Tails to get to the TAILS desktop.

Manually configure networking

Unfortunately, this will also have to be done each time you boot your Tails VM.

Qubes doesn't use DHCP on it's internal networking, but rather passes network config values around with qubesdb. Unfortunately, we can't use that inside Tails right now, so we'll need to login and manually configure networking.

  1. In Qube Manager, open the settings for the Tails qube and move it to one side where you can see the Networking section.
  2. In Tails, from the Applications menu, System tools submenu, open a Terminal.
  3. In the terminal, type:
    1. sudo su
    2. enter your administration password from step 3 of the First real boot process above.
    3. ip addr add 10.137.0.xx/32 dev eth0
      1. substitute 10.137.0.xx with the IP value from the Qube settings.
    4. ip route add 10.137.0.yy/32 dev eth0
      1. substitute 10.137.0.yy with the Gateway value from the Qube settings.
    5. ip route add 0.0.0.0/0 via 10.137.0.yy dev eth0
      1. substitute 10.137.0.yy with the Gateway value from the Qube settings.
    6. exit
    7. exit
  4. At this stage, the terminal will disappear, and you'll get a notification saying you're connected to Tor.
  5. Congrats.