DNS Fails after setting firewall rules (domain-specific VM)

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

  1. Create a new VM named domain-specific with Debian 12 template
  2. 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:~$ 
  1. Open the Qubes Manager GUI
  2. Right click on the domain-specific VM and click on Edit firewall
  3. Click on the radio button Limit outgoing connections to ...
  4. Click the green + icon, type qubes-os.org into the Address field, and click OK
  5. Click the Apply button
  6. 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?

Context

I’m using Qubes 4.1.2 and Debian 12.

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:

  1. It can only make outgoing connections to a single domain (eg qubes-os.org)
  2. 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.

I checked the Firewall rules tab of the sys-vpn VM’s setttings. It is set to Allow all outgoing connections

I meant inside the qube itself with iptables, not in the GUI, since your qube rules are applied on the netvm itself for security reasons.

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:

  1. I’m able to do DNS queries again
  2. 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    -             -         -        -               -          -       -

Yes, I’m able to curl qubes-os.org

user@domain-specific:~$ curl -sL qubes-os.org | tail
  
<!-- Heading anchor links -->
<script src="/js/anchor.min.js"></script>
<script>anchors.add();</script>
  <!-- Remove anchors on team page -->
  

  </div>
</body>
</html>
user@domain-specific:~$ 

…but I’m also able to curl microsoft.com :frowning:

user@domain-specific:~$ curl -sL microsoft.com | tail
                                                                                                        our
                                                                                                        ads</a></li><li>©
                                                                                                Microsoft
                                                                                                2024.303</li></ul></nav></div></footer></div></div></div></span></div>
                <script type="text/javascript">/*<![CDATA[*/var ISLOGGEDIN="False",AUTHMETHOD=0,PAGENAME="smarterror.aspx",PAYLOADTYPE="Page",LOCALE="en-us",JSLLAPPID="mscomsitemuse",MUIDDOMAIN="www.microsoft.com"/*]]>*/</script><script
                        type="text/javascript"
                        src="https://az725175.vo.msecnd.net/scripts/jsll-4.js">/*<![CDATA[*/  /*]]>*/</script><script
                        type="text/javascript"
                        src="https://c.s-microsoft.com/en-us/CMSScripts/script.jsx?k=f65ecb70-094d-0b11-7c9d-7da1bcadfaa7"></script>
        </body></html>user@domain-specific:~$ 

This would be a reasonable workaround if it actually worked :confused:

Why is the firewall not actually restricting like it should when I use the sys-whonix network VM?

Can you try to allow both qubes-os.org and www.qubes-os.org and try again attached to your VPN qube?

If it doesn’t work, can you check the iptables rules inside the VPN qube?

If I remember correctly, the firewall rules are in the QBS-FORWARD table, so something like sudo iptables -t QBS-FORWARD -L should show them.

qvm-firewall does not work on sys-whonix, it uses its own firewall, so the rules are not used.

Are you sure? I assumed the firewall rules would get placed somehow between the AppVM and its NetVM so that we don’t have to trust either.

Anyway, I’m not seeing any rules on the NetVM that reflect what I’ve set in the Qubes Manager GUI (and verified with sys-firewall per above)

root@sys-vpn:~# iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0            state INVALID
DROP       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:68
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
REJECT     all  --  0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0            state INVALID
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
QBS-FORWARD  all  --  0.0.0.0/0            0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            owner GID match 996
DROP       all  --  0.0.0.0/0            0.0.0.0/0           

Chain QBS-FORWARD (1 references)
target     prot opt source               destination         
root@sys-vpn:~# 

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

Try some other tables like nat, raw and mangle.

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 :laughing::laughing::laughing:

I’m not setting these in iptables on the AppVM. I’m setting them in the Qubes Manager for the AppVM in dom0.

My understanding is that a VM cannot modify its firewall settings this way.

Do you know where in the doc it talks about where those settings are?

The only thing I’ve seen so far is this

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.

1 Like

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).