67

I am confused about DNS caching. I am writing a small forward proxy server and want to use OS DNS cache on a Linux system.

If I understand correctly, then there is DNS caching at the browser level. Then there is DNS caching at OS level (Windows has it. I am not sure if Linux distros have it by default).

So, how does a browser/proxy_server use OS DNS caching? I am trying to find if I can rely on Linux for DNS caching instead of doing it on my own inside my proxy.

Thanks

jeteon
  • 2,731
  • 22
  • 39
agent.smith
  • 8,106
  • 8
  • 32
  • 45

4 Answers4

94

On Linux (and probably most Unix), there is no OS-level DNS caching unless nscd is installed and running. Even then, the DNS caching feature of nscd is disabled by default at least in Debian because it's broken. The practical upshot is that your linux system very very probably does not do any OS-level DNS caching.

You could implement your own cache in your application (like they did for Squid, according to diegows's comment), but I would recommend against it. It's a lot of work, it's easy to get it wrong (nscd got it wrong!!!), it likely won't be as easily tunable as a dedicated DNS cache, and it duplicates functionality that already exists outside your application.

If an end user using your software needs to have DNS caching because the DNS query load is large enough to be a problem or the RTT to the external DNS server is long enough to be a problem, they can install a caching DNS server such as Unbound on the same machine as your application, configured to cache responses and forward misses to the regular DNS resolvers.

Community
  • 1
  • 1
Celada
  • 20,176
  • 3
  • 55
  • 70
  • Hey, thanks. One more question. Do you know how it works in browsers on windows. I have read that chrome relies on OS dns cache. So, does that mean applications can access OS dns cache? In general, what is the flow for dns resolution (In context of caching.) Browser checks its own cache if it maintains one. Then does it ask OS or it reads OS dns cache? If no entry is found then it goes out for resolution. – agent.smith Jun 13 '12 at 19:19
  • 6
    When an OS-level cache is available, it gets used automatically and transparently by all applications unless the application bypasses the standard name querying APIs (`getaddrinfo()` et al.) and implements its own DNS queries directly. That applies to MacOS X unconditionally, and it applies to Linux if by some chance nscd is running and active (can't speak for MS Windows). If an application implements its own cache, then it applies in addition to any OS-level cache that may or may not be present (again, unless the application bypasses the OS and queries directly). – Celada Jun 13 '12 at 19:30
  • 3
    @Celada can you provide a source for `On Linux (and probably most Unix), there is no OS-level DNS caching unless nscd is installed and running.`? I googled around with no luck... – cYrus Dec 03 '12 at 15:31
  • 7
    You can look around in the `resolv` subdirectory of the glibc source code, it's all there. That's not a specific answer, I realize, but it comes down to the fact that there's no code in there that implements a cache and in any case you can see if you trace it that it makes no use of any file or shared memory segment or other kind of location where this cache could potentially be stored. – Celada Dec 03 '12 at 16:29
  • @Agent Smith: You can find good comments about windows DNS caching and Browser caching here: https://www.itdojo.com/resolver-cache-linux-vs-windows/ – kovacsbv Jul 18 '16 at 16:23
  • 5
    **Note**: nowadays on `systemd` there's [a service to cache DNS](https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html), it could be enabled with `systemctl enable systemd-resolved`. – Hi-Angel Sep 23 '16 at 11:06
  • I've experienced that the behaviour is to try 1 DNS IP after another. Some applications fail to do this properly. And even on Chrome URL resolutions become slow. This is another reason to have a local DNS server to handle upstream resolutions in parallel. – CMCDragonkai Apr 18 '18 at 06:01
  • nscd is the most common and it's DNS cacheing is broken. Unbound is easy to install and works extremely well. Services like dnsmasq can be overrun. Unbound works well. – TekOps Oct 21 '18 at 02:17
  • Two words: Linux sucks. nscd is broken for almost a decade. Nobody fixes it. While windows and macOS are doing more and more hiding all the complicated DNS stuff. – Lothar Aug 03 '19 at 15:22
23

Here are two other software packages which can be used for DNS caching on Linux:

  • dnsmasq
  • bind

After configuring the software for DNS forwarding and caching, you then set the system's DNS resolver to 127.0.0.1 in /etc/resolv.conf.

If your system is using NetworkManager you can either try using the dns=dnsmasq option in /etc/NetworkManager/NetworkManager.conf or you can change your connection settings to Automatic (Address Only) and then use a script in the /etc/NetworkManager/dispatcher.d directory to get the DHCP nameserver, set it as the DNS forwarding server in your DNS cache software and then trigger a configuration reload.

Zan Lynx
  • 49,393
  • 7
  • 74
  • 125
  • 4
    Nowadays on `systemd` [is one more](https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html), it could be enabled with `systemctl enable systemd-resolved`. – Hi-Angel Sep 23 '16 at 11:11
13

You have here available an example of DNS Caching in Debian using dnsmasq.

Configuration summary:

/etc/default/dnsmasq

# Ensure you add this line
DNSMASQ_OPTS="-r /etc/resolv.dnsmasq"

/etc/resolv.dnsmasq

# Your preferred servers
nameserver 1.1.1.1
nameserver 8.8.8.8
nameserver 2001:4860:4860::8888

/etc/resolv.conf

nameserver 127.0.0.1

Then just restart dnsmasq.

Benchmark test using DNS 1.1.1.1:

for i in {1..100}; do time dig slashdot.org @1.1.1.1; done 2>&1 | grep ^real | sed -e s/.*m// | awk '{sum += $1} END {print sum / NR}'

Benchmark test using you local cached DNS:

for i in {1..100}; do time dig slashdot.org; done 2>&1 | grep ^real | sed -e s/.*m// | awk '{sum += $1} END {print sum / NR}'
Community
  • 1
  • 1
Tk421
  • 5,187
  • 5
  • 33
  • 40
2

Firefox contains a dns cache. To disable the DNS cache:

  1. Open your browser
  2. Type in about:config in the address bar
  3. Right click on the list of Properties and select New > Integer in the Context menu
  4. Enter 'network.dnsCacheExpiration' as the preference name and 0 as the integer value

When disabled, Firefox will use the DNS cache provided by the OS.

Leigh
  • 28,424
  • 10
  • 49
  • 96