Mullvad uses many different DNS addresses depending on what the user selects in the app. The default Wireguard DNS address is 10.64.0.1, but it can also be in the 100.64.0.x range if the user chooses to use the DNS filtering rules.
For OpenVPN, it’s different too. Each port gives a different subnet and the DNS is always 10.x.0.1. DNS filtering (100.64.0.x) also works with OpenVPN.
Since it’s hard to know what protocol the user will be using and if they will be using any DNS filtering rules, I would recommend adding the following script to update the DNS accordingly:
#! /usr/bin/env bash
update_dns() {
# mullvad_on: 0 -> off, 1 -> on
mullvad_on=$([[ $(grep -v -c "nameserver \+10.139" /etc/resolv.conf) -gt 0 ]] && echo 1 || echo 0)
if [[ $mullvad_on -eq 1 ]]; then
echo "Mullvad is on"
# get the mullvad dns ip address. First one is used if there is more than one.
mullvad_dns_ip=$(grep "nameserver" < /etc/resolv.conf| awk '{print $2}' | head -n 1)
# delete all the lines defined in dnat-dns
sudo nft flush chain ip qubes dnat-dns
# forward all dns requests to mullvad dns servers
sudo 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 "$mullvad_dns_ip"
else
echo "Mullvad is off"
# get qubes nameserver ip addresses
nameserver_ips=$(grep "nameserver" < /etc/resolv.conf| awk '{print $2}')
# delete all the lines defined in dnat-dns
sudo nft flush chain ip qubes dnat-dns
# add rule to forward dns requests to qubes nameservers
for ip in $nameserver_ips; do
sudo nft add rule ip qubes dnat-dns ip daddr "$ip" udp dport 53 dnat to "$ip"
sudo nft add rule ip qubes dnat-dns ip daddr "$ip" tcp dport 53 dnat to "$ip"
done
fi
}
update_dns
# check for /etc/resolv.conf content change
inotifywait -m -q -e close_write /etc/resolv.conf | while read -r;
do
update_dns
done
However it doesn’t allow to easily change VPN server on the fly
I would feel better if a killswitch was whitelist-based instead of blacklist-based like here. Maybe it would be better to drop everything by default and only allow packets on Mullvad’s interface?
New Qubes user here. I struggled for a bit and want to clarify what I had trouble with for any other less experienced users.
I was thinking the DNS script wasn’t working because Mullvad’s leak checker kept telling me I was leaking. This was not because of the script DVM wrote, which works, but was actually from a Firefox browser setting.
When you do the leak check on mullvad’s site and read the DNS leak guide, it has the answer. You have to disble “DNS over HTTPS” setting in Firefox ESR. By default it is enabled and made it so I was using a Cloudflare DNS server nearby the VPN server.
Also it wasn’t clear to me by reading this thread, but the script DVM wrote needs to be run in the sys-mullvad-vpn-app qube terminal, not the Dom0 terminal. The script needs to be run again if you change the settings in the DNS blocking inside the Mullvad app, however it seems like you don’t need to run the script again just to change the VPN server if it has the same DNS blocking settings. The script also needs to be run again after reboot.
Could someone give specific instructions on how to set up the killswitch in the qvm-firewall? I barely know what I’m doing and don’t want to break anything since I have the VPN working now.
I did this guide exactly same, same fedora version everyting.
Now the proxy vm which has mullvad gui app seems to somehow provice internet to app vm, because telegram app is working via mullvad vpn, and firefox mullvad extensions shows “connected to mullvad” status, and says the proxy is working… but the firefox can’t connect to any websites. Same with chrome and other app vms.