Why can’t I do DNS lookups after I configure a VM with Firewall rules?
I’m trying to create a domain-specific VM – that is a VM that can do outgoing connections to a single domain. But as soon as I use the Qube Manager GUI to change the Firewall rules tab from Allow all outgoing connections to Limit outgoing connections to ... and click Apply, the VM looses the ability to query for DNS. This is despite the fact that the documentation (and the window itself) says that All DNS requests and ICMP (pings) will be allowed regardless of the settings I make.
Steps to reproduce
Create a new VM named domain-specific with Debian 12 template
Boot the new VM, and attempt to do a DNS lookup
user@domain-specific:~$ dig qubes-os.org
; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> qubes-os.org
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43480
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;qubes-os.org. IN A
;; ANSWER SECTION:
qubes-os.org. 300 IN A 188.114.96.3
qubes-os.org. 300 IN A 188.114.97.3
;; Query time: 3406 msec
;; SERVER: 10.139.1.1#53(10.139.1.1) (UDP)
;; WHEN: Wed Dec 04 10:54:25 -05 2024
;; MSG SIZE rcvd: 73
user@domain-specific:~$
Open the Qubes Manager GUI
Right click on the domain-specific VM and click on Edit firewall
Click on the radio button Limit outgoing connections to ...
Click the green + icon, type qubes-os.org into the Address field, and click OK
Click the Apply button
Again attempt to do a DNS lookup
user@domain-specific:~$ dig qubes-os.org
;; communications error to 10.139.1.1#53: host unreachable
;; communications error to 10.139.1.1#53: host unreachable
;; communications error to 10.139.1.1#53: host unreachable
;; communications error to 10.139.1.2#53: host unreachable
; <<>> DiG 9.18.28-1~deb12u2-Debian <<>> qubes-os.org
;; global options: +cmd
;; no servers could be reached
user@domain-specific:~$
Note that this issue happens if you omit #6 above (leaving the firewall table empty).
My understanding is that DNS shouldn’t be affected by these rules, but clearly it is. Why?
Update: The Net qube for this domain-specific VM is a sys-vpn Qube.
If I change the domain-specific VM to use sys-firewall directly (as opposed to sys-vpn which then is connected to sys-firewall), the issue disappears and I’m able to use DNS again.
Why is this? And what do I have to do to restrict a VM such that:
It can only make outgoing connections to a single domain (eg qubes-os.org)
all of its traffic is forced through a shared sys-vpn network-providing VM
In the netvm of this qube, check the qubes-firewall iptables rules and see if they are set correctly. Since it’s a VPN qube, something may have gone wrong and the rules are not being applied as expected.
Update: if I switch the networking VM of my domain-specific VM from from my sys-vpn VM to the sys-whonix VM, then a couple of interesting things happen:
I’m able to do DNS queries again
My domain-specific rules are completely ignored
For clarity, here’s the firewall settings of my domain-specific VM
[user@dom0 ~]$ qvm-firewall domain-specific list
NO ACTION HOST PROTOCOL PORT(S) SPECIAL TARGET ICMP TYPE EXPIRE COMMENT
0 accept qubes-os.org - - - - - -
1 accept - - - dns - - -
2 accept - icmp - - - - -
3 drop - - - - - - -
Sure, I added www.qubes-os.org to the domain-specific VM’s Firewall rules exceptions list too. The DNS lookup still fails to both qubes-os.org and also www.qubes-os.org
Why are you setting firewall rules inside that vm directly instead of a sys-firewall-domain that your domain vm uses as its network vm?
Isn’t having the firewall settings in a vm you use as an app kinda contrary to the Qubes security model? Because the idea is that if your app vm gets hacked, then the attacker can in theory modify your firewall settings from inside the VM and such
Of course, such an attacker would have the know how to get past this DNS issue too as well so maybe getting hacked might solve your problem
In that part of the documentation, there’s this line:
Rules are implemented on the netvm.
If you are on Q4.2, they are all in the qubes-firewall table. You can check this with sudo nft list table ip qubes-firewall in the netvm used by the qube that gets the firewall rules.
Update: I haven’t found a solution to this, but my workaround is:
I’m simply manually defining an IP for the domain (that I want to restrict the domain-specific VM to) in the domain-specific VM’s /etc/hosts file.
I can still specify the actual domain name in the Firewall rules tab of the GUI.
Also, I just upgraded to Qubes 4.2, so I can confirm this is an issue on the latest version of Qubes too.
This works decently for some applications, but other applications throw NS_ERROR_CONNECTION_REFUSED errors – I guess it’s a thing for Mozilla to refuse to let you connect to some servers if the IP is defined in /etc/hosts? It’s not an issue for GET requests in Firefox, but Thunderbird does refuse to let me do OAuth (with NS_ERROR_CONNECTION_REFUSED errors).