Well, I tried, and now I really ran into a problem.
I’ve installed dnscrypt-proxy in my network qube (sys-net-my let say), it’s listening on 127.0.0.1:53, [::1]:53 and even 10.137.0.41:53 (IP address shown ip a) to be on the safe side.
And everything is working inside the network qube itself, but when I go into a regular AppVM, DNS resolving stops.
In order to have DNS working fine on AppVMs, I have to re-enable my provider’s DNS servers received by DHCP:
nmcli con mod "Wired connection 1" ipv4.ignore-auto-dns no
But this is exactly what I’m trying to move away from!
Could somebody please explain why my dnscrypt-proxy listening on port 53 of the internal interface is not enough for this?
What, in your opinion, will make my system less secure - installing two additional packages from the official repo?
Installing per se - unlikely (unless the installation process is compromised). Using them - could be, as it increases the attack surface of the VM.
A distrusted VM (such as sys-net) can be considered part of the distrusted infrastructure - an essential philosophy of Qubes.
Do you suppose that moving these packages to a separate VM would be more secure?
That’s the idea of security of compartmentalization. In the particular case, your sys-dns will have the necessary minimum of packages required for its work and will be isolated from the influence of other processes.
Actually, I don’t see too much difference.
Could you please advise a more suitable scheme for that?
Could somebody please explain why my dnscrypt-proxy listening on port 53 of the internal interface is not enough for this?
IIUC, you have configured it to service only the localhost:
I’ve installed dnscrypt-proxy in my network qube (sys-net-my let say), it’s listening on 127.0.0.1:53, [::1]:53 and even 10.137.0.41:53 (IP address shown ip a) to be on the safe side.
Principle answer:
Safe side of what? Your sys-net is distrusted, i.e. consider it compromised. Trying to create safety in it is self-contradictory (AKA security theater).
Ignoring the principle above:
You need proper firewall rules to direct the incoming packages to your dnscrypt-proxy service. I can’t go into that though because this thread is about a different setup, so we better not confuse others. I hope you don’t mind.
I used “to be on the safe side” in the sense of “just in case.”
Actually, I agree that the architecture of the qubes I have should be built from independent bricks providing just one feature each, but at this moment, I’m unable even to configure a simple and, let’s say, less secure solution (though much more secure than unencrypted DNS requests - these are two different kinds of “secure,” so we can’t directly compare them).
Here I see two potential improvements that could be made in Qubes OS out of the box:
Provide an alternative sys-net qube that uses dnscrypt-proxy instead of exposing all DNS requests to anyone in the middle. Or have a separate specialized qube for that, sys-dns, as you suggested.
Provide tools for easily configuring access from one VM to another, with the ability to link DNS records to them (their IP addresses are dynamic, which increases the complexity). This could be a tool that helps to construct network from the bricks.
Otherwise, Qubes users have to do this manually (and we are doing this in the current topic).
I have an ecosystem of projects that need to communicate with each other by domain names (e.g., app.local, subservice.app.local, website.local, etc.). So at this moment, I boot Qubes OS from time to time to configure one part of it, then one more and so on, hoping that eventually I will be able to fully migrate to Qubes.
So I’m following the updates of this thread while continuing my own investigations. Maybe after figuring all the issues out, we could even propose this solution to the Qubes OS team. I think the features I listed are essential.
I am planning a new guide that will come with easy to use scripts, so less manual work will be required.
Meanwhile, for your setup you need nft rules.
I will just paste a WIP version of something I have been working on some time ago, so you can probably use it as a startup scheme and fine tune it for your needs:
#!/usr/sbin/nft -f
define sys_dns_addr = "10.137.0.xx" # Where your dnscrypt-proxy service works
define qubes_internal_ipv4_addr = {
10.137.0.0/16,
10.138.0.0/16
}
flush chain ip qubes custom-forward
add chain ip qubes custom-dnat-dns
delete chain ip qubes custom-dnat-dns
table ip qubes {
chain custom-forward {
iifgroup 2 \
ip saddr $qubes_internal_ipv4_addr \
meta l4proto { tcp, udp } th dport 53 \
accept
}
chain custom-dnat-dns {
type nat hook prerouting priority dstnat - 1
policy accept
# Traffic not originating from the resolver goes to it
iifgroup 2 \
ip saddr != $sys_dns_addr \
meta l4proto { tcp, udp } th dport 53 \
dnat to $sys_dns_addr
}
}
table inet filter {
chain custom-output {
oifgroup 1 \
ip daddr $sys_dns_addr \
meta l4proto { tcp, udp } \
th dport 53 \
accept
}
}
You need to put this in /rw/config/qubes-firewall.d/name-of-your-choice.nft and make it executable. That’s in the firewall qube.