How to Configure /etc/hosts, /etc/resolv.conf and DNS Resolution on RHEL 7

DNS resolution is one of the first things you troubleshoot when a server cannot reach other hosts by name. On Red Hat Enterprise Linux 7, name resolution is controlled by a layered system involving /etc/hosts, /etc/resolv.conf, /etc/nsswitch.conf, and NetworkManager. Understanding how these files interact — and how NetworkManager can silently overwrite your manual changes — is essential for any system administrator. This tutorial explains the complete DNS resolution stack on RHEL 7, how to configure it reliably, and how to test that it is working correctly.

Prerequisites

  • A RHEL 7 system with root or sudo access.
  • Basic understanding of IP addressing and DNS concepts.
  • The bind-utils package for testing tools: yum install -y bind-utils.
  • NetworkManager running (default on RHEL 7): systemctl status NetworkManager.

Step 1: Understanding /etc/hosts

The /etc/hosts file is a simple static lookup table that maps hostnames to IP addresses. It is consulted before DNS by default on RHEL 7, making it the fastest and most reliable way to resolve a small number of known hosts — particularly useful in isolated environments, for loopback addresses, or for overriding DNS during testing.

# View the default /etc/hosts file
cat /etc/hosts
# 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
# ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

The format of each line is:

IP_ADDRESS    canonical-hostname    [alias1] [alias2] ...

To add custom host entries, append them to the file. There is no service to restart — changes take effect immediately.

# Add custom host entries
echo "192.168.1.50    dbserver01 dbserver01.internal.example.com" >> /etc/hosts
echo "192.168.1.51    webserver01 webserver01.internal.example.com" >> /etc/hosts
echo "10.0.0.5        build-ci" >> /etc/hosts

# Test immediately
ping -c2 dbserver01

Step 2: Configuring /etc/resolv.conf

The /etc/resolv.conf file tells the system which DNS servers to query and how to search for unqualified hostnames. It supports three key directives:

  • nameserver — The IP address of a DNS server. Up to three nameserver lines are supported; they are tried in order.
  • search — A list of domain suffixes appended when resolving unqualified names (e.g., typing ping webserver01 will also try webserver01.example.com).
  • domain — Sets a single default domain for unqualified names (similar to search but only one value; search takes precedence if both are present).
# Example /etc/resolv.conf
cat > /etc/resolv.conf << 'EOF'
# Primary and secondary internal DNS servers
nameserver 192.168.1.1
nameserver 192.168.1.2
# Public fallback
nameserver 8.8.8.8

# Search domains (up to 6, space-separated)
search example.com internal.example.com dev.example.com

# Optional: number of attempts per nameserver before trying the next
options attempts:2

# Optional: timeout per query in seconds
options timeout:3
EOF

Step 3: Understanding NetworkManager and resolv.conf

A common source of frustration on RHEL 7 is that NetworkManager automatically regenerates /etc/resolv.conf when network connections change. Any manual edits you make will be silently overwritten at the next network event (e.g., reconnect, DHCP renewal, or reboot).

There are two approaches to making persistent DNS changes under NetworkManager:

Option A: Configure DNS via nmcli (Recommended)

# List all connections to find the connection name
nmcli connection show

# Set DNS servers for a specific connection (replace "ens33" with your connection name)
nmcli connection modify ens33 ipv4.dns "192.168.1.1 192.168.1.2"

# Set search domains
nmcli connection modify ens33 ipv4.dns-search "example.com internal.example.com"

# Tell NetworkManager NOT to use DHCP-supplied DNS for this connection
nmcli connection modify ens33 ipv4.ignore-auto-dns yes

# Apply changes
nmcli connection down ens33 && nmcli connection up ens33

# Verify the generated resolv.conf
cat /etc/resolv.conf

Option B: Tell NetworkManager Not to Manage resolv.conf

# Create or edit /etc/NetworkManager/conf.d/no-dns.conf
cat > /etc/NetworkManager/conf.d/no-dns.conf << 'EOF'
[main]
dns=none
EOF

# Restart NetworkManager
systemctl restart NetworkManager

# Now you can safely edit /etc/resolv.conf manually without it being overwritten

Step 4: Controlling Resolution Order with /etc/nsswitch.conf

The Name Service Switch configuration file /etc/nsswitch.conf determines the order in which different name resolution sources are consulted. The critical line for hostname resolution is the hosts entry.

# View the hosts line in nsswitch.conf
grep "^hosts" /etc/nsswitch.conf
# hosts:      files dns myhostname

The default value files dns myhostname means:

  1. files — Check /etc/hosts first.
  2. dns — Query DNS servers listed in /etc/resolv.conf.
  3. myhostname — Fall back to the system hostname.

If you want DNS to be checked before /etc/hosts (unusual, but sometimes required), change the order:

# Edit /etc/nsswitch.conf to check DNS before files
sed -i 's/^hosts:.*/hosts:      dns files myhostname/' /etc/nsswitch.conf

Step 5: Testing DNS Resolution with nslookup, dig, and host

After making changes, always verify resolution works correctly using the standard testing utilities.

Using nslookup

# Forward lookup (hostname to IP)
nslookup google.com

# Reverse lookup (IP to hostname)
nslookup 8.8.8.8

# Query a specific DNS server directly
nslookup google.com 192.168.1.1

Using dig

# Basic forward lookup
dig google.com

# Short output (just the answer)
dig +short google.com

# Reverse lookup
dig -x 8.8.8.8

# Query a specific record type
dig google.com MX
dig google.com NS

# Query a specific DNS server and show full trace
dig @192.168.1.1 internal.example.com +trace

# Check which DNS server was actually used
dig google.com | grep "SERVER:"

Using host

# Simple forward lookup
host google.com

# Reverse lookup
host 8.8.8.8

# Look up all record types
host -a google.com

Step 6: Adding Custom DNS Entries Persistently

For internal hostnames that should not be in public DNS, you have three main options on RHEL 7: /etc/hosts for a small number of static entries, a local DNS server (like BIND or dnsmasq) for larger environments, or split-horizon DNS.

# For a handful of static entries, /etc/hosts is simplest
cat >> /etc/hosts < /etc/dnsmasq.d/internal.conf << 'EOF'
address=/gitlab.internal.example.com/192.168.10.100
address=/nexus.internal.example.com/192.168.10.101
EOF

# Enable and start dnsmasq
systemctl enable dnsmasq
systemctl start dnsmasq

# Configure resolv.conf to use localhost first
nmcli connection modify ens33 ipv4.dns "127.0.0.1 192.168.1.1"
nmcli connection up ens33

Conclusion

DNS resolution on RHEL 7 is a multi-layer system: /etc/hosts for static overrides, /etc/resolv.conf for DNS server configuration, and /etc/nsswitch.conf to control which source is consulted first. The critical operational point is that NetworkManager owns /etc/resolv.conf by default — always configure DNS through nmcli or suppress NetworkManager’s management of that file to ensure your settings survive a reboot. Use dig, nslookup and host routinely to verify resolution from multiple angles, and consider a local dnsmasq instance when you need to resolve more than a few internal names without deploying a full BIND server.