Starting this past early September, I’ve been working on and off to create a new tool for secure webcam integration in Qubes OS out of absolute necessity for remote work at both my (new) job and school at the university I’m newly attending. The tool is called Qubes Video Companion and I’m proud to announce that it’s evolved far past that basic requirement and at version 1.0.4 is now publicly available for testing!
Before resorting to the creation of an entirely new project, I thought of many other potential solutions for allowing me to use a webcam in Qubes but all of them fell flat in one way or another, to list them all (skip through this list if you’re not up for too much reading, haha):
- Do video conferencing in the sys-usb qube with the webcam device attached
Unfortunately, the desktop I run Qubes OS on doesn’t have a sys-usb qube due to complications of its hardware. The primary issue being that I require a USB sound card which has to stay attached to dom0 where the other Qubes audio components are. Not to mention, this solution is also far from being optimal from a security standpoint particularly because I also use a USB mouse and keyboard meaning I would essentially have to hand over control of those devices to sys-usb. This leaves the door open for keyboard injection into dom0 thereby compromising it (and the entire system) in the case sys-usb is compromised due to, for example, a bug in the video conferencing software. This also means enabling networking (removing the air gap) for sys-usb which again is harmful to security.
Note that I don’t personally consider not having a sys-usb qube for protecting dom0 from physical USB device attacks as much of a security issue because my desktop is always at home which is outside of my threat model.
- Do video conferencing in any qube with qrexec+usbip (with a sys-usb qube; can’t be done from dom0)
Even disregarding my personal hardware issues above, qrexec+usbip is a mess to get working and does poor on performance according to this GitHub issue: . Although, I’ve never been able to test it out myself. Additionally, the security concerns of using TCP/IP and USBIP between qubes is there. This also remotely exposes the webcam firmware which is yet another security risk with this configuration. 3. Do video conferencing in any qube with a bought USB hub PCI card This also means taking on all the security risks of attaching that physical hardware directly to the VMs which considering they are to run applications I don’t trust such as Zoom (which my job requires; I wouldn’t use Zoom given the choice of course) — doesn’t sit well with me at all. Plus, hot swapping PCI devices, though supported by Xen, is disabled in Qubes because of what a complex operation it is security-wise leaving the door open to bugs (I read this was the reason somewhere I think in the Qubes mailing list I think). This means that in order to use my webcam on different qubes (my “school” and “work” qubes for my purposes) I would have to reboot them each time to attach and remove the USB hub with my webcam plugged into it. This would be very inconvenient for my use case particularly when I’m trying to get work done efficiently. I thought about combining my school and work qubes into just one qube but at that point why am I even bothering to use Qubes OS if I don’t utilize its most basic security feature. Lastly, I could also buy multiple USB hub PCI cards but that was just too hacky for me. 4. Do video conferencing in any qube with FFmpeg for streaming video At the time, there were preliminary outlines of a working solution for webcam video streaming with FFmpeg. While this was a good start, it just didn’t cut it for my needs. The resolution was very low (when I tried to raise it to 1920x1090 it didn’t work) and even with that low resolution the latency was below optimal and it just tore up my CPU power when I needed it the most; hence this too was not a realistic solution. Plus, FFmpeg isn’t available in Fedora without adding RPM Fusion repo due to patent issues which was just one more little gripe I had with it. And to top it off, FFmpeg doesn’t exactly have an amazing security track record… 5. Dual booting and other OSs Finally, as a very last resort (not being able to use my webcam wasn’t an option for me), I thought about dual booting (way too inconvenient not to mention the security downfalls) and (just for a very brief moment for the sake of completeness) other OSs. However, I have already contributed one project (qvm-create-windows-qube) to Qubes OS and have now been “locked in” to the Qubes ecosystem (haha) by fantastic features such as Qubes Split GPG, a great community as well as countless other qualities and would feel insecure running any other operating system. As far as using a webcam in Qubes OS went, I needed something that , I needed — Qubes Video Companion. And that’s how this project was born. Add in screen sharing (a welcomed bonus), an unspoofable video sharing tray indicator, packaging and all the documentation to boot, and you’ve got what Qubes Video Companion has evolved into! I’ve tested performance and although I haven’t tried qrexec+usbip with a webcam myself (reasons stated above), I can say that by comparing CPU performance (using CPU model performance comparison websites) of the CPU specs of other Qubes users and the performance they are getting with qrexec+usbip versus what I’m getting with Qubes Video Companion and my lower power, older CPU (some of you guys are rocking beast setups or just plain laptops that outperform my desktop, haha) it would seem to me that Qubes Video Companion wins on performance by a wide margin. I also saw reports of qrexec+usbip using a lot of RAM. Well, with Qubes Video Companion that’s no problem because from the moment I start the video stream from my webcam (at 1920x1080 30 FPS) I only see a 30-40 MB increase in RAM on the sending and receiving side then it remains stable at that amount! I’ve already been using Qubes Video Companion on a regular basis for a couple of months now (in time for when my job contract began) and it’s been working amazingly even in a Zoom call with over 60 other people I had absolutely no problems (just had to assign all 4 of my vCPUs to that qube and up the memory or else Zoom would have trouble)! Repo can be found here: I spent a lot of time trying to make this a “just works” (and well) experience (discounting just a couple of hiccups in the FAQ of the README and GitHub Issues) as I would’ve wanted back in September (or earlier) so please star the repo if my project achieves that for you. Otherwise, create an issue and I’ll try to diagnose and fix the problem you’re having as soon as I have a moment. One of the main advantages of the architecture of Qubes Video Companion is that it depends on GStreamer as opposed to FFmpeg. I found out about GStreamer in the v4l2loopback GitHub Issues and saw it was being used as part of the “set-caps” functionality in the “v4l2loopback-ctl” command. This interested me and upon further research, it became increasingly apparent to me that GStreamer has multiple benefits over FFmpeg in the context of this project all of which are documented in the README. The timeline for working on this project starting from September was (as I mentioned) very on and off until early January at which point I had figured out all the GStreamer and video related components. Going from knowing nothing about GStreamer or Video4Linux to the level of knowledge required to create this project was an involved process to say the least mostly consisting of trial and error (tons of it), reading GStreamer documentation and mailing lists, Stack Overflow and countless hours of work. I almost gave up at one point, but a couple of months later after having success with another somewhat related mini project I was doing at the time, I persevered and I’m glad I did because I’m very happy with how this project turned out! In particular, I got wrapped up in one red herring based on something I saw in the very verbose GST_DEBUG logs. That and vague GStreamer error messages that appear to only be of any assistance if you get into reading the underlying GStreamer code (such as the very helpful “Internal data stream error” which I never want to see again, haha). Of course, in retrospect looking at the final solution now, it all seems so obvious and straightforward but it sure wasn’t at the time. After all that, it was just a matter of making the UI (in which I applied some of the object-oriented programming (OOP) experience I acquired in one of my university classes), adding polishing, packaging and all the documentation to boot from mid-January to now (although, the UI was a last minute thing I decided I wanted to add somewhere in around March)! As for contribution to the Qubes Community Repo (if that is to be desired) I first want to fix the issue with Firefox (see the GitHub issue) because Mozilla has been a great supporter of Qubes with the big grant they gave so it’s the least we could do as well as to not put Firefox at a disadvantage. Hope you’re doing well! Best regards, Elliot P.S. As part of making this project, I found myself needing to do video conferencing in one of my Kali Linux qubes (“debian-10” qube turned into a “kali” qube). Unfortunately, the audio and microphone PulseAudio components were broken in that qube by one of the packages Kali Linux installs by default. I was able to fix this issue and plan on making a pull request to the Qubes documentation so others can fix this issue if they run into it with their “kali” qubes. Also, if you’re looking for a solution to enable screen sharing with Zoom then check out my issue here (although I didn’t solve the issue myself): – You received this message because you are subscribed to the Google Groups “qubes-users” group. To unsubscribe from this group and stop receiving emails from it, send an email to . To view this discussion on the web visit .