1. What dnsmasq Is¶
dnsmasq is a lightweight, combined DNS forwarder/cache and DHCP server, designed for small networks — routers, homelabs, embedded devices — where running a full BIND or Unbound instance plus a separate DHCP server (like ISC DHCP or Kea) would be overkill. Its defining trait versus Unbound or BIND-as-resolver is that DNS and DHCP are integrated in one process, which lets it do something neither pure resolver can: automatically create DNS records for DHCP leases, so a device that just got an address via DHCP is immediately resolvable by hostname on the LAN, with zero manual zone editing.
It is not a validating, security-hardened resolver in the Unbound sense, and not an authoritative server for real internet-facing zones in the BIND sense — it's a pragmatic, low-overhead tool for exactly the "small network, want names to just work" use case, which is why it ships as the default resolver/DHCP stack on most consumer routers and many Linux distributions' NetworkManager integration.
2. Installation¶
# Debian/Ubuntu
sudo apt install -y dnsmasq
# RHEL/CentOS/Fedora
sudo dnf install -y dnsmasq
On desktop Linux, dnsmasq is frequently already running in the background as a helper for NetworkManager (bound only to a loopback/internal address) — check systemctl status NetworkManager and ss -tulpn | grep :53 before assuming port 53 is free, since a second manually-configured dnsmasq instance will conflict with it.
3. Configuration Basics¶
Main config file: /etc/dnsmasq.conf, with distro convention of also reading everything under /etc/dnsmasq.d/*.conf.
# /etc/dnsmasq.conf
# Interface(s) to listen on
interface=eth0
bind-interfaces
# Don't read /etc/resolv.conf or /etc/hosts for upstream info automatically
no-resolv
no-hosts
# Upstream resolvers
server=1.1.1.1
server=1.0.0.1
# DHCP range: start, end, lease time
dhcp-range=192.168.1.50,192.168.1.150,12h
# Local domain suffix
domain=lan
local=/lan/
# Log every query (troubleshooting only — see caveats)
log-queries
log-facility=/var/log/dnsmasq.log
Key directives:
| Directive | Purpose |
|---|---|
interface / except-interface |
Which interfaces to bind and serve on |
bind-interfaces |
Bind only the named interfaces rather than all addresses, wildcard-listening on 0.0.0.0 |
no-resolv |
Don't use /etc/resolv.conf to discover upstream servers — use only explicit server= lines |
server= |
Upstream resolver(s) to forward to; can be scoped per-domain (server=/internal.example.com/10.0.0.1) for split resolution |
local=/domain/ |
Mark a domain as local-only — never forwarded upstream, answered from local data or NXDOMAIN |
dhcp-range |
Enables DHCP serving for the given pool |
dhcp-host |
Static DHCP reservation, can also assign a fixed hostname |
address=/name/ip |
Wildcard local override, similar to Unbound's local-data/local-zone redirect |
cache-size |
Number of DNS answers cached in memory (default 150 — often worth raising) |
4. DHCP + DNS Integration¶
The signature dnsmasq feature: DHCP clients are automatically added to DNS.
dhcp-range=192.168.1.50,192.168.1.150,12h
domain=lan
Any client that DHCP-leases an address and sends its hostname in the DHCP request becomes resolvable as <hostname>.lan immediately, with no separate DNS record ever written by hand. Static reservations combine both roles in one line:
dhcp-host=aa:bb:cc:dd:ee:ff,nas,192.168.1.10,infinite
This both reserves 192.168.1.10 for that MAC address via DHCP and makes nas.lan resolve to it — the same operational win BIND's dynamic-update (allow-update) is used for at larger scale, but here it's automatic and doesn't need a separate protocol exchange.
5. Split DNS / Per-Domain Forwarding¶
server=/internal.example.com/10.0.0.5
server=/10.in-addr.arpa/10.0.0.5
server=8.8.8.8
Queries for internal.example.com (and the matching reverse zone) go to the internal resolver; everything else falls through to the general upstream. This is dnsmasq's version of BIND's forward-zone scoped to a specific name, or Unbound's non-. forward-zone — the same split-horizon-adjacent idea covered in the dedicated split-horizon guide.
6. Caching Behavior¶
dnsmasq caches answers in memory up to cache-size entries (default 150, small for anything beyond a handful of devices — raising it to 1000+ is common and cheap). Unlike Unbound, dnsmasq does not perform full recursive resolution itself by default; it's fundamentally a forwarder with a cache, always relying on upstream servers (server= lines or /etc/resolv.conf) to do the actual root-to-authoritative work.
7. Security Considerations¶
- CVE history: dnsmasq has had several notable memory-corruption CVEs over the years (the "DNSpooq" cluster in 2021 being the most cited) — because it's so widely embedded in consumer routers with infrequent firmware updates, patch lag here is a persistent real-world exposure. Keep it current, and don't expose it to the internet.
bind-interfaces/ explicitinterface=: without scoping which interfaces dnsmasq listens on, a box with a WAN-facing NIC can end up answering (and forwarding) queries from the internet — the same open-resolver risk covered for BIND and Unbound.- No DNSSEC validation by default:
dnssecmust be explicitly enabled (conf-file=/usr/share/dnsmasq/trust-anchors.confplusdnssec), and dnsmasq's validation implementation is considered less battle-tested than Unbound's — for anything where DNSSEC validation is a hard requirement, put dnsmasq in front of a validating Unbound instance rather than relying on dnsmasq's own validation. - No built-in ACL granularity beyond interface binding — dnsmasq doesn't have BIND-style named ACLs or Unbound-style per-netblock allow/deny lists; access control is mostly "which interface is this socket on."
8. When to Reach for dnsmasq vs. Alternatives¶
- Small LAN/homelab wanting automatic DHCP-to-DNS naming with minimal config → dnsmasq is the natural fit.
- Need DNSSEC validation as a hard requirement, or a security-hardened resolver posture → Unbound.
- Need to actually host authoritative zones for a real domain → BIND (or a cloud-managed DNS provider).
- Ad/tracker blocking with a web UI on top of exactly this kind of setup → Pi-hole, which itself uses dnsmasq (or, in newer versions, its own forked
FTL/dnsmasq-derived engine) as its resolution backend — see the dedicated Pi-hole guide.
9. Useful Commands¶
# Test config syntax without restarting
dnsmasq --test
# Check active leases
cat /var/lib/misc/dnsmasq.leases
# Restart after config changes
sudo systemctl restart dnsmasq
# Clear the in-memory cache (SIGHUP also re-reads /etc/hosts and dhcp-hostsfile)
sudo systemctl reload dnsmasq
10. Reference Links¶
- Official site / man page: https://thekelleys.org.uk/dnsmasq/doc.html
- Source repository: https://thekelleys.org.uk/gitweb/?p=dnsmasq.git