How do you see the OS DNS cache on linux?
Context
According to Cloudflare docs, the sequence of a DNS query from Chrome to the recursive resolver looks something like this:
Check browser DNS cache --miss--> Check OS DNS cache --miss--> Recursive resolver
| |
V V
hit hit
Chrome's DNS cache chrome://net-internals/#dns and firefox's DNS cache about:networking#dns lists entries in one or another, and the Windows DNS cache can be accessed with ipconfig /displaydns
.
The Windows version looks like this:
PS C:\> ipconfig /displaydns
Windows IP Configuration
chrome.cloudflare-dns.com
----------------------------------------
Record Name . . . . . : chrome.cloudflare-dns.com
Record Type . . . . . : 1
Time To Live . . . . : 54
Data Length . . . . . : 4
Section . . . . . . . : Answer
A (Host) Record . . . : 104.18.27.211
vortex.data.microsoft.com
----------------------------------------
Record Name . . . . . : vortex.data.microsoft.com
Record Type . . . . . : 5
Time To Live . . . . : 6
Data Length . . . . . : 8
Section . . . . . . . : Answer
CNAME Record . . . . : asimov.vortex.data.trafficmanager.net
...
systemd-resolve
On my Ubuntu 20.04 VPS, this looks promising, but I can't get a way to list all entries.
rj@VPS:~$ systemd-resolve motel6.com
motel6.com: 23.35.171.243 -- link: eth0
-- Information acquired via protocol DNS in 85.2ms.
-- Data is authenticated: no
rj@VPS:~$ systemd-resolve motel6.com
motel6.com: 23.35.171.243 -- link: eth0
-- Information acquired via protocol DNS in 1.4ms.
-- Data is authenticated: no
I would assume on the second instance, it's pulling from the OS DNS cache, but a DNS request to VPS' DNS server could also be 1.4ms and now cached.
Question
How do you see all entries in the DNS cache for Linux?
(Bonus points for macos as well, but I'm scoping this to Linux)
Caching is not guaranteed to be present on every Linux system. In the traditional configuration (i.e. without systemd), apps would send DNS queries directly to the servers found in /etc/resolv.conf, so there's no "system" DNS cache to be seen in the first place.
Distributions do often enable DNS caching by default, but the exact mechanism varies.
systemd-resolved as DNS cache
If you are using systemd-resolved as the DNS cache (which these days is indeed the closest thing to a "system DNS cache"), run systemctl kill -s USR1 systemd-resolved
and it will dump all cache contents to the system journal (journalctl -b -u systemd-resolved
) upon receiving the SIGUSR1.
Note that the 'systemd-resolve' tool is named resolvectl query
in recent versions, which additionally has the --cache=no
option to bypass caching done by systemd-resolved.
Testing this out, we can ask journalctl for all DNS records in the cache after the start of the script and then grep for IN records.
time=$(date +%s)
systemctl kill -s USR1 systemd-resolved
journalctl -b -u systemd-resolved -S "@$time" -o cat | grep " IN "
We get this output:
cloudflare.com IN A 104.16.133.229
cloudflare.com IN A 104.16.132.229
motel6.com IN A 23.35.171.243
vortex.data.microsoft.com IN CNAME asimov.vortex.data.trafficmanager.net
Non-systemd DNS resolvers
Before systemd, it was also not uncommon to run the Dnsmasq or Unbound resolvers on 127.0.0.1 – those have their own caches, of course. If one of them is running on your system, it probably warrants its own topic, as the ability to dump caches needs to be manually enabled upfront in both.
-
In Unbound:
unbound-control dump_cache
will dump the entire cache in a textual format that can be loaded back again, but the control channel must be first set up usingunbound-control-setup
. -
In dnsmasq: SIGUSR1 will generate a cache dump, just like with systemd-resolved, but it only works if the
log-queries
option has been enabled (or if dnsmasq is running in debug mode using-d
).
Some systems may run nscd as a general-purpose caching daemon, which works at a higher level than DNS queries – it handles abstract "name lookup" requests. There doesn't seem to be a way to dump its cache contents normally (though nscd -p
exists for inspecting "offline cache" in /var/db, if that is enabled).
By default, there is no DNS caching on Linux systems. You can confirm this on your system with the command
systemctl is-active systemd-resolved
Enable the service if you want DNS caching.