ping
, curl
, and all other apps don't really use DNS directly – they use the OS-provided "gethostbyname" function, which then calls multiple providers. One of them is "dns" (which speaks to DNS servers), another is "files" (that is /etc/hosts
); there can be additional providers which speak other protocols. They're all configured via /etc/nsswitch.conf
.
Meanwhile dig
, host
, and nslookup
are fundamentally DNS clients – they bypass the OS "gethostbyname" functions and instead directly craft & send DNS packets. (They were specifically written this way.) As a result they also skip /etc/hosts
and any other name resolution mechanisms, and there's nothing you can configure to "fix" this.
(The OS itself is not going to examine every UDP packet to check if it's DNS, and it's also not going to inject a fake DNS reply from /etc/hosts just because.)
The only way to make dig
&c. honor /etc/hosts is to set up an actual DNS server for the app to speak to, which would provide the desired static replies. For example, dnsmasq will act as DNS cache/proxy and loads static data from /etc/hosts by default. Alternatively, Unbound has extensive "local-data" configuration, although it can't read /etc/hosts directly.
Once you've configured dnsmasq or Unbound, point /etc/resolv.conf
to 127.0.0.1 (or whatever other host dnsmasq is running on).