[guide] how-to setup a sys-dns qube

I used to run dnscrypt-proxy inside of sys-net to encrypt and secure dns-requests. Meanwhile I moved the service to a separate sys-dns and would like to share the setup with the community. Prerequisite is a fedora-36-minimal and fedora-36-minimal-dvm with dnscrypt-proxy installed and disabled.

[user@dom0 ~]$ qvm-clone fedora-36-minimal-dvm fedora-36-minimal-dns
[user@dom0 ~]$ qvm-create -C DispVM --template fedora-36-minimal-dns --label orange sys-dns
[user@dom0 ~]$ qvm-prefs sys-dns netvm sys-net
[user@dom0 ~]$ qvm-prefs sys-dns autostart true
[user@dom0 ~]$ qvm-prefs sys-dns provides_network true
[user@dom0 ~]$ qvm-run -u root fedora-36-minimal-dns xterm

Change /rw/config/rc.local in fedora-36-minimal-dns as follows:

[user@fedora-36-minimal-dns]~% cat /rw/config/rc.local
#!/bin/sh

# This script will be executed at every VM startup, you can place your own
# custom commands here. This includes overriding some configuration in /etc,
# starting services etc.

# Example for overriding the whole CUPS configuration:
#  rm -rf /etc/cups
#  ln -s /rw/config/cups /etc/cups
#  systemctl --no-block restart cups

# allow redirects to localhost
/usr/sbin/sysctl -w net.ipv4.conf.all.route_localnet=1
/usr/sbin/iptables -I INPUT -i vif+ -p tcp --dport 53 -d 127.0.0.1 -j ACCEPT
/usr/sbin/iptables -I INPUT -i vif+ -p udp --dport 53 -d 127.0.0.1 -j ACCEPT

# redirect dns-requests to localhost
/usr/sbin/iptables -t nat -F PR-QBS
/usr/sbin/iptables -t nat -A PR-QBS -d 10.139.1.1/32 -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1
/usr/sbin/iptables -t nat -A PR-QBS -d 10.139.1.1/32 -p tcp -m tcp --dport 53 -j DNAT --to-destination 127.0.0.1
/usr/sbin/iptables -t nat -A PR-QBS -d 10.139.1.2/32 -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1
/usr/sbin/iptables -t nat -A PR-QBS -d 10.139.1.2/32 -p tcp -m tcp --dport 53 -j DNAT --to-destination 127.0.0.1

# set /etc/resolv.conf and start dnscrypt-proxy
echo "nameserver 127.0.0.1" > /etc/resolv.conf
/usr/bin/systemctl start dnscrypt-proxy.service

If you want to configure dnscrypt-proxy the easiest way to achieve persitance is doing that in the template:

[user@dom0 ~]$ qvm-run -u root fedora-36-minimal xterm

From my point of view the most interesting settings are located in the following files:

[user@fedora-36-minimal]~% nano /etc/dnscrypt-proxy/dnscrypt-proxy.toml 
[user@fedora-36-minimal]~% nano /etc/dnscrypt-proxy/captive-portals.txt 
[user@fedora-36-minimal]~% nano /etc/dnscrypt-proxy/cloaking-rules.txt

I.e. you need to have

listen_addresses = ['127.0.0.1:53']

set in /etc/dnscrypt-proxy/dnscrypt-proxy.toml. I disabled systemd-resolved in the template, it might be possible to deinstall it. Actually I like systemd but sometimes systemd (and others like NetworkManager) do stuff in the background which I do not fully understand.

After setting everything up to your needs fedora-36-minimal-dns and fedora-36-minimal have to be shutdown. Then start sys-dns and point sys-firewall to sys-dns:

[user@dom0 ~]$ qvm-shutdown fedora-36-minimal
[user@dom0 ~]$ qvm-shutdown fedora-36-minimal-dns
[user@dom0 ~]$ qvm-start sys-dns
[user@dom0 ~]$ qvm-prefs sys-firewall netvm sys-dns
7 Likes

Thank you for sharing this info.

I am looking for a way to use DNScrypt for my non-whonix qubes as well. However, I am not using minimal templates but the default ones. Could you kindly share what I need to do?

I notice you don’t add any firewall rules to block non-local port 53 traffic from/to “client” qubes (those which will use sys-net/firewall and hence sys-dns in turn). Doesn’t that leave an open door for a qube to still try to access a DNS server directly, not going through dns-proxy?

Also, is there any particular reason to use iptables instead of nftables? Doesn’t Qubes OS use nftables?

minimal templates are lightweight versions of their standard template counterparts.

This means that this same setup will most likely work on your existing templates, you’ll just have to install the required packages and use the template names that apply to your case (instead of fedora-36-minimal you may have to use fedora-36).

You can read more about minimal templates here: Minimal templates | Qubes OS

Yes, I know what minimal templates are. I am just not using them. Thanks for the info.

What about the other questions?

The answer to your question is in the explanation I provided.

It doesn’t answer my firewall related questions. Maybe you didn’t notice them, did you?

I finally found the time to try this and I followed strictly the steps. Unfortunately, dnscrypt-proxy doesn’t seem to work as expected.

What happens in sys-dns is: systemctl status dnscrypt-proxy shows that the service starts successfully but for some reason it cannot connect to the network. The last message in the journal is (skipping the timestamps):

... sys-dns dnscrypt-proxy[444]: ... [NOTICE] Network not available yet -- waiting...

and it remains like this forever. The Internet connection is definitely fine - in sys-net I can ping and so on. FWIW, all my config files in /etc/dnscrypt-proxy are taken from another (physical) machine running Linux where they work fine. In case that might be interesting regarding the current issue, in dnscrypt-proxy.toml I have netprobe_timeout = -1.

Another thing I notice in sys-dns: Although my /rw/config/rc.local is identical to the example given in the OP, the file /etc/resolv.conf does not exist, i.e. is not auto-created as expected.

I tried restarting all the network related sys-* qubes but the result is always the same as described above.

How can I make this work please?

the file /etc/resolv.conf does not exist

More specifically:

# ls -l /etc/resolv*
lrwxrwxrwx 1 root root 39 Jan 11 15:48 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

and the target seems to be non-existing.

Wild guess - did you try to enable systemd rc-local.service instead or to create the file manually?

Wild guess - did you try to enable systemd rc-local.service instead or to create the file manually?

No. I have only followed the exacts steps listed in the OP.

Some more things I notice:

Looking at the iptables rules given in this guide, I see they relate to 10.139.1.x addresses. In Qubes VM manager, column IP address, I see no qubes with IP addresses in the 10.139.1.x range. I also see that command iptables does not exist in fedora-36-minimal.

Based on all this, my questions are:

  • What is PR-QBS? (I can’t find any documentation about it)
  • What is IP address range 10.139.1.x and why is it used in a firewall rule when there is no actual host (qube) with such IP address?
  • What to do regarding missing iptables command?
  • Should the more modern nftables be used instead?
  • What should be the actual firewall rules? (considering the everything above)
  • Does this guide need an update? If yes, please someone provide the actual steps that work.

I still hope to make this work, so I kindly ask for help again.

I’m not familiar with that guide, but I will take a look tomorrow.

In the meantime -

Qubes needs some mechanism to allow networking to work in a flexible
environment.
PR-QBS is a chain in the nat table which allows DNS traffic to
propagate up Qubes networking until it reaches sys-net, whatever that
networking looks like and however the user changes it
.
10.139.1.x are placeholders used in resolv.conf in the originating qube.
When the upstream qube sees DNS traffic to those addresses it forwards it
upstream.
This continues until it reaches sys-net, where the traffic is forwarded
to the actual DNS servers used by sys-net. Responses are returned down
the network to the originating qube.

You can interrupt this flow at any stage, by changing the rules in the
PR-QBS chain.

Unless someone else jumps in I’ll comment tomorrow.

Of course.
But, it probably is already, because most use of iptables now is not
iptables-legacy but iptables-nft (nf_tables). It is a bridge from
familiar iptables commands to the nftables api.
Check what you are using with iptables -V

Probably. Once you are clear on what is wrong, perhaps you can provide
the update.

I never presume to speak for the Qubes team. When I comment in the Forum or in the mailing lists I speak for myself.
1 Like

I’m not familiar with that guide, but I will take a look tomorrow.

Great! Thank you!

PR-QBS is a chain in the nat table which allows DNS traffic to
propagate up Qubes networking until it reaches sys-net, whatever that
networking looks like and however the user changes it
.

Where did you learn about all this? How can I educate myself?

10.139.1.x are placeholders used in resolv.conf in the originating qube.

But how do those relate to the actual IP addresses of the qubes as seen in Qubes manager? The later are quite different.

This continues until it reaches sys-net, where the traffic is forwarded
to the actual DNS servers used by sys-net. Responses are returned down
the network to the originating qube.

You can interrupt this flow at any stage, by changing the rules in the
PR-QBS chain.

Doesn’t that make sys-firewall, being a/the dedicated firewall, the proper place to do that? What is the benefit of having a whole separate sys-dns qube just for DNS compared to simply installing dnscrypt-proxy in sys-firewall (or sys-net) itself?

I may be missing something but considering minimalism and simplicity as a security principle, as well as the (always) limited system resources, is it not an overkill to have whole 3 VMs chained one after another just to connect to the Internet?

Check what you are using with iptables -V

As I mentioned, the command iptables does not exist in fedora-36-minimal. I have no idea which package to install and in which particular qube in order to have it in sys-dns. Assuming that the minimal template was created by experts with the intention to be minimal, I suppose it is a deliberate choice not to include iptables in it. IOW, I wonder if it is appropriate to even consider installing anything additional to the intentionally minimal system. So, this is kind of confusing. I will wait for your clarifications.

Once you are clear on what is wrong, perhaps you can provide the update.

Of course, I would be glad to help if I can. However, although I run dnscrypt-proxy on my (non Qubes OS) Linux systems, I don’t consider myself a network expert. Perhaps that would better be done by someone who has deeper knowledge about Qubes OS and could answer questions which may arise later. It may be best to simply have dnscrypt-proxy “out of the box” in Qubes OS as default DNS system for the non-anonymous networking. Then, one can simply customize the config files in /etc/dnscrypt-proxy. I don’t know if that has been suggested or considered but IMO it would fit quite well the overall philosophy of Qubes OS.

Looking forward to your further comments.
Thank you.

Dear @unman,

Did you have the time to look into this?
I really hope you can help.
Thanks.

After finding some problems, I made it work.
I am working on an updated guide. Coming soon.

2 Likes

Looking forward to it.