Itâs possible but iirc the network stack of rootless KVM (qemu:///session) only support very basic networking option with SLiRP. Can it be configured to run Whonix as-is?
Possibly related:
Also worth noting is that, at least on Ubuntu, even with QEMU/KVM connection (Libvirt uri: qemu:///system ) QEMU arenât run as root, but as a separate user âlibvirt-qemuâ.
Lets see, hopefully one day qubes-os gonna be having KVM based qubes which gonna help alot.
You can change the user in the libvirt config. Even auto chown for self-generating files like snapshots or images is possible.
By default it uses root though, if Iâm not mistaken. At least on Debian I believe.
Pretty sure thatâs not the case. The Qemu processes are run as user libvirt-qemu on my computer as we speak. You can ps -ef |grep qemu on host to see if this was true.
This is looks like a must in case of Kicksecure, as the current way of importing Whonix to KVM cant be done on user side (nor sysmaint):
Severity: Critical.
This makes KVM port more or less unsupported.
The absence of porting KVM to rootless makes Whonix KVM (and Kicksecure KVM) incompatible with a default Kicksecure installation, which comes with user-sysmaint-split.
Right now:
- Installation commands: Such as
sudo virsh -c qemu:///system net-define Whonix_external*.xmlmaybe can be run in sysmaint session. - Start commands: Such as
sudo virsh start Whonix-Gatewayshouldnât be run in sysmaint session and cannot be run in user session.
In effect, Kicksecure hosts are incompatible unless unrestricted admin mode is enabled,which would be silly to suggest, since KVM seems to support rootless.
Hence porting to rootless is crucial.
Please kindly fix ASP. @HulaHoop
From researching this, apparently it is the networking that throws a wrench in the possibility of easily running rootless QEMU, but it seems to have been resolved and documented. Since I am not running the appropriate host setup to experiment I ask @nurmagoz to please help test these instructions and report back on a Kicksecure host
A solution is in these articles to run libvirt under a qemu:session vs the qemu:system default connection. passst is superior to SLIRP if we have to go down the emulated network route.
https://bbs.archlinux.org/viewtopic.php?id=262025
https://www.gns3.com/gns3-cannot-work-with-qemu
Thanks to this Reddit article (https://old.reddit.com/r/archlinux/comments/b9emxp/qemusystemx86_64_does_not_execute_how_can_i/ek47btb/), I found the issue.
I opened an issue ( qemu-system-x86_64 fails to run with regular user after following arch wiki article (#515) ¡ Issues ¡ QEMU / QEMU ¡ GitLab ) to qemu developers (where you can see the resolution.
And I edited the Arch Wiki article ( QEMU - ArchWiki ) that led to this issue.
I went ahead and experimented with this.
File â Add connection â QEMU user session
Experimented with adding KS under this connection type which is straight forward enough:
-
Use tar to decompress the archive:
tar -xvf Kicksecure*.libvirt.xz -
Import the Kicksecure ⢠image. Kicksecure ⢠works with the network named default out of the box:
virsh -c qemu:///session define Kicksecure*.xml -
Moving the Kicksecure ⢠Image File
mv Kicksecure*.qcow2 /home/user/.local/share/libvirt/images/Kicksecure.qcow2
Change path in KS xml to redirect to /home/user/.local/share/libvirt/images
The networking is where things get hairy and despite following the most recent and correct instructions for Debian, I end up with:
âNetwork not found: no network with matching name âdefaultââ
So letâs explain how networking is supposed to work on a session connection. You cannot directly create any useful type of connection under this unprivileged mode. VMM would burp out an error that you donât have permission to create a bridge. The only possible workaround is to use the qemu-bridge-helper binary to act as a liaison between the VMs running as users and the bridge networks created under the system connection.
You would need to add the virtual bridge interface names to a whitelist, then adjust the permissions for that whitelist file and the qemu-bridge-helper binary and enable IP forwarding as a sysctl option and Bobâs your uncle. Except all these widely documented steps donât seem t be working and I get the aforementioned error
This is the most recent documentation that has improved on earlier referenced version. Perhaps someone can pull up their sleeves and give this a go and tell me what weâre missing here.
Yeah i tested this and we dont need sudo to use virsh because we added âkvmâ user already:
maybe we can remove âsudoâ from the commands in the wiki.
This is not as easy as its written, user need commands gymnastics in order to avoid the path issue:
/var/lib/libvirt/images/
E.g:
- Create new (user level) path on user side e.g ~/VMs/Whonix.
- Move or copy the images to the new path.
- Change the paths inside the .xml for both workstation and gateway to the new created path.
- As per libvirt documentation:
The directories containing disk images must either have their ownership set to match the user/group configured for QEMU, or their UNIX file permissions must have the âexecute/searchâ bit enabled for âothersâ.
The simplest option is the latter one, of just enabling the âexecute/searchâ bit. For any directory to be used for storing disk images, this can be achieved by running the following command on the directory itself, and any parent directories
chmod o+x /path/to/directory
In particular note that if using the âsystemâ instance and attempting to store disk images in a user home directory, the default permissions on $HOME are typically too restrictive to allow access.
This means Libvirt disk image files and their parent directories must be accessible to the user/group under which QEMU runs, and parent directories need execute/search permission, so it means has access to these paths:
/home/user
/home/user/VMs
/home/user/VMs/Whonix
/home/user/VMs/Whonix/*.qcow2
Note: preferable to install acl package and use setfacl in order to only give access to libvirt-qemu for reading .qcow2 files (not to every other user).
e.g of usage:
setfacl -m u:libvirt-qemu:--x /home/user
then when you run:
virsh -c qemu:///system start Whonix-Gateway
Will give:
error:Failed to create file
/var/lib/libvirt/dnsmasq/virbr1.macs,new: no such file or directory
And lets go into another gymnastics of commands..
Thats crazy to have it done from normal user just to make a hypervisor running whonix or x distro.
So without a method to have the KVM smoothly running by default (can be installed and configured by default in KS/Whonix), KVM can be considered incompatible in KS/Whonix.
Please ignore the storage path problems. This part is easily solved by using an alternative path under the user directory and is inconsequential. For now go ahead and follow the first steps when moving the image file and adjusting the xml to reflect that new path.
What we need to solve is the networking issue because without it, the VMs are useless without connectivity.
We should not touch the wiki instructions until this is completely solved.
Then we can mark the Whonix KVM (and Kicksecure KVM) port as unsupported.
Because Whonix is based on Kicksecure, if the Whonix KVM maintainer does not have a host setup to ensure Whonix support on Kicksecure hosts, as well as compatibility in source code, documentation, and testing, then Whonix KVM (and Kicksecure KVM) is effectively unsupported.
From sysmaint:
This is needed since we are using qemu:///system not qemu:///session
sudo mkdir -p /var/lib/libvirt/dnsmasq
sudo chown root:root /var/lib/libvirt/dnsmasq
sudo chmod 755 /var/lib/libvirt/dnsmasq
Then on user side:
virsh -c qemu:///system net-start Whonix-External
virsh -c qemu:///system net-start Whonix-Internal
Then run Whonix-Gateway and Workstation normally.
Some might say what about using SLIRP (instead of virbr0) with qemu:///session isnt it for usermode?
Well its too much restricted to the level it can break many things e.g current bridge (check here).
Unless something new does resolve this issue (which i didnt find), qemu:///system is going to be used.
Sadly yes and no solution to this seems to be.
Not really that much of helpful as we need more than just one VM to have internet, its like:
Whonix-Workstation â Whonix-Internal â Whonix-Gateway â Whonix-External (Internet/Tor)
I dont think anybody explained how to solve this on the internet.
I went ahead and completely ported KS and Whonix to work under QEMU session as documented below. I had to use passt and (internal) network tunneling to replace the current nework architecture, since qemu-bridge-helper was useless.
Itâs great news because now no sudo is needed at any point in the setup or runtime process.
This may also help solve the OpenVPN on the host issue thatâs been reported before as incompatible and the lingering dnsmasq problem too (both need to be confirmed)..
Great progress!
The idea is get fully rid of qemu:///system and exclusively use qemu:///session.)
Likely not, because your current version is still using IP addresses.
Ported to unix domain socket files. Please test and take over:
No Internet Connection inside Whonix-Workstation KVM with NordVPN with Kill-Switch on Host - #16 by Patrick
- For qemu commandlines to be accepted in the file, the XML namespace needs to be included in the first line of the settings file (or the QEMU commands block)
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
- One will run into Apparmor issues when using QEMU commands since they are treated as arbitrary and not whitelisted by default
libvirt: QEMU command-line passthrough - Testing the git branch settings for sockets triggered this bug which I donât even know how to begin to diagnose. I think we are better off using what we currently know works
Error starting domain: internal error: process exited while connecting to monitor: 2026-06-03 qemu-system-x86_64: -device {âdriverâ:âvirtio-vgaâ,âidâ:âvideo0â,âmax_outputsâ:1,âbusâ:âpcie.0â,âaddrâ:â0x1â}: PCI: slot 1 function 0 not available for virtio-vga, in use by virtio-net-pci,id=(null)
- Indeed libvirt cannot process relative paths. I think the only easy solution that is readily implementable is to create a subdirectory under /opt/ with user accessible permissions and use that as the storage pool for QEMU session
Linux /opt Folder Permissions: Best Practices for Developer Access and Software Installation on Ubuntu â linuxvox.com - Someone on SE suggests using /srv/ instead for this purpose. Letâs decide on the cleanest way to use a generic dir for this
https://unix.stackexchange.com/questions/70700/whats-the-most-appropriate-directory-where-to-place-files-shared-between-users#70708
*The reason I picked vhost-user over user is performance. I am wary of allowing untrusted access to shared memory though. The GW should be trusted but KS VMs shouldnât. Perhaps we can opt for just âuserâ for the latter.
Since 11.1.0 (QEMU and KVM only) you may prefer to use the passt backend with the more efficient and performant type=âvhostuserâ rather than type=âuserâ. All the options related to passt in the paragraphs below here also apply when using the passt backend with type=âvhostuserâ; any other details specific to vhostuser are described here.
This is a compelling alternative, because passt provides all of its network connectivity without requiring any elevated privileges or capabilities, and vhost-user uses shared memory to make this unprivileged connection very high performance as well.
libvirt: Domain XML format
Attempting to remove the dnsmasq-base package out right would rip the guts out of the libvrit install.[1] After a brief search it was suggested that disabling âdefaultâ network should disable dnsmasq and it was indeed the case as confirmed by ânetstat -tulpenâ. So by not creating or using a network that would use dnsmasqâs services it is never used and can be safely ignored.
[1]
sudo apt purge dnsmasq-base
The following package was automatically installed and is no longer required:
libvirt-daemon-config-nwfilter
Use âsudo apt autoremoveâ to remove it.REMOVING:
dnsmasq-base* libvirt-bin* libvirt-daemon-config-network* libvirt-daemon-driver-lxc* libvirt-daemon-driver-network* libvirt-daemon-system*Summary:
Upgrading: 0, Installing: 0, Removing: 6, Not Upgrading: 0
Freed space: 1,873 kBContinue? [Y/n]