Configuring Shared Directories Between KVM Hosts & Guests
You cannot trust Virtualbox. KVM, while awesome, is nowhere near as user-friendly and thus requires a little bit of demystifying.
Oh, how I miss the good old days when I naively thought I could run Whonix in VirtualBox and actually be safe. Just kidding. I never believed that. I’ve never trusted closed source software because I’m not an idiot.
I was running Whonix in KVM back in 2015, long before it was officially supported. I had to manually convert the VDIs into qcow2 disks and edit the XML manually. It was a bit of a task, if I recall correctly. But even then, it wasn’t particularly difficult, and it was certainly infinitely more secure. By the way, do you remember when it used to take us software engineers days, weeks, months, or even years to do something that artificial intelligence can now do in 30 seconds? There was no GPT in 2015. Honestly, I am grateful for that. I suspect that we may end up with a generation of kids who think they can do anything, and some of them might be able to, but will any of them understand what they are doing? I doubt it, but I could be wrong. Time will tell. I digress…
Do not ever use VirtualBox. It’s closed source for a reason. There are definitely RCE backdoors in that software. They will be used against you. I know this from experience. It is a really annoying lesson to learn. Do you know how annoying it is to reinstall your operating system every week? Yeah. Imagine that. Don’t be an idiot. There is no point in running Whonix in VirtualBox. That’s like wearing a condom that you intentionally poked holes in. Pointless. So come to the light side. Switch to KVM. Let’s do it.
So I assume you managed to get Whonix or another operating system running in your KVM. Congratulations, you are one step closer to something resembling security. There’s still a lot of work to be done though. For instance, it’s much easier to set up a shared folder in VirtualBox than in KVM. And it’s this kind of nonsense that keeps people using software they know is insecure! Thus, I am going to show you how to set this up.
Before going any further, let’s consider the implications on our operational security that this procedure may have. The point of running a virtual machine (or at least one of the most common ones) is to isolate our identities or activities, usually for security reasons. For example, I do not trust certain applications, yet I need to run some of them, so to be safe, I run them in a virtual machine. For instance, I suspect that PyCharm (or perhaps some malicious add-on that I installed) has some kind of backdoor built into it because I’ve traced system compromises to my development environment. Rather than not using PyCharm anymore, which is otherwise a great IDE, I choose to run it inside a virtual machine instead.
Assuming for a moment (for the sake of example) that I am correct, and there is a backdoor in the PyCharm IDE. If this is true, I want to ensure that any virtual machine running this application has the least access possible to the host operating system. For me, that means disabling audio input and output (I never use that anyway), among other things. Regarding a shared directory, I highly recommend installing an additional SSD on your system solely for hosting your VM share directory. Also, do not use the default mount options — i.e., do not mount it under `/media/$USER/disc`
— because to allow the guest access to `/media/$USER/disc/shared`
, we need to give the `libvirt-qemu` group read access to:
/media
/media/$USER
/media/$USER/disc
/media/$USER/disc/shared
If the VM is compromised, the adversary could access whatever other disks you or any other user have mounted on that system. This is a terrible idea.
Instead of doing that, edit the mount options of your disk and create a mount point just under the file system root, or “/”, which we shall call “/kvm_share”. The easiest way to do this is by using the gnome-disk utility:
Create a directory on the disk:
$ sudo mkdir /kvm_share/shared
Set the access control list:
$ sudo setfacl -m u:libvirt-qemu:rx /kvm_share
$ sudo setfacl -m u:libvirt-qemu:rwx /kvm_share/shared
$ sudo setfacl -m g:kvm:rx /kvm_share
$ sudo setfacl -m g:kvm:rwx /kvm_share/shared
$ sudo chown -R libvirt-qemu:kvm /kvm_share
$ sudo chmod -R 775 /kvm_share # First make sure that this works, then later change to 770.
Your user should already be part of the `libvirt-qemu` group, so that ought to be sufficient to allow you to write to the directory. Verify it works:
$ cd /kvm_share
$ sudo su -s /bin/bash libvirt-qemu
$ ls
If you still have permission issues, temporarily disable SELinux:
$ sudo setenforce 0
Or, if using AppArmor, temporarily put libvirtd into complain mode:
$ sudo aa-complain /etc/apparmor.d/usr.sbin.libvirtd
Edit the VM’s XML file to add the file share, then restart the VM. This can be done in the shell with `virsh`, or you can use the GUI:
<filesystem type='mount' accessmode='mapped'> <source dir='/kvm_share/shared'/> <target dir='shared_folder'/> <address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/> </filesystem>
Note that you may need to change the bus ID. If you get an error about a duplicate ID, simply increment the ID to `0x07`, see if that works, if not try going to `0x08`, and so on. In my experience, bus 6 or 7 tends to work fine.
$ sudo virsh shutdown Whonix-Workstation
$ sudo virsh start Whonix-Workstation
Assuming the machine boots, you’re in excellent shape! Now mount the directory and set permissions on the guest:
Install qemu-guest-agent
:
$ sudo apt-get update && sudo apt-get install qemu-guest-agent
Create a mount point:
$ sudo mkdir -p /mnt/shared_folder
Mount the shared folder:
$ sudo mount -t 9p -o trans=virtio shared_folder /mnt/shared_folder -oversion=9p2000.L
If you get an error about /etc/fstab
not being set up, open /etc/fstab
and add:
$ shared_folder /mnt/shared_folder 9p trans=virtio,version=9p2000.L 0 0
Run:
$ sudo mount -a
$ sudo chown $USER:$USER /mnt/shared_folder
$ cd /mnt/shared_folder
$ echo test > test
Check from the host that you can see the file test
:
$ cd /kvm_share/shared
$ file test
test: ASCII text
$ echo test > test2
From the guest, you should be able to see the test2
file. That’s it! We’re done. You can now securely transfer files between your host and guest system.
The last thing you will want to do is write a shell script that should probably run as a cron job that will fix the permissions so that both your user and the vm’s user will be able to read and write to the shared folder.