Candid photograph of a Linux server terminal with a soft olive-green glow against a dark slate background, conveying a calm technical atmosphere.

Step-by-step guides for system administrators — covering command-line basics, web server setup, and preparation material for technical interviews.

Browse Tutorials

Setting up a DNS caching server with dnsmasq on CentOS

DNS resolution sits quietly behind almost every interaction a Linux server has with the outside world, yet it is often overlooked when performance tuning. Every web request, package update, container pull, and email delivery starts with a lookup, and those lookups add up fast on a busy box. Running a local caching resolver turns thousands of repeated queries into a handful, shaving milliseconds off each request and reducing outbound traffic to upstream providers.

dnsmasq is a lightweight DNS, DHCP, and TFTP daemon that has been a staple of small networks for two decades. It is small enough to run on a Raspberry Pi, stable enough for production, and easy enough to configure without a dedicated BIND zone file. For a single CentOS server or a small internal fleet, it strikes a useful balance between features and simplicity.

For Australian administrators, a resolver can make a real difference. Connections from Perth to international anycast servers routinely traverse undersea cables and add latency that smaller caches cannot mask. Local ISPs such as Telstra, Optus, and TPG also publish their own resolvers, which are often faster than the global defaults. Pairing those resolvers with a local dnsmasq instance keeps repeat lookups inside your own network, which helps on slower NBN connections in regional areas.

This walkthrough covers installation on CentOS and RHEL-based systems, configuration of upstream servers, firewall adjustments, and quick checks that confirm the cache is doing its job.

Installing dnsmasq on CentOS and RHEL

dnsmasq ships in the EPEL repository, so the first step is enabling EPEL if it is not already present. On CentOS Stream or RHEL 9, the commands are straightforward:

sudo dnf install epel-release -y
sudo dnf install dnsmasq -y

Once installed, enable the daemon so it survives patches and power events:

sudo systemctl enable dnsmasq

Before editing any files, take a copy of the shipped defaults. The package maintainers include a long example file with commented options that explain nearly every knob:

sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.orig

On minimal CentOS images you may also need bind-utils to get dig and nslookup for testing later. The package is small and worth having on any debugging host.

Configuring the main dnsmasq file

Open /etc/dnsmasq.conf in your preferred editor. The file is large but most lines are commented examples. A sensible starting point for a caching-only server includes listening on a specific interface, allowing queries from your local subnet, and caching a generous number of entries.

The minimum useful configuration looks like this:

listen-address=127.0.0.1
cache-size=1000
domain-needed
bogus-priv

If the server has multiple interfaces, add a second listen-address line for the internal IP. Avoid binding to the public interface unless you intend to run an authoritative or recursive service for the whole internet, which is rarely what you want in a typical Australian business environment.

The cache-size value controls how many names dnsmasq keeps in memory. The default of 150 is conservative; 1000 is a reasonable starting point for most servers. Larger values consume more RAM but reduce misses on busy hosts.

Pointing to upstream resolvers

Out of the box, dnsmasq reads /etc/resolv.conf to find upstream servers. For predictable behaviour, set the resolvers explicitly using the server= directive. Australian ISPs publish their own resolvers, and these are often faster than generic public ones because the paths are shorter within the autonomous system.

For example, to prefer Telstra's resolvers with Cloudflare as a fallback:

server=139.130.4.4
server=203.50.0.1
server=1.1.1.1
server=1.0.0.1

You can also use the resolve-file option to point dnsmasq at a separate file, which keeps /etc/resolv.conf untouched for other services. This is useful when NetworkManager rewrites resolv.conf during DHCP renewals on a CentOS host. After saving the file, restart the service to load the new settings:

sudo systemctl restart dnsmasq

Opening DNS ports in firewalld

dnsmasq listens on UDP and TCP port 53. On a default CentOS installation with firewalld active, those ports are blocked externally, which is the safe default. If other hosts on the same subnet will query the cache, you need to allow them through.

The minimal rule for a single trusted subnet looks like this:

sudo firewall-cmd --permanent --add-service=dns
sudo firewall-cmd --reload

If you need to scope it tighter, replace --add-service=dns with a rich rule that limits source addresses to your office or data centre range, such as the IPs allocated to your Sydney or Melbourne office networks. For a single workstation acting as its own resolver, no firewall change is required because queries stay on the loopback interface.

Do not open port 53 to the public internet unless you understand the abuse vectors and have a clear operational reason. Open recursive resolvers are regularly scanned and weaponised for amplification attacks, and the ACSC has published advisories about exposed DNS services in Australian networks.

Testing, logging, and verifying cache hits

With the service running, confirm it is responding locally with dig:

dig @127.0.0.1 example.com

The first lookup should show a query time in the tens of milliseconds. Run the same command again and the query time should drop to single digits or zero, indicating a cache hit. The flags field in the response will show a non-zero bit when the answer came from cache.

To watch dnsmasq in real time, enable query logging temporarily by adding log-queries to /etc/dnsmasq.conf and restarting the service. Logs land in /var/log/messages on classic syslog or in the journal under dnsmasq on systemd-based systems. Use journalctl -u dnsmasq -f to follow them. Turn query logging off once you have verified the cache works, since verbose logging on a busy server fills disks quickly.

If you are also running mail services on the same host, the postfix mail server guide follows a similar pattern of local caching and explicit upstream configuration.

Common pitfalls and tweaks

A few issues show up often. SELinux can block dnsmasq from binding to non-standard ports or reading custom files; check /var/log/audit/audit.log and run audit2allow if needed. NetworkManager sometimes overwrites /etc/resolv.conf, which silently breaks dnsmasq's upstream path. Set PEERDNS=no in the relevant ifcfg file or use the resolve-file option to keep things stable.

Another common trap is systemd-resolved running on port 5353 on the loopback interface. Either disable it with systemctl disable --now systemd-resolved or point dnsmasq to a different listen address so the two do not collide. For Australian setups behind CGNAT or restrictive ISP plans, you may also want to set min-cache-ttl and max-cache-ttl to suit your patch and refresh schedule.

Configuration drift is the silent killer of dnsmasq setups, especially across a small fleet. Keeping snippets and config notes in a tool such as a personal project workspace makes it easier to spot when a host has wandered off the standard.

A local dnsmasq resolver is one of those rare sysadmin tweaks that pays back almost immediately. Once it is running, every service on the box benefits, from yum and dnf through to container runtimes, and outbound DNS traffic drops sharply. The savings show up first in package install times and container pulls, then quietly under everything else that touches the network.