QubesOS / qubes-issues

The Qubes OS Project issue tracker
https://www.qubes-os.org/doc/issue-tracking/
536 stars 47 forks source link

DNS search domains in AppVMs #2782

Open Rudd-O opened 7 years ago

Rudd-O commented 7 years ago

In normal Qubes OS, AppVM DNS requests get forwarded through the ProxyVM and then to the NetVM, which in turn sends them.

The problem is that the resolver library in the AppVM will not obey the DNS search domains setting in the NetVM's resolv.conf (usually obtained via DHCP). So, if your business has a default domain search setting such as example.com and you ping aardvark from the NetVM, it will work correctly to resolve aardvark.example.com, but if you do that from the AppVM, bam, NXDOMAIN.

I see two solutions:

  1. A daemon like systemd-resolved or dnsmasq in the NetVM, which automatically and recursively resolves DNS requests coming from chained VMs by obeying resolv.conf's settings.
  2. A qrexec-based mechanism to set up resolv.conf in the chained VMs on boot of the VM, and to update it when the NetVM's resolv.conf changes.

What say you?

marmarek commented 7 years ago

IMO additional daemon/network service would add additional thing easing break into NetVM. While it could do cool things like cacheing etc, the risk is too high. So, this leaves the second option. We already have /etc/NetworkManager/dispatcher.d/30-qubes-external-ip, which is mostly leftover from pre-R3 days, but does very similar thing with regard to the "public" IP of the machine. We could place additional script there + qrexec service to notify appropriate domains about that.

Care must be taken to not forward this setting to some VMs - for example those behind a VPN, or Tor.

Rudd-O commented 7 years ago

but does very similar thing with regard to the "public" IP of the machine. We could place additional script there + qrexec service to notify appropriate domains about that.

YES PLEASE. That is exactly what I was thinking is the best thing to do about.

Care must be taken to not forward this setting to some VMs - for example those behind a VPN, or Tor.

The question is how we model this feature in such a way that it does not impact those VMs.

I have an idea.

  1. each NetVM/ProxyVM has access to a qubesdb key qubes-search-domains under its namespace, with write access to it.
  2. each of these VMs, by default, runs a Qubes service that inotify-watches /etc/resolv.conf (IN_CLOSE_WRITE or the rename-to-resolv.conf event).
  3. When the event triggers, the daemon reads the resolv.conf file, extracts the search parameter, and writes it to the VM's qubesdb key qubes-search-domains.
  4. dom0 has a daemon that watches all the qubes-search-domains keys. When the key qubes-search-domains for a VM is updated, the daemon gets the value from the key qubes-search-domains, sanitizes it, then iterates over the VM's immediate children, using qrexec to change the search parameter in each.

As you can see, this would dynamically propagate the search parameter to all VMs downstream, because — as the inotify events fire across VMs — it would be a recursive process:

Here's how a per-VM pref Use DNS search domains from attached NetVM could influence this algorithm. The box actually controls what gets written in step (4) above. During the iteration over the immediate children, if the child has that pref off, then the process of updating resolv.conf in the child is silently skipped. Note how, if the update of resolv.conf in the child is skipped, that means none of the grandchildren will get the update either.

Ergo: uncheck the pref box for a VPN / Tor VM, and said VM plus all its descendants would not get the updated resolv.conf either.

About the only loose end to tie, is the fact that NetVM attach events need to have the setting enforced. So, if the pref is enabled, then upon attach of A to B, key /B/qubes-search-domains should be read, and its contents written to A's resolv.conf.

None of this must necessarily be done using raw qrexec, of course. A RPC service qubes.SetSearchDomains can accept the new search domains parameter from dom0, and do the work of rewriting resolv.conf within the VM in a proper manner (atomically and respecting protected.d settings).

This does require the use of a small Qubes service that watches the resolv.conf file in the Proxy/NetVMs, though. Reason being that it isn't just NetworkManager who likes to update resolv.conf. Other daemons like OpenVPN, as well as third-party programs, also like to do that too.

There is also no hard requirement that the management side of this feature be implemented with any child-iterating code in dom0. For example, it is conceivable that a Qubes service on each VM is watching its corresponding NetVM's qubes-search-domains key, and when that key is updated, the daemon updates resolv.conf. The pref I spoke of earlier then becomes a toggle for the Qubes service — if the pref is off for VM P, then the Qubes service does not start, and resolv.conf updates in P's NetVM have no effect on P. Of course, the tradeoff in this case is running one Qubes service on each VM (two in the case of NetVMs/ProxyVMs) and not running any code in dom0, versus running zero Qubes services on each VM (one in the case of NetVMs/ProxyVMs) and running the child update code in dom0.

the2nd commented 7 years ago

Hi,

i've written some quick and dirty shell scripts for this.

https://github.com/the2nd/qubes-dns-search

Just in case someone needs a fix for this. The only problem is that the search domain is not added to a VMs resolv.conf on reboot. You have to re-connect your network for this.

Regards the2nd