It’s not really about disconnecting, but rather adapting to user preferences.
Mullvad provides multiple DNS IPs based on the protocol/feature used, so using a fixed IP would make many features of the app useless.
as of right now, mullvad always sets nameservers to 10.64.0.1
This is the case for Wireguard with default settings.
However, enabling any DNS filters will switch it to the 100.64.0.0 range, with the last part changing according to the enabled lists.
anyone else having any issues on DNS connectivity inconsistency? Sometimes its just painfully slow to connect and speeds fall off a cliff.
i use vpn over mullvad (wireguard) with no issues.
Ive experimented with vpn settings + quantum resistance through the app but that doesnt seem to fix my issues
Because the symptoms in your case are not as simple as “it never works”, you should consider the possibility that it’s an MTU issue.
Are you familiar with PMTU problems and have you looked into it? Factors will be your Internet provider MTU and whether you’re using any encapsulation of your own beyond the Wireguard encapsulation in the netVM in question
is the fix dns script 100% leak proof? the fact that it dynamically changes kinda bothers me tbh i need a setup that is 100% leak proof - re there patches that would assure this?
There’s nothing to worry about if you use lockdown mode in the app and the qubes firewall (qvm-firewall in dom0) to only allow the entry IP of your server(s).
thank you, but regardless, is it possible to permanently set dns to mullvad’s servers?
If you plan to always use the same configuration, without any DNS filtering and with the wireguard protocol, you can set this in /rw/config/rc.local instead of the script:
nft flush chain qubes dnat-dns
nft add rule ip qubes dnat-dns meta l4proto { tcp, udp } ip daddr { 10.139.1.1, 10.139.1.2 } th dport 53 dnat to 10.64.0.1
now that’s what i’m talking about. thank you!
Thank you! I used this guide with Fedora42 and it works great. Ok also the operation of DNS with Duckduckgo.
I checked on Mullvad’s website and it’s ok. In the recommendations on the site it says to disable DNS over HTTPS(if you use Firefo o or Libre Librewolf.
Has anyone tried scripting out a dom0 utility to programmatically set qvm-firewall rules governing the Mullvad VPN app qube based on the current WireGuard endpoint IP chosen by the app?
Like from dom0:
- query the vpn app qube for the current endpoint IP
- set up the
qvm-firewallkillswitch implemented on thesys-firewallabove the vpn app qube in thenetvmhierarchy, using the current endpoint IP
And rerun as needed when the endpoint IP changes.
Can this work? Will the Mullvad VPN app have a fit if it is isolated to an IP for a time once its WireGuard tunnel is in place? I believe it generates some of its own heartbeat/statistic traffic unrelated to the tunnel, but I don’t know if it ‘needs’ to be able to do that stuff to function.
(The goal here being to have the versatility of changeable VPN geography merged with the stronger killswitch security of a non-Mullvad app, static endpoint sys-vpn qube.)
This kind of thing is totally possible, but then you open a way for a compromised mullvad to be allowed to get to a new endpoint, it’s kind of dangerous if implemented incorrectly.
I don’t see much risks in just opening a static list of hosts that are all owned by mullvad.
You could layer these, right? One broad qvm-firewall killswitch that limits the vpn qube to a large-ish static list of mullvad-owned IPs, and then a dynamic qvm-firewall killswitch implemented above or below that (but always above/outside the vpn qube) that limits the vpn qube to a single IP, its current tunnel endpoint (which also appears in the large-ish static list).
I implemented this idea a while ago, using qubesdb-write in the sys-vpn qube, and qubesdb-watch in dom0, along the lines of:
-
a NetworkManager hook in sys-vpn gets executed on each network change; the hook looks for any wireguard tunnel,extracts the endpoint IP, then invokes:
qubesdb-write /vm-config/currentIP ${VPN_ENDPOINT} -
in dom0, a script invokes:
qubesdb-watch -d ${sys-vpn-name} /vm-config/currentIP…which waits indefinitely for a change; when a change is detected, the ${VPN_ENDPOINT} is extracted with qubesdb-read, then qvm-firewall is used to whitelist this IP and remove the previous whitelist. Then it loops again to qubesdb-watch, waiting for a change…
It works. But in the end, as @solene writes, there are two factors that made me abandon the idea:
- the list of endpoints I use is not so long
- if the sys-vpn qube is compromised, then it can request any whitelisting, right? The only thing needed being a new wireguard connection. Ok, this is raising the bar quite a lot for an attacker, but all in all my threat model is not justifying this complexity.
Note: I am using the name “currentIP” but it does not mean it has to be an IP
… it works as well with a DNS name.
Thanks for your input.
That’s a great point that a compromised VPN qube could request any whitelisting. So ultimately the static whitelist is the only reliable line of defense. The dynamic whitelist (clever hook → qubesdb-write → qubesdb-wait solution btw, smarter than what I was imagining) is workable only if you don’t worry too much about the risk of wrong endpoint, and if you don’t worry too much about that then you probably don’t really need this extra infrastructure.
Perhaps there is a middle ground such that the dynamic single-IP whitelisting is always manually initiated from dom0, and the current tunnel IP in the vpn app qube must match what dom0 expects to see. But, at that point probably it’s best to not do any of that and instead just set up a bunch of non VPN-app static wireguard sys-vpn qubes.
Whitelisting only vpn endpoints is a failsafe against a VPN that would not connect and the qube would route network without the VPN.
If the VPN qube is compromised, it can exfiltrate whatever it wants through the VPN, the firewall rules are not there to protect against this.
Good point.
Yes, the impulse underlying my thinking has been more about strictly geo-locking the VPN than about mitigation of compromise. A standard Mullvad subscription gets you 5 static routings at one time, so at most 5 sys-vpn qubes for 5 geographies. But the Mullvad app allows switching up the routing at will, so with a little bit of careful orchestration you could have more geographic routings than 5 on a single subscription as long as you don’t need to run them all at the same time.