0

What is the name of the program or script that opens and reads /etc/hosts when name resolution is needed? and is it different for every linux/unix distro?

I read the man page for hosts and tried whereis looking for a binary named hosts but whereis outputs filenames like /etc/hosts.allow and /etc/hosts.deny. I was under the impression that hosts.allow and hosts.deny were config files for TCPWrappers and now Im more confused than when I started.

2

There's no specific program that parses this file.

A number of standard files (e.g. /etc/hosts) are parsed by standard library files (e.g. gethostbyname(3)). However the story may be a lot more complicated.

Hostname resolution is typically controlled by an entry in /etc/nsswitch.conf.

e.g.

% grep hosts /etc/nsswitch.conf
hosts:      files dns

This entry tells the resolver routines to use the "files" backend, and if the result isn't found there then to do a DNS lookup. Other values could be placed there (e.g. ldap or nis) which can change the way that hostnames are looked up.

These routines are typically called "Naming Services". The same concepts are also used for username lookups (passwd), group entries (group) and so on.

So when you do ping a.remote.host then the ping program will call a glibc library function, and that will load the routines defined in nsswitch.conf. The result is you won't see a specific program to do the lookup; ping does the work itself, via the libary and NS routines.

There's a program called getent that can be used to do the name searching; you specify a "database" (one of the entries in nsswitch.conf) and the value you want to search for.

So

getent hosts a.remote.host

will do a name lookup following the rules defined in nsswitch.conf. This is useful for testing purposes, and sometimes also in scripts.

--- addendum ----

This information is from Stephen's comment below, but very useful, so I am adding it to his answer.

strace getent hosts www.google.com 2>&1 | grep libnss_

will tell which library (or none) was used to resolve the name. If it says libnss_files, then /etc/hosts was used. If it says libnss_dns, then DNS was used. libnss_myhostname means that nothing worked, and a backup GNU system kicked it (and may have failed). If no library is listed, then you probably used a numerical address, like 127.0.0.1, so no resolver was necessary.

  • 1
    Is there a way to log what source was used from nsswitch.conf? Example- if /etc/nsswitch.conf listed - hosts: files dns ldap, and the resolver routine found the host's entry in files instead of dns. Is there a way to produce a log message that would look similar to a DNS request log or is there already a log produced that I am unaware of? – python_nube Dec 2 '18 at 22:18
  • 1
    If you're trying to debug a specific lookup then strace getent ... is easiest. eg % strace getent hosts www.google.com 2>&1 | grep nss_ open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 3 -- this tells me that dns was the last NSS module loaded and so was the last entry used. However % strace getent hosts localhost 2>&1 | grep nss_ open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3 only uses files so the name was resolved from /etc/hosts – Stephen Harris Dec 2 '18 at 22:26
  • The intent was to find the source code that I could modify that would allow /etc/hosts to have functionality similar to TCPWrappers (spawn and twist). So if a specific host in the hosts file is used, send a log to syslog. Something like... – python_nube Dec 2 '18 at 22:45
  • 172.217.11.78 google.com gmail : spawn (/bin/echo %a from %h accessed %d >> /var/log/connections.log) – python_nube Dec 2 '18 at 22:50
  • So the library routine that parses /etc/hosts is nss_files (eg` /usr/lib64/libnss_files.so.2` or /lib/x86_64-linux-gnu/libnss_files.so.2). The source is part of glibc. You could try modifying and compiling that... but it'll not be simple! – Stephen Harris Dec 2 '18 at 23:03
2

On GNU/Linux systems, /etc/hosts is typically read by glibc libraries.

See GNU’s documentation on the subject:

Internally, the system uses a database to keep track of the mapping between host names and host numbers. This database is usually either the file /etc/hosts or an equivalent provided by a name server. The functions and other symbols for accessing this database are declared in netdb.h. They are BSD features, defined unconditionally if you include netdb.h.

All POSIX compliant UNIX and UNIX-like systems will follow this guideline, as netdb.h is a POSIX standard. The main difference being the C library they use, as not all UNIX systems use glibc.

The GNU documentation also talks about functions such as gethostbyname and gethostbyaddr that read through the data gathered from /etc/hosts. These two functions are actually obsolete today. getaddrinfo and getnameinfo should be used instead.

  • To clarify, if I only care about name resolution (and not reverse look-ups) there are 3 c functions that could possibly read the /etc/hosts file (or name server equivalent)? – python_nube Dec 2 '18 at 21:32
  • @python_nube: See my latest edit. I learned the functions I originally specified are now obsolete. There are two main functions for getting data from /etc/hosts. Those being getaddrinfo and getnameinfo. – Peschke Dec 2 '18 at 21:48

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.