Mullvad + Wireguard on Qubes-OS

Hi everyone,
I looked for every thread in this forum but I could not find an answer for my specific case:

I would like to redirect all my traffic trough Mullvad’s Wireguard Servers (except Whonix/sys-whonix traffic, for confidentiality reasons).
The problem is that most of the guides are talking about Openvpn/.conf files, and they are usually pointing to just one server if they are talking about Wireguard.

  • How can I use Wireguard, maybe via the GUI app, to redirect the whole traffic of my Qubes?
  • Also, what if I install the application in the Templates that I’m using and then running it on the AppVMs that I want to redirect the traffic from, and then let it run?

I run mullvad wiregard with this:

I followed the instruction and it just works!!

I have multiple proxy qubes. Each point to a different mullvad server.

Hope it helps!!
Good luck


The problem is that with this method, I have to create a lot of different qubes… And I don’t like this idea, I would like a cleaner solution

Install the gui app on your template, and make sure “network-manager” service is activated on the network-providing appvm. Then add /etc/mullvad-vpn to bind-dirs. Done.

Thanks, but can you please provide a more detailed explanation?

I’m new to Qubes and just started my journey here :slight_smile:

Ok, lets try.

  1. Create new template based on Fedora/Debian template. For example qvm-clone fedora-33 mullvad-template. Start the shell in new template.
  2. Copy the Mullvad installation .rpm to your template (download it with internet-connected appvm, verify signature, copy using Qubes tools (right-clock, copy to other appvm → mullvad-template)
  3. In the mullvad-template, convince the OS to install unsigned .rpm (at least the last time I tried it was unsigned). So something like sudo rpm -ivh --nosignature MullvadVPN-2021.4_x86_64.rpm. Most likely some packages are missing, but rpm should tell you. For example sudo dnf install libXScrnSaver libnsl. The .rpm doesn’t have rpm signature, but the binary was verified with gnupg in the previous step.
  4. Shut down the template.
  5. Next, create new appvm based on this template. Nothing special here, just normal appvm based on mullvad-template in this example. In the Advanced tab, click “provides networking”. In the services tab, add network-service with the + button.
  6. In the appvm, configure bind-dirs for /etc/mullvad-vpn as explained here. Reboot.
  7. In the appvm, start the GUI /opt/Mullvad VPN/mullvad-gui. Configure it to your taste. Click “Lauch app on start-up” in the Preferences.

When I tried this, both wireguard and openvpn worked, but for me the wireguard hangs every now and then. Probably some network interface issue, not related to Qubes / Linux.

Now you can assign this new network-providing appvm to any client you want to use VPN.

You could make the appvm as standalone (skipping the template creation, and installing .rpm directly to standalone appvm, and no need to configure bind-dirs), but with this procedure you can create more VPN appvm’s that can run at the same time, all deriving from the common template mullvad-template.

Maybe I forgot something, so please try it out and let me know how it went.


How about installing Mullvad on a StandaloneVM template based on the Fedora-32 template? You don’t have to create an AppVM and deal with bind-dir. Frankly it’s a lot of overhead for a VPN app.

I tried a fedora-32-minimal template but it didn’t work because of some keyring issue. I’m not sure if I installed all the relevant packages to make it work.

Another route I tried was installing my VPN app on an AppVM and using bind-dir to make the relevant folders / files persistent but it didn’t work so I resorted to using a StandaloneVM. Also those instructions for making /rw/config/qubes-bind-dirs.d didn’t work for me. It worked in /rw/bind-dirs. The few files that persisted were saved in there.

Yes, if all you need is one vpn-providing appvm, standalone is better.

Just from a security perspective, I think using a separate VM for your VPN is better than setting up a VPN inside an AppVM. Otherwise you are opening up a potential avenue into the AppVM.

Using third-party apps for VPN connections, rather than connecting through mechanisms in the OS, can also be less secure.

There’s always a trade off with convenience and security and maybe this won’t matter to you, but for other users’ sake it’s something to consider. If you want better security while using a VPN, something like Qubes-VPN-Support in a dedicated VM is a good way to go.

You can have multiple configuration files on the VPN VM if multiple VPN qubes isn’t to your liking.

1 Like

Yes, this is the reason why “Qubes people” always recommend manual VPN configurations, but the OP was asking about Mullvad gui app, and that’s what I answered to. Personally, I don’t find it any less “secure”, whatever that means in this context. Yes, the gui app might be buggy or something, but in the end, it will communicate with the same servers using same protocols.

I wouldn’t install that on my normal templates though, just to keep things clean and simple.

Edit: I added comment about signature verification to my instructions.

The gui also has a killswitch that works automatically regardless of server. In that regard, I find it more secure than openvpn which has limited killswitch options.

I had the belief it’s more secure to install a third party vpn app in an AppVM. If it’s shady it doesn’t affect an entire template. Plus it’s designed simply to function as a vpn proxy. Unfortunately, this route doesn’t work anyway since it’s not persistent.

I’ve had limited success writing scripts to move the required vpn files from /usr to /home/user and back to /usr again after restart. Or I would have to change the existing vpn python scripts to permanently reference /home/user but I don’t know if that’s possible.

If you aren’t running the vpn GUI software in your TemplateVMs, then it shouldn’t affect the template.

Absolutely, I wasn’t criticising your answer. It’s informative and I’m sure what a lot of people want. YTMMV (Your threat model may vary :wink: )

But for others coming across the thread it’s useful to know the security implications.

I think Mullvad is open source and written in Rust, so as clients go, it’s probably a good one.

This is a useful note Tasket put on the Qubes-VPN-Support github repo:

“Since it is the job of a VPN vendor to focus tightly on link security, you should be wary of VPN clients that manipulate iptables or nftables in an attempt to secure the system’s communications profile (i.e. prevent leaks); they probably don’t take Qubes’ unusual network topology into account in which case anti-leak would fail. Normally, security should be added to a VPN setup from the OS or specialty scripts (like these) or by the admins and users themselves. An exception to this is the LEAP bitmask client, which alters iptables with its own anti-leak rules that account for Qubes.”

I’m not sure if this applies to Mullvad, but if you’re very security focused (or paranoid :D) it’s probably best to use the OS or openVPN as they’re well tested. And use a separate VM for your VPN.

This I haven’t tested with the Mullvad gui app.

Most simple kill switch would be to limit VPN qubes traffic to the VPN gateway only using Qubes firewalling, but that is kinda difficult in this case, because I’d imagine one would use the gui app for flexibility. That is, being able to switch connections very quickly, and in that case all the possible gateway IP’s would need to be taken into account. That is certainly possible, but a lot of work.

" Qubes is also powerful. Organizations like the Freedom of the Press Foundation, Mullvad, and Let’s Encrypt rely on Qubes as they build and maintain critical privacy and security internet technologies that are in turn relied upon by countless users around the world every day." - Introduction | Qubes OS

Since the Mullvad team is using Qubes-OS, would be great to receive an “official” answer from them. Is someone able to contact them and link this thread?

1 Like

Thanks for the detailed instructions. I can’t believe it’s that easy. I’m trying it this way next time.

Somehow something still doesn’t work with this setup, I can’t pass through any traffic from other vm’s (though the vpn works fine for this specific qube). Seems like the traffic isn’t routed through the wg-mullvad interface and everything is blocked. Does anyone know about setting up bridges securely that forward packets from client-vms to wg-mullvad interface?

Try this from github

works flawlessly qubes 4.1rc3 with mullvad wireguard

1 Like

Thanks, I’ll have a look at it once I have some time :slight_smile:. Does it also work with the mullvad cli? Or do I have to do all the steps for setting up a pure wireguard? I’m looking for the flexibility of automatically pulling the configs and switching servers, which I guess I’d either have to script or do manually with the wg-tools approach…