Mullvad VPN App 4.2 setup guide

did you reboot the qube after the change?

yes,

could it be something with the MTU issues ?

No, you clearly face a DNS issue here, the MTU isn’t related.

I’m not sure what to do next to help you debug this… If you know how to use tcpdump/wireshark, it could be interesting to see what happens in the mullvad vpn when an AppVM make a DNS request.

What’s the output of this command in your VPN qube?

sudo nft list table ip qubes
1 Like

table ip qubes {
set downstream {
type ipv4_addr
elements = { 10.137.0.10 }
}

set allowed {
	type ifname . ipv4_addr
	elements = { "vif8.0" . 10.137.0.10 }
}

chain prerouting {
	type filter hook prerouting priority raw; policy accept;
	iifgroup 2 goto antispoof
	ip saddr @downstream counter packets 0 bytes 0 drop
}

chain antispoof {
	iifname . ip saddr @allowed accept
	counter packets 0 bytes 0 drop
}

chain postrouting {
	type nat hook postrouting priority srcnat; policy accept;
	oifgroup 2 accept
	oif "lo" accept
	masquerade
}

chain input {
	type filter hook input priority filter; policy drop;
	jump custom-input
	ct state invalid counter packets 0 bytes 0 drop
	iifgroup 2 udp dport 68 counter packets 0 bytes 0 drop
	ct state established,related accept
	iifgroup 2 meta l4proto icmp accept
	iif "lo" accept
	iifgroup 2 counter packets 0 bytes 0 reject with icmp host-prohibited
	counter packets 0 bytes 0
}

chain forward {
	type filter hook forward priority filter; policy accept;
	jump custom-forward
	ct state invalid counter packets 0 bytes 0 drop
	ct state established,related accept
	oifgroup 2 counter packets 0 bytes 0 drop
}

chain custom-input {
}

chain custom-forward {
	tcp flags syn / syn,rst tcp option maxseg size set rt mtu
	oifname "eth0" counter packets 0 bytes 0 drop
}

chain nat {
	type nat hook prerouting priority dstnat; policy accept;
	iifname "vif*" tcp dport 53 dnat to 10.64.0.1
	iifname "vif*" udp dport 53 dnat to 10.64.0.1
}

chain dnat-dns {
	type nat hook prerouting priority dstnat; policy accept;
	ip daddr 10.139.1.1 udp dport 53 dnat to 10.139.1.1
	ip daddr 10.139.1.1 tcp dport 53 dnat to 10.139.1.1
	ip daddr 10.139.1.2 udp dport 53 dnat to 10.139.1.2
	ip daddr 10.139.1.2 tcp dport 53 dnat to 10.139.1.2
}

}

I’m not sure which rules will take priority here.

Can you change:

nft add chain qubes nat { type nat hook prerouting priority dstnat\; }

to

nft add chain qubes nat { type nat hook prerouting priority dstnat -1\; }

In your /rw/config/qubes-firewall-user-script and restart VPN qube?

1 Like

just changed it and restarted qube, still no change.

What if you replace 10.64.0.1 with 9.9.9.9?
You can run these commands for a test in your VPN qube:

sudo nft flush chain ip qubes nat
sudo nft add rule qubes nat iifname == "vif*" tcp dport 53 dnat 9.9.9.9
sudo nft add rule qubes nat iifname == "vif*" udp dport 53 dnat 9.9.9.9
1 Like

just ran these commands and still no connection on the appvm,

Can you check if curl with IP address will work in AppVM?

curl https://9.9.9.9

[user@work ~]$ curl https://9.9.9.9
not found[user@work ~]$

Ok, seems to really be a problem with DNS.
Does DNS work in VPN qube itself?

Could you try to modify the fix DNS part by adding the keyword counter at the end, do some DNS requests in an appvm and then use nft list ruleset (this will show all rules in the mullvad vpn qube, if you added firewall rules in an appvm, it will be displayed, this may leak information you don’t want to)

this should look like this

DNS=10.64.0.1
nft add chain qubes nat { type nat hook prerouting priority dstnat\; }
nft add rule qubes nat iifname == "vif*" tcp dport 53 dnat "$DNS" counter
nft add rule qubes nat iifname == "vif*" udp dport 53 dnat "$DNS" counter

we will be able to figure if the rules is actually used

yeah it works fine in the VPN qube, for some reason i just cant get the appvm to connect to it, the browsers wont connect.

What’s the content of /etc/resolv.conf in AppVM?

this shouldn’t matter because the mullvad qube intercept it and redirect using nftables

It could be empty.

1 Like

[user@work ~]$ sudo nft list ruleset
table ip qubes {
set downstream {
type ipv4_addr
}

set allowed {
	type ifname . ipv4_addr
}

chain prerouting {
	type filter hook prerouting priority raw; policy accept;
	iifgroup 2 goto antispoof
	ip saddr @downstream counter packets 0 bytes 0 drop
}

chain antispoof {
	iifname . ip saddr @allowed accept
	counter packets 0 bytes 0 drop
}

chain postrouting {
	type nat hook postrouting priority srcnat; policy accept;
	oifgroup 2 accept
	oif "lo" accept
	masquerade
}

chain input {
	type filter hook input priority filter; policy drop;
	jump custom-input
	ct state invalid counter packets 0 bytes 0 drop
	iifgroup 2 udp dport 68 counter packets 0 bytes 0 drop
	ct state established,related accept
	iifgroup 2 meta l4proto icmp accept
	iif "lo" accept
	iifgroup 2 counter packets 0 bytes 0 reject with icmp host-prohibited
	counter packets 0 bytes 0
}

chain forward {
	type filter hook forward priority filter; policy accept;
	jump custom-forward
	ct state invalid counter packets 0 bytes 0 drop
	ct state established,related accept
	oifgroup 2 counter packets 0 bytes 0 drop
}

chain custom-input {
}

chain custom-forward {
}

}
table ip6 qubes {
set downstream {
type ipv6_addr
}

set allowed {
	type ifname . ipv6_addr
}

chain antispoof {
	iifname . ip6 saddr @allowed accept
	counter packets 0 bytes 0 drop
}

chain prerouting {
	type filter hook prerouting priority raw; policy accept;
	iifgroup 2 goto antispoof
	ip6 saddr @downstream counter packets 0 bytes 0 drop
}

chain postrouting {
	type nat hook postrouting priority srcnat; policy accept;
	oifgroup 2 accept
	oif "lo" accept
	masquerade
}

chain _icmpv6 {
	meta l4proto != ipv6-icmp counter packets 0 bytes 0 reject with icmpv6 admin-prohibited
	icmpv6 type { nd-router-advert, nd-redirect } counter packets 0 bytes 0 drop
	accept
}

chain input {
	type filter hook input priority filter; policy drop;
	jump custom-input
	ct state invalid counter packets 0 bytes 0 drop
	ct state established,related accept
	iifgroup 2 goto _icmpv6
	iif "lo" accept
	ip6 saddr fe80::/64 ip6 daddr fe80::/64 udp dport 546 accept
	meta l4proto ipv6-icmp accept
	counter packets 0 bytes 0
}

chain forward {
	type filter hook forward priority filter; policy accept;
	jump custom-forward
	ct state invalid counter packets 0 bytes 0 drop
	ct state established,related accept
	oifgroup 2 counter packets 0 bytes 0 drop
}

chain custom-input {
}

chain custom-forward {
}

}
[user@work ~]$

nameserver 10.139.1.1
nameserver 10.139.1.2

Do some DNS requests in an appvm and then use sudo nft list chain ip qubes nat in your VPN qube to check the counter.