[Dnsmasq-discuss] Extend server to accept hostnames for upstream resolver

Dominik Derigs dl6er at dl6er.de
Sat Oct 15 10:28:49 UTC 2022


Hey Simon,

when setting up a new docker server this morning I desperately
missed the specify-server-by-host feature in dnsmasq. I revived
my initial patch and added what was requested: I removed the
compile-time option and changed the code to always use all
suitable addresses (IPv6 is not suitable when source is IPv4 and
vice versa).

Along the way, I found a small bug: IPv6 source addresses are
incorrectly interpreted as interface names for IPv4 server
addresses (and vice versa). This is fixed in my patch:

BEFORE:
--server=1.2.3.4 at fe80::
dnsmasq: using nameserver 1.2.3.4#53(via fe80::)

NOW:
--server=1.2.3.4 at fe80::
dnsmasq: bad command line options: cannot use IPv4 server address
with IPv6 source address



Examples:

--server=localhost
dnsmasq: using nameserver 127.0.0.1#53


--server=a.test.dl6er.de at fe80::
dnsmasq: warning: no upstream servers configured


--server=both.test.dl6er.de at fe80::
dnsmasq: using nameserver dead:beef::#53


--server=both.test.dl6er.de at 10.0.0.1
dnsmasq: using nameserver 1.2.3.4#53


--server=both.test.dl6er.de
dnsmasq: using nameserver dead:beef::#53
dnsmasq: using nameserver 1.2.3.4#53


--server=amazon.com
dnsmasq: using nameserver 54.239.28.85#53
dnsmasq: using nameserver 52.94.236.248#53
dnsmasq: using nameserver 205.251.242.103#53


--server=does-not-exist-4615465468435.com
dnsmasq: bad command line options: Name or service not known
  (dnsmasq refuses to start)


What do you think?

I'm undecided if dnsmasq should fail hard on the second example
(no IPv6 address for a hostname but IPv6 source address given)
but this may be a real edge-case where we can expect users to
understand what they're doing and read the logs. Catching this
would require extra logic (valid hostnames are returned but none
is used -> error out).

Best,
Dominik

On Thu, 2022-04-07 at 12:24 +0100, Simon Kelley wrote:
> This seems like a sensible idea, but it does need a clear
> warning in the 
> documentation that it will only work if the dnsmasq instance
> being 
> configured is not the one providing DNS to the local system.
> 
> Two comments about the patch.
> 
> 1) Geert's point is a good one: This patch uses only libc: it
> doesn't 
> add any build dependencies and it's small. There's no reason to
> make it 
> a compile-time option.
> 
> 2) Not handling multiple addresses from getaddrinfo() feels
> like a 
> mistake. What should happen in that case is obvious and the
> obvious 
> behaviour is useful. If it's not done now, we'll end up doing
> it later 
> when someone falls foul of this short-cut. the implementation
> is more 
> complex, but I think returning the struct addrinfo * linked
> list from 
> getaddrinfo instead of a single address should work: the caller
> of 
> parse_server becomes responsible for freeing the struct
> addrinfos
> 
> 3) One error that needs to be handled is if a source address is
> specified, and the address family of the source address doesn't
> match 
> the address family of an address returned  from getaddrinfo. My
> initial 
> thought was to make this a fatal error, but that has the
> problem that
> 
> server=dns.example.com at 192.168.7.1
> 
> will work fine until an AAAA record is added for
> dns.example.com, when 
> dnsmasq would no longer start. Better I thing to only use DNS
> records 
> that match the source address type if it's specified.
> 
> 
> Cheers,
> 
> Simon.
> 
> 
> 
> 
> 
> On 02/04/2022 20:40, Dominik Derigs wrote:
> > Dear Simon,
> > 
> > In docker swarm and compose configurations, other containers
> > are
> > only reachable via hostnames. It is not always possible to
> > assign
> > IP addresses beforehand. Hence, the upstream server IP is not
> > known at dnsmasq start when the upstream is part of the
> > deployed
> > configuration, e.g., a local cloudflared or unbound
> > container.
> > 
> > So far, getting dnsmasq to run in such a case requires hacks
> > that
> > somehow try to determine the IP address before starting
> > dnsmasq.
> > An example for such a hack (not invented by me):
> > https://github.com/tschaffter/docker-dnsmasq/blob/54b5d5d551746b6f1708fbf4a705e2de66c2eaee/docker-entrypoint.sh#L14-L23
> > 
> > This patch implements name resolution functionality for
> > server=... by querying the system resolver for a hostname. It
> > is
> > only used when a user supplied something that is not a valid
> > IP
> > address (dnsmasq currently fails hard in this case so this
> > isn't
> > a breaking change) and can be omitted by a compile time flag
> > (I
> > think it's worthwhile to have it).
> > 
> > I know my proposal does sound somewhat strange (resolving a
> > DNS
> > server name) but this is something that is somewhat
> > frequently
> > needed and currently only possible through external hacks.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Extend-server-to-accept-hostnames-for-upstream-resol.patch
Type: text/x-patch
Size: 19407 bytes
Desc: not available
URL: <http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20221015/45a7bb00/attachment-0001.bin>


More information about the Dnsmasq-discuss mailing list