socketry / async-dns

An asynchronous DNS resolver and server.
MIT License
96 stars 14 forks source link

Async::DNS::System.nameservers should probably ask systemd-resolved #25

Open mattiasb opened 1 year ago

mattiasb commented 1 year ago

The function Async::DNS::System.nameservers tries to get a list of nameservers by parsing /etc/resolv.conf. This will only get 127.0.0.53 (The localhost address for systemd-resolved) on at least Ubuntu and Fedora since a couple of years.

The way to go (if one wants to get the real list of DNS servers) is probably to read the DNS property out of org.freedesktop.resolve1 on the system bus.

This is an example query from the command line:

$ gdbus call --system --dest org.freedesktop.resolve1 --object-path /org/freedesktop/resolve1 --method org.freedesktop.DBus.Properties.Get org.freedesktop.resolve1.Manager DNS
(<[(1, 2, [byte 0x7f, 0x00, 0x00, 0x99]), (4, 2, [0xac, 0x1f, 0x20, 0x64]), (4, 2, [0xac, 0x1f, 0x20, 0x65]), (3, 2, [0xac, 0x1f, 0x20, 0x64]), (3, 2, [0xac, 0x1f, 0x20, 0x65])]>,)

Note though that systemd-resolved supports split DNS, thus each interface might have its own DNS server attached to it.

ioquatix commented 1 year ago

What problem are you trying to solve by using the systemd-resolved nameservers directly?

mattiasb commented 1 year ago

I'm trying to get a list of DNS servers from the system that I can use as passthrough for an otherwise-clause in a DNS server that is registered as a global nameserver in systemd-resolved. To avoid a DNS loop I then would want to filter myself out of that list.

I'm not certain that this is where I'm actually heading, I'm currently pondering just returning NXDOMAIN for domains I don't handle and NOTIMPL for records I don't handle. That is: just not do any passthrough.

So while busy thinking about my own problem I posted this issue real quick to not forget about it since I thought the current behaviour of Async::DNS::System.nameservers didn't match its documentation.