Many developers encounter this frustration: after adding entries to /etc/hosts
or custom files like /etc/hosts.dnsmasq
, dnsmasq stubbornly refuses to recognize the changes without a manual service restart. This becomes particularly annoying during development when constantly testing domain configurations.
By design, dnsmasq reads host files only at startup. This conservative approach ensures stability but creates workflow friction. The daemon doesn't monitor file changes because:
- Original design focused on lightweight DNS caching
- Frequent file checks could impact performance
- Some deployments prefer explicit control over DNS changes
Method 1: inotify Trigger Script
This approach uses Linux's filesystem monitoring:
#!/bin/bash
while inotifywait -e modify /etc/hosts /etc/hosts.dnsmasq; do
systemctl reload dnsmasq
logger "dnsmasq reloaded due to hosts file change"
done
Save as /usr/local/bin/watch_hosts.sh
, make executable, and run as service.
Method 2: systemd Path Unit
Create /etc/systemd/system/dnsmasq-reload.path
:
[Unit]
Description=Monitor hosts files for dnsmasq
[Path]
PathModified=/etc/hosts
PathModified=/etc/hosts.dnsmasq
[Install]
WantedBy=multi-user.target
Then create matching service file /etc/systemd/system/dnsmasq-reload.service
:
[Unit]
Description=Reload dnsmasq after hosts change
[Service]
Type=oneshot
ExecStart=/bin/systemctl reload dnsmasq
Method 3: dnsmasq Exec Hook
Add to /etc/dnsmasq.conf
:
conf-file=/etc/hosts.dnsmasq
dhcp-hostsfile=/etc/hosts.dnsmasq
no-hosts # Disable default /etc/hosts reading
Then use this post-processing script:
#!/bin/bash
while true; do
inotifywait -e modify /etc/hosts.dnsmasq
kill -SIGHUP $(cat /var/run/dnsmasq/dnsmasq.pid)
done
After implementing any solution:
- Test with
dig @localhost example.com
- Check logs:
journalctl -u dnsmasq --since "5 minutes ago"
- Verify PID file location matches your system
For containerized environments:
- Bind-mount hosts file into container
- Use
--dns-opt='options:debug'
in Docker - Consider dnsmasq alternatives like CoreDNS when auto-reload is critical
Many sysadmins and developers encounter this issue - after modifying /etc/hosts
or a custom hosts file like /etc/hosts.dnsmasq
, dnsmasq stubbornly refuses to recognize the changes without manual intervention. This behavior persists even when dnsmasq is configured to read these files.
By design, dnsmasq doesn't actively monitor files for changes. It loads host entries only:
- At startup
- When explicitly told to reload (via SIGHUP)
- When the maximum cache size is reached (triggering a flush)
Here are three effective approaches to solve this:
1. Inotify-triggered Reload
Using inotifywait to monitor changes:
#!/bin/bash
while inotifywait -e modify /etc/hosts /etc/hosts.dnsmasq; do
pkill -HUP -x dnsmasq
done
2. Systemd Path Unit
Create /etc/systemd/system/dnsmasq-reload.path
:
[Unit]
Description=Monitor hosts files for changes
[Path]
PathModified=/etc/hosts
PathModified=/etc/hosts.dnsmasq
[Install]
WantedBy=multi-user.target
Then create /etc/systemd/system/dnsmasq-reload.service
:
[Unit]
Description=Reload dnsmasq
[Service]
Type=oneshot
ExecStart=/bin/kill -HUP $(cat /run/dnsmasq/dnsmasq.pid)
3. Custom Cron Script
For simpler implementations:
*/5 * * * * root [ /etc/hosts -nt /var/lib/dnsmasq/hosts.timestamp ] && pkill -HUP dnsmasq && touch /var/lib/dnsmasq/hosts.timestamp
Ensure your dnsmasq.conf contains:
no-hosts # Ignore /etc/hosts by default
addn-hosts=/etc/hosts # Explicitly include
addn-hosts=/etc/hosts.dnsmasq # Additional hosts file
After implementation, test with:
# Add test entry
echo "127.0.0.1 test.local" >> /etc/hosts
# Check if resolved
dig test.local @127.0.0.1 | grep -A1 "ANSWER SECTION"