When running dnsmasq on a host that serves as both DNS and DHCP server (like 'rtfm.lan' in this case), we encounter an interesting behavior:
- DHCP-assigned hostnames (e.g., 'client1.lan') resolve correctly to their dynamic IPs
- But the local server's own hostname ('rtfm.lan') resolves to 127.0.0.1 from
/etc/hosts
Dnsmasq has two parallel mechanisms for name resolution:
1. The hosts file (/etc/hosts by default) - typically contains 127.0.0.1 mapping
2. DHCP lease database - contains actual assigned IP addresses
By default, dnsmasq gives priority to the hosts file, which causes this behavior even when we have a proper DHCP reservation.
The simplest solution is what you already tried:
no-hosts
address=/rtfm.lan/192.168.1.2
But as you noted, this creates maintenance overhead when IP addresses change.
We can make dnsmasq treat the local hostname just like DHCP-assigned hostnames:
# First, prevent reading /etc/hosts
no-hosts
# Then add a custom hosts file
addn-hosts=/etc/dnsmasq.hosts
# Make sure local domain is properly handled
local=/lan/
domain=lan
Now create /etc/dnsmasq.hosts
with:
192.168.1.2 rtfm.lan
Since you already have DHCP reservations, we can leverage that:
dhcp-host=00:23:54:5d:27:fa,rtfm.lan,192.168.1.2
dhcp-host=00:23:54:5d:27:fb,rtfm.lan,192.168.1.2
Then add this to dnsmasq.conf:
no-hosts
read-ethers
And create /etc/ethers
with:
00:23:54:5d:27:fa rtfm.lan
00:23:54:5d:27:fb rtfm.lan
After making changes, verify with:
# Reload dnsmasq
sudo systemctl restart dnsmasq
# Test resolution
dig rtfm.lan @localhost
nslookup rtfm.lan 127.0.0.1
The output should show the actual IP (192.168.1.2) rather than 127.0.0.1.
When running dnsmasq on a host that's both a DNS server and a DHCP server (like 'rtfm.lan' in our case), you'll notice that the local hostname always resolves to 127.0.0.1 when queried from other machines on the network. This happens because:
- By default, dnsmasq reads /etc/hosts
- Local hostnames in /etc/hosts typically point to 127.0.0.1
- DHCP-assigned hostnames work fine because they're stored separately
When your host serves as both a DNS resolver and a network resource (like a file server or web server), other machines need to reach it via its LAN IP (192.168.1.2 in our example), not loopback. The current behavior breaks:
# From another machine:
ping rtfm.lan # Returns 127.0.0.1 (wrong)
ssh rtfm.lan # Fails to connect
The obvious but inflexible solution would be:
no-hosts
address=/rtfm.lan/192.168.1.2
This becomes problematic when your IP changes. Here's the proper approach:
Since you're already using DHCP reservations (as shown in your config), leverage this information:
# In dnsmasq.conf
no-hosts
read-ethers
dhcp-host=00:23:54:5d:27:fa,rtfm.lan,192.168.1.2
Key configuration notes:
no-hosts
: Prevents loading /etc/hostsread-ethers
: Allows hostname-IP mapping from DHCP leases- Ensure your DHCP reservation includes both MAC and hostname
For environments where you need more control over host entries:
no-hosts
addn-hosts=/etc/dnsmasq-hosts
expand-hosts
domain=lan
Then create /etc/dnsmasq-hosts with:
192.168.1.2 rtfm rtfm.lan
After making changes:
sudo systemctl restart dnsmasq
dig rtfm.lan @192.168.1.2
Expected output should show the LAN IP (192.168.1.2) not 127.0.0.1.
For dual-homed hosts or complex networks, consider these additions:
# Force specific interface responses
interface=eth0
bind-interfaces
# Explicit local domain declaration
local=/lan/