1

I run Ubuntu 14.04 instances on AWS EC2 in a VPC. These use the nameserver provided by our VPC. Each DNS lookup by a process is sent to the VPC nameserver. Our processes do many lookups, and some fail, resulting in blocked processes.

I wish to fix this by installing a local caching DNS resolver on every machine. This resolver will listen on 127.0.0.1:53, serving local processes. The resolver will be listed in /etc/resolv.conf, i.e. I'll have nameserver 127.0.0.1 instead of the VPC nameserver provided dynamically via DHCP.

There are lots of alternatives programs for this: bind9, nscd, dnsmasq, dnscache, etc. But there seem to be many ways to manually manage /etc/resolv.conf, e.g. marking the file as read-only, or editing /etc/network/interfaces, or editing /etc/dhcp/dhclient.conf. Which is recommended?

I have one more requirement: the local resolver will forward lookups to the VPC nameserver, our trusted authority for DNS info. However, the programs I listed do not seem to behave this way. Instead, they forward their lookups to preconfigured root nameservers.

Theoretically, I could make this work by customising dhclient-script, resolvconf, or something like that. I would add a hook which takes the DHCP-provided nameserver IP, injects it into my local DNS resolver's config, then restart the local DNS resolver daemon. But this is pretty hairy, and I want to avoid doing that. (The default scripts in Ubuntu 14.04 seem to have some inbuilt knowledge of nscd and dnscache, and possibly do what I want, but it's very unclear.)

Which is the "blessed" way to run a local caching DNS resolver on Ubuntu 14.04? In particular, how do I make the local resolver forward to the default DHCP nameserver?

1

The easiest way is probably nscd.

Install nscd, using the default config.

Update /etc/nsswitch.conf and add cache before dns to the hosts line. (Edit: this part is not applicable to glibc as used in most linux distributions but is needed on fbsd)

hosts: files cache dns

Test

tcpdump -v -n 'port 53'
getent hosts superuser.com

You should not need to mangle /etc/resolve.conf or even capture the dhcp resolver to update nscd's upstream. nsswitch will correctly route gethost* calls through the cache server since it is part of glibc.

  • Thanks for this Andrew! So my assumptions were wrong; libc does not directly consult /etc/resolv.conf. Actually, it first consults /etc/nsswitch.conf for the hosts database, and then only consults /etc/resolv.conf if this includes a source called dns. You say that cache is another source name, and presumably this tells libc to consult a DNS server at 127.0.0.1:53. This would solve my problems! However I can't find any source for this. man nsswitch.conf only mentions files and dns. Could you point me to your source for this? – jameshfisher Feb 2 '18 at 18:45
  • It's from the freebsd docs and not applicable to linux. glibc as used in most linux distributions will always use nscd if it is available and enabled before trying other sources. Long story short, if nscd is running on a glibc system, it will try to use it. – Andrew Domaszek Feb 2 '18 at 19:58
  • 1
    Holy moly, you're right. nscd is deeply integrated with glibc. Unfortunately, I had a bad experience with it. I wrote up some reasons for not using nscd. I'm looking for a standard DNS server. I'm going to try djbdns's dnscache, because it looks like Ubuntu 14.04's DHCP routines have some knowledge of how to update dnscache. – jameshfisher Feb 5 '18 at 11:24
  • I'd argue that your blog post is a bug in the software package you are using and not nscd or the glibc platform. Applications should honor nsswitch.conf and glibc's implementation of getXXbyYY() as the lookup system of record on systems based on glibc. But definitely use what works. – Andrew Domaszek Feb 5 '18 at 18:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.