Printing from DisposableVMs

Printing from disposableVMs

  • Set up a dedicated template where you can install the potentially insecure 3rd party printing driver.

Hi, would you be able to expand on how you did this?


Sure, it’s actually quite simple.

  • I cloned my fedora template and named it something like “fedora-insecure” (you could choose any other template you like).
  • Install the respective driver for your printer in this template. See the Qubes documentation for the reasoning behind this. With one of my printers this works like a charm. With another one I still have inexplicable problems.
  • Create a DisposableVM template from the “fedora-insecure” template. If you need instructions on this see
  • Optional but very much recommended: restrict the firewall settings of this new DisposableVM template to the IP address of your printer only. If you have detailed knowledge about your printer you could even further restrict the firewall to allow only the ports required for the actual printing. (Qubes docs on firewalling)

This is basically it. You could now further tweak your settings for disposableVMs to improve your workflow.
For example, it could be useful to set this VM as default disposable VM for some appVMs. Then a simple “right click on document -> Open in DisposableVM” would open a printable instance of this document.

I went another route. I edited the Qubes RPC policy file /etc/qubes-rpc/policy/qubes.OpenInVM in dom0 and changed the first line from $anyvm $dispvm allow to $anyvm $dispvm ask (you could also just delete this line because the remaining line $anyvm $anyvm ask has the same effect).
This way, every time I choose “Open in DisposableVM” from a context menu in any VM, dom0 shows a pop up asking for the target VM where I want to open the document in. I can then decide if I want to print (opening the file in the DisposableVM for printing) or if I just want to securely view a document (opening it in a DisposableVM which is offline). I could even open a file in a non-disposable appVM this way.

Minor drawbacks:

  • Do not close the document right after you hit the print button. Closing the document will shutdown the VM instance and most likely kill the print job before it finished. I usually let the document window open for a few minutes or until I grabbed my copy out of the printer.
  • If you want to print multiple documents, it is quite memory consuming to open them all in dedicated disposable VMs. Using the Qubes-RPC modification I described it is possible to open further documents in the same DisposableVM as the first one by specifying it’s name. Since these names are all just randomly generated numbers I recommend to choose a color for your printing dispVM which is distinct from your other dispVMs.

There is stuff like “named dispVMs” which I haven’t yet dived into. Probably, my approach could still be tweaked a bit for better usability.


Thanks a lot @phl for the explanation as well. And thanks @Surf for bringing it up. I was actually on the lookout for a guide like this for a while now.

(I’ve also moved this discussion into it’s own thread since it may be useful for others and this way it’s easier to find. I hope that’s ok)

1 Like

Thanks I’ll try your instructions and I’ll get back to you. Thanks so much,

Static/named DisposableVMs do indeed work for printer VMs, and they avoid some of the drawbacks listed above. More info in this section of the page already linked above:


Thanks @adw. That sounds interesting. I’ll definitely have a look into this. Not only for a printVM but also for the cases listed in the docs (disposable sys-net and sys-firewall).

I can confirm that named DispVM works for printing.

Also, to add to the topic (confusion?!), I approach printing a bit differently. Rather than putting cups, printer(s), etc. in the regular template (or a clone of it), I have a minimal template with just networking, cups, and a PDF reader. This is the only template with cups installed.

As needed, DisposableVMTemplate AppVMs are created wherein the printer(s) is(are) installed, and these are firewalled to just those printers or (local) network segments.

Since I (probably too) frequently want to save a copy of what I’ve printed, there is usually only minimal extra steps involved: Print to PDF in the qube with the data & app, fire up the printing DispVM (if not already running), copy/move the PDF to it, and print. Since it’s a DispVM, these PDFs go away when it shuts down.

This setup keeps the AppVMs template(s) free of cups, printers, & configs; isolates cups to 1 template with minimal other software; and allows printers to be created together or separately in the DisposableVMTemplates as desired.

One final FYI aside: I also played with cups’ ServerRoot facility to direct files to /home/user, but ran into a problem: Printing appeared to work fine, but only blank pages came out of the printer. Have given up on resolving this for now - there’s virtually no info on the web re. ServerRoot, and it may be incompletely implemented…



These are alternate instructions. I’m going to try to give more specific instructions in this version. Please rip this apart and argue anything that you see wrong with this! Lets make this process better. (and hopefully easier too).

  1. Make a copy of the debian template (currently called “debian-10”) either by opening settings and selecting “clone” or by doing this in a dom0 terminal:
    qvm-copy debian-10 debian-10-print-server
    (note: we use debian in order to not install unnecessary binary print drivers)
  2. Launch a terminal for the new debian-10-print-server template and remove “contrib” and “nonfree” from /etc/apt/sources.list (if they are there)
  3. In a terminal for the new debian-10-print-server run: sudo apt-get update; sudo apt-get install task-print-server
  4. In the same terminal, run: system-config-printer and set up your printer. (note, do NOT attempt a test page in the template VM, as the template should not have access to the network)
  • Note: If you cannot find a driver that will work with your printer, then you may need to find and install a binary driver for your specific printer.
  1. Shut down the template VM with “sudo poweroff”
  2. In dom0 type:
  • qvm-create --template debian-10-print-server sys-printer --label red
  • qvm-prefs sys-printer template_for_dispvms True
  • qvm-features sys-printer appmenus-dispvm 1
  1. Open the settings for sys-printer VM and scope the firewall to your local network (or even just the printers ip). If you do not your local network, adding unroutable addresses and will probably work
  2. From the disposable menu, start a disposable sys-printer
  3. Run torbrowser.
  4. open a terminal for the torbrowser system and type:
    inotifywait -m /home/user/Downloads | while read a b file; do [[ $b == *CREATE* ]] && qvm-move /home/user/Downloads/mozilla.pdf; done
  5. From inside torbrowser, print to “pdf”.
  6. When the menu pops up, confirm that it is comming from the correct VM, then select your running sys-printer disposable vm
  7. open a terminal in the running sys-printer disposable vm, and type: lpr QubesIncomming/*/mozilla.pdf
  8. Now either erase the qube with: sudo poweroff, or if your willing to reuse it, type rm QubesIncomming/*/mozilla.pdf to allow the next printjob.

Possible enhancements:

  • we could put a small script in cron that would wait for a mozilla.pdf file to show up, run the lpr command after it does, and then either erase the mozilla.pdf file, or power down the disposable VM. (this would streamline workflow allowing users to not have to open the terminal in the sys-printer disposable VM)
  • the inotifywait command could be put in the whonix workstation template with some kind of auto-start?
1 Like

I think that between steps 9 and 10, you’re missing the part in which you copy the file to the disposable printer VM. :slight_smile:

Ha. I totally was :slight_smile: . fixed.

updated it to be a automated version that does not require the user to type the qvm-move command, just to authorize the move

2 posts were split to a new topic: Pinged four times on non-subcribed thread

does anyone see a security reason to not to put the inotifywait command (in step 10) into the whonix workstation templates autostart?

inotifywait -m /home/user/Downloads | while read a b file; do [[ $b == *CREATE* ]] && qvm-move /home/user/Downloads/mozilla.pdf; done

Not a security issue, but a usability one. On your attempt to get out the optimal solution for your own setup you customized the configuration pretty much, maybe more than you even realize it yourself.

Which is perfectly fine if it works great for you. Just a small reminder that my approach is a bit more general (and note that my variant might not even be the best solution for everyone’s use case. See, e.g., @unman’s sys-printer setup in your other thread).

Getting back to the usability issue I am spotting: you totally focussed on the aspect of printing web pages (or emails, for what it’s worth) which are automatically named “mozilla.pdf”. Everything else that you might ever want to print will not profit from your setup. It might even crash your script if you download anything in torbrowser which is not called mozilla.pdf. so, at least you should probably put your inotifywait call in a loop, so that it triggers whenever a new file appears. Maybe even make it more general, so that it triggers whenever you download something with a particular file extension (.pdf, maybe also .docx or something similar?).
However, before customizing that much in this direction I would probably rather setup an unman-inspired cups-proxy with qrexec.

Securitywise, as every call to “qvm-move” would trigger a popup window from dom0 (unless you tinker with the default qrexec policies), everything should be fine.