Hack and /

Lightning Hacks: Qubes Tips

Kyle Rankin

Issue #283, November 2017

Learn a few tips to get the most out of your Qubes desktop.

Every so often I write a Lightning Hacks piece in this space. The idea behind it is to gather up some tips that wouldn't be enough to fill out a full article but that are useful nonetheless. The idea is based on lightning talks you'll see at conferences—ten-minute talks so the speaker can present various ideas that wouldn't take up a full 50-minute slot on their own.

I've been using the high-security Qubes operating system for quite some time now, and I wrote a multipart series for Linux Journal in the past. While I've been using it, I've gathered a few useful tips for it, and in this article, I cover a few tips specifically tailored for Qubes. Even though these tips are for Qubes and assume a desktop full of VMs, you could adapt the overall ideas to other desktop environments.

Clock In, Clock Out

Generally speaking, it's a good idea to separate your personal and work environments completely on different machines. It's better for security, because if your personal machine gets hacked, you don't risk infecting your work environment and vice versa. Of course, if for some reason you don't have the luxury of two machines, or if you want to set up a travel laptop that's configured both with your work and personal settings (like I've mentioned in prior articles), you'll want some way to switch between work and personal modes.

Because Qubes does everything through many different VMs, this means writing a simple pair of scripts, clock_in and clock_out, that are stored in the dom0 VM. Both scripts define a list of personal and work VMs, and they will shut down or start up VMs depending on whether you are clocking in or clocking out. Here's an example clock_in script:

#!/bin/bash

PERSONAL_VMS="fb personal personal-web vault finance 
 ↪writing sys-whonix"
WORK_VMS="work work-web stage prod1 prod2 vault-work"

for i in $PERSONAL_VMS; do qvm-shutdown $i; done
for i in $WORK_VMS; do qvm-start $i; done

Compare this to my clock_out script, and you'll see that the list of VMs is different:

#!/bin/bash

PERSONAL_VMS="fb personal personal-web vault"
WORK_VMS="work work-web stage prod1 prod2 vault-work stage-gpg 
 ↪prod-gpg sys-vpn-stage sys-vpn-prod1 sys-vpn-prod2"

for i in $PERSONAL_VMS; do qvm-shutdown $i; done
for i in $WORK_VMS; do qvm-start $i; done

The reason the list is different is that in both cases I want to be comprehensive in the VMs I shut down, but need only particular VMs to start up when I clock in or out. By creating separate lists, I can make sure all the VMs that might be running are all shut down, and I start only the VMs I need.

VM Selector for URLs

One great thing about Qubes is that if you get a questionable file or URL in one VM, you can open it in a less-trusted or disposable VM. Typically when it comes to URLs though, this means going through Qubes's more-secure copy-and-paste method, which takes twice the number of keystrokes as a normal copy and paste. I realized that I commonly wanted to open a URL from a more-trusted VM in a certain list of less-trusted ones, so I created the following script called vm_picker that pops up a simple GUI selector I can use to choose the VM with which I want to open a URL:

#!/bin/bash

VM=$(zenity --list --title 'Open in which VM?' --column='VM Name' \
  untrusted \
  dispVM \
  personal-web \
) 

if [ "$VM" == "dispVM" ]; then
  qvm-open-in-dvm $@
else
  qvm-open-in-vm $VM $@
fi

In this script, I've defined three different VMs, my completely untrusted one I use for normal web browsing, a disposable VM for particularly risky VMs and my personal-web VM that I use for more trusted authenticated sessions. The script uses zenity, which is a handy command-line tool you can use to display basic GUI elements—in this case, a list. Once you select the VM, zenity assigns it to the VM variable, and if it's a disposable VM, I use a special Qubes command for disposable VMs. If it's any other VM, I use a separate one.

Save the script in any VMs from which you want to open URLs, and then go into that VM's Preferred Applications program (you may have to update the list of visible shortcuts for that VM to see this program). Set this script as your preferred web browsing application and then all of your right-click “Open URL” dialogs in terminals or other web-aware programs will use your VM picker.

Obviously, you'll want to customize the script to present your own VMs and in your preferred order. I find I have a different list and order depending on which VM I call it from, so each VM has a slightly different version of the script. I also set up a custom version for the KeePassX program that runs in my vault, because it allows you to specify a URL assigned to a particular user name and password, and you can tell it to open the URL with a keybinding. Buried in the KeePassX settings is a setting that allows you to define a custom URL handler, so I set it to my VM-picker script.

Conclusion

So if you use Qubes, I hope you've found these tips to be handy. If you don't use Qubes, you still could adapt these ideas to your desktop. For instance, you simply could change the clock_in and clock_out scripts to shut down and launch specific programs (or programs with specific modes set). Instead of the vm_picker script choosing specific VMs, you could change it so that it allows you to pick between your different web browsers so you can open some URLs in Firefox and others in Chrome. You even could inspect the URL ahead of time and automatically launch a particular browser without a prompt at all.

Kyle Rankin is VP of engineering operations at Final, Inc., the author of many books including Linux Hardening in Hostile Networks, DevOps Troubleshooting and The Official Ubuntu Server Book, and a columnist for Linux Journal. Follow him @kylerankin.