Is your /etc/hosts file healthy?
The /etc/hosts file is one of the few files you will always find on a Linux system. It stores the ‘hosts’ database, and can be used to resolve between IP addresses and hostnames. Although the file is very simple structured, it is still common to see minor issues with name resolving on systems. Guess what, your /etc/hosts file might be causing more trouble than you think. A regular check up won’t hurt.
Order matters in name resolving
Linux systems have a library called Name Service Switch. It defines the databases for resolving between identities and names. Not just between hostnames and IP addresses, but also your user accounts. Knowing a little bit more about this library is good to know, especially when working both IPv4 and IPv6 addresses and the combination of local files and DNS.
The first step is knowing how the system determines where to look when it wants to do some name resolving. We use the /etc/nsswitch.conf file for this.
This file shows for each database type what order it will use and what specific query mechanism. For our hosts database we see it queries first the applicable files, then uses DNS. This is good to know, as we can leverage to overrule hardening with the /etc/hosts file.
Please note that some tools will not adhere to this order. Tools like host and dig are meant to query data via DNS. Querying the ‘hardening’ hostname, which is listed in /etc/hosts, will still result in an error:
Host hardening not found: 3(NXDOMAIN)
If you want to validate how resolving is performed by a tool, use the strace command:
strace host test
Give it a go and see if you can find /etc/hosts in your output (we can’t).
The hosts database
The hosts database is formed by the /etc/hosts file. We can query it in two ways:
- View /etc/hosts
- Use getent
The first option is easy, as we can use the cat command for that.
cat /etc/hosts
The second command is less familiar, yet always available as well.
getent hosts
Both will query (or show) what is in the hosts database. While this might have the same goal, the output might surprisingly be different.
In this screenshot we see the last two lines missing from the getent command output. This is because they are not normal hosts. They can be compared to broadcast addresses in IPv4, with ip6-allnodes for all systems (including routers), the ip6-allrouters for just the routers in the network segment.
What can be wrong with /etc/hosts?
Although the /etc/hosts file is a simple structured file, there are a few things that should be checked. So next time you are on a system, become an IT auditor and check the following parts:
Your hosts file is not a DNS replacement
If you have added more than 10 systems to your /etc/hosts file you may consider moving that to a separate DNS zone. Even if it is for internal usage, name translation is perfectly performed by DNS. Add your internal zone to your name servers for optimal caching and easy of management. Even if you use configuration management tools like Ansible or Puppet, your host file should not be storing many entries.
Using your local hosts files may also have the risk of introducing unexpected behavior when some system name is reused for example. If you truly only use some entries for temporarily testing, then the hosts file can be a great option. From experience we can say that temporary often results in permanent (on purpose, but more often by accident). So try to be disciplined and avoid changing the hosts file and keep your systems tidy.
No FQDN provided
Still many Linux installations are not properly configured when it comes to the domain name. Even if you provided it during the installation process, it may not have been propagated to the /etc/hosts file. The so-called Fully Qualify Domain Name (FQDN) defines the hostname + domain.
You can easily check if your Linux system is properly configured by using the hostname command.
hostname -d
No output of this command means there is not hostname configured. In that case change your hosts file into this format
[IP address] [FQDN] [hostname]
One typical error is that the last two are reversed. The longest match, which is the FQDN, should be at the front to get it working.
Localhost mapping
The localhost entry defines the local system. It should always map against 127.0.0.1 or ::1 (IPv6) to prevent issues. To check this, use the getent utility.
getent hosts localhost
The other way around should be return at least localhost, with optional some aliases.
getent hosts 127.0.0.1
Conclusion
The /etc/hosts file is used on Linux to support local name resolving. The file itself should remain as small as possible, so the remaining entries can do their job. One of them is resolving the localhost entry back to 127.0.0.1 (IPv4) or ::1 (IPv6). The other purpose is to define the domain name of the system, to properly form the fully qualified domain name (FQDN).
Want to test these things automatically for all systems? Then check out Lynis, as it has built-in tests for that (and much more).