Critique this Mullvad VPN access strategy

I have never been sure I am doing the right thing with this setup, but I have found it really very convenient. Since security/privacy is usually inversely related to convenience, something is probably wrong. I’d like to hear your critique.

Objective: GUI Mullvad app in a VPN-vm (as template for disp-vm) - visual representation of connection, easy-to-change locations, killswitch.

  • Mullvad app > Use multihop (bridge) connections.
  • Website (server list) > Select a limited number of “entry” servers to use.
  • Qubes firewall tool (Settings panel) > limit connections to these IP addresses.
  • Mullvad app > chose/change “exit” server in the GUI as you wish.

Qubes Firewall rules (GUI settings panel) doesn’t catch pings or DNS. So,

  • enable Mullvad’s shadowsocks5 proxy in the browser (about:preferences Networking)
  • make sure the option to shunt DNS traffic through the proxy is switched on.

Mullvad’s check page ( always seems to go green for me, although DNS is the slowest to register (especially between server changes). Is it enough to trust this page? If not, what other tests can we do?

wget, curl and gpg (for any network access) don’t work in client qubes, but that’s probably because I haven’t bothered to work out how to pass them through the proxy. (I just use another dispVM).

I have occasionally had Google or a large chain store seem to pick my real location (or close to it), but its not common. That may be a leak through other ‘layers’ (e.g. fingerprinting).

I would love it if someone could point out where this strategy is flawed.


  1. Historically, the Mullvad GUI app has been buggier than manually configuring OpenVPN - likely because a lot more code is needed to both configure the service and make a “visual representation” of the service. Depending on your threat model, it only takes one buggy leak to compromprise you - so it’s probably best to keep unnecessary code to a minimum.

  2. For years, Mullvad tech support has repeatedly endorsed their “Qubes OS 4 and Mullvad VPN” guide as the best way to configure Mullvad in Qubes OS. When asked about the official app, they usually say something like “Sure, you can use that. Many people find it easier to install.” That doesn’t mean it’s the best setup though.

  3. The Qubes firewall GUI in Qubes Manager settings has limitations and lacks the features to properly figure ICMP and DNS.

  4. Socks5 configuration within Firefox does not guarantee VM-wide DNS leak prevention - especially if your VPN proxyVM and browser appVM are different VMs.

  5. It’s unclear if DNS leak prevention (“shunting”) is 100% reliable in the Mullvad app. That is why Mullvad customer support specifically recommends:

  6. An anti-DNS hijacking script ensures that iptables are properly configured to force all DNS requests to and

  7. Mullvad support does not recommend connecting via bridges when using a manually configured firewall and their anti DNS hijacking script. In their words, “It complicates things.” They recommend two “single-hop” proxyVMs (each with their own firewalls/scripting) to achieve the multi-hop (with a quasi-“third hop” created by a socks5 proxy in the appVM in Firefox → settings → network)

  8. curl works just fine from my “client qube” when my VPN proxyVM is sitting behind it.

In my opinion, the best modification of Mullvad’s official Qubes guide is to make the proxyVM disposable.

“Qubes OS 4 and Mullvad VPN” recommends a standalone VM to setup the VPN service. However, I don’t prefer it because I am unable update using dom0/Salt and it lacks the security of volatile/inherited directories. I have had excellent results with fully volatile named disposables for my VPN proxyVMs. You can use the standard Mullvad set up guide with a few minor adjustments (ask if you are unclear) and gain the benefit of more secure updates and knowing that your VPN qube is clean every time it boots.

Also, if you want to connect to a variety of cities, you can create a single configuration file that has 20-30 IP addresses of various global servers that are randomly chosen when you boot. You can also use sudo service openvpn restart to randomly change cities until you find one that you want. This allows you to connect to potentially dozens of cites using a single, manually configured, hardened, fully disposable Mullvad VPN qube.

1 Like

If you are a very “visual” person and insist on some sort of visual feedback (more than curl and sudo ip route show, Micah Lee’s Mullvad setup guide using Network Manager is worth a look. I can’t speak to which approach is the most reliable, but I suspect it is better than trusting the GUI app (simply because VPN GUI apps are notorious for their bugs, regardless of the vendor).

Thank you very much for this.

Its the first time I have seen much of this information. Moreover, written together in one place, cogently.

1 Like

Hi, I would like to do that… could you explain what “minor adjustments” you have done ? I was able to follow the Mullvad tutorial with success using a standalone VM, but I had no success with a disposable VM (based on a Debian minimal template).

Create a named disposable VM (i.e. a “fully volatile” appVM that inherits a root directory from a standard Debian template and a home directory from a “disposable VM template”). In other words, to create a disposable VPN VM, you need to make changes to three different VMs (a standard template, a disposable VM template and a named disposable VM).

Follow the Mullvad guide for installing VPN in a standalone VM with the following exceptions:

  1. Install OpenVPN, enable autostart of OpenVPN and place the Mullvad configuration files in the Debian template.

  2. Add the firewall script to the “disposable VM template” and modify the vif address in the script to match the vif of the named disposable VM.

  3. Configure the network firewall in the settings of the named disposable VM. In dom0, using the qvm-firewall command, configure the DNS, icmp and drop settings for the named disposable VM.

  4. In the named disposable VM settings (Qubes Manager), set the the netVM (basic tab) and enable “provides network” (advanced tab).

When you are done, you will have a named disposable that inherits a root directory (specifically changes made to /etc) from a Debian template and a home directory (specifically changes made to /rw) from a disposable VM template.


To make a “disposable VM template”, simply create an appVM from the main Debian template and in Qubes Manager -> settings -> advanced -> other check “disposable template”

To create the named disposable VM, simply open Qubes Manager and create a new qube with type=“fully volatile” and template= the disposable VM template you created.

1 Like

My approach:

Mullvad VPN GUI App VM (minimal fedora template) >
Sys-firewall 3/4/5 (disposable, specific to the VPN destination VM) >
VPN VM (micah lee setup, disposable, minimal fedora) >

You get the benefit of the mullvad GUI features, a triple bridge, but also fail-safe in case the app leaks. Different base VPN VMs for purpose compartmentalization.

1 Like

Thank your, it worked !