dnsmasq is a lightweight DNS forwarder and DHCP server ideal for local networks, development environments, and small deployments. It provides DNS caching, custom DNS entries, DHCP, and TFTP in a single small package. This guide covers common dnsmasq configurations for VPS and local network use.
Installation
sudo apt install dnsmasq # Ubuntu/Debian
sudo dnf install dnsmasq # Rocky Linux
DNS Caching Configuration
# /etc/dnsmasq.conf
# Listen on localhost only
listen-address=127.0.0.1
bind-interfaces
# Upstream DNS servers
server=1.1.1.1
server=8.8.8.8
# Cache size (default 150)
cache-size=10000
# Never forward plain names (without dots)
domain-needed
bogus-priv
# DNSSEC validation
dnssec
trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
# Log queries (for debugging)
# log-queries
# log-facility=/var/log/dnsmasq.log
Custom DNS Entries
# /etc/dnsmasq.conf
# Local DNS entries (like /etc/hosts but for the whole network)
address=/myapp.local/10.0.0.50
address=/db.local/10.0.0.51
address=/api.internal/10.0.0.52
# Wildcard DNS (all subdomains resolve to same IP)
address=/.dev.local/10.0.0.50
# *.dev.local → 10.0.0.50
# Block domains (return NXDOMAIN)
address=/ads.example.com/
address=/tracking.example.com/
# CNAME records
cname=www.myapp.local,myapp.local
# Or use /etc/hosts (dnsmasq reads it by default)
# 10.0.0.50 myapp.local www.myapp.local
# 10.0.0.51 db.local postgres.local
DHCP Server
# /etc/dnsmasq.conf
# Enable DHCP for local network
dhcp-range=10.0.0.100,10.0.0.200,24h
dhcp-option=option:router,10.0.0.1
dhcp-option=option:dns-server,10.0.0.1
dhcp-option=option:domain-name,local
# Static IP assignments
dhcp-host=aa:bb:cc:dd:ee:ff,10.0.0.50,server1
dhcp-host=aa:bb:cc:dd:ee:00,10.0.0.51,server2
Split DNS (VPN/Internal)
# Route specific domains to internal DNS server
server=/internal.company.com/10.0.0.1
server=/10.in-addr.arpa/10.0.0.1
# Everything else goes to public DNS
server=1.1.1.1
server=8.8.8.8
Development Environment
# Resolve all .test domains to localhost (great for development)
address=/.test/127.0.0.1
# Or use specific development domains
address=/frontend.dev/127.0.0.1
address=/api.dev/127.0.0.1
address=/db.dev/127.0.0.1
systemd-resolved Conflict (Ubuntu)
# Ubuntu uses systemd-resolved on port 53 — disable it first
sudo systemctl disable --now systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
# Start dnsmasq
sudo systemctl enable --now dnsmasq
Testing
# Test DNS resolution
dig @127.0.0.1 myapp.local A +short
dig @127.0.0.1 example.com A +short
# Check cache statistics
kill -USR1 $(pidof dnsmasq) # Dumps stats to syslog
journalctl -u dnsmasq | grep "queries"
# Test DHCP
sudo journalctl -u dnsmasq | grep DHCP
Best Practices
- Use
bind-interfacesand explicitlisten-addressfor security - Set
cache-sizeto 5000-10000 for busy networks - Enable DNSSEC validation for security
- Use
/etc/hostsfor static entries — dnsmasq reads it automatically - Disable systemd-resolved on Ubuntu before running dnsmasq
- Use wildcard entries (
address=/.dev.local/) for development convenience