Andrew Mercer
on this page

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 / explicit interface=: 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: dnssec must be explicitly enabled (conf-file=/usr/share/dnsmasq/trust-anchors.conf plus dnssec), 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
  • Official site / man page: https://thekelleys.org.uk/dnsmasq/doc.html
  • Source repository: https://thekelleys.org.uk/gitweb/?p=dnsmasq.git