DNS resolver on a server: systemd-resolved or Unbound for your scenario

Name resolution breaks unnoticed: services respond more slowly, and some queries go outside. We configure a DNS resolver for your scenario — with local cache, fault tolerance, and clear regulations. We'll discuss the task and come back with an implementation plan.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

DNS Resolver Setup: Where Name Resolution Breaks

Name resolution on a server is a chain: application, local resolver, upstream servers, and the root zone.

It is usually not the chain itself that breaks but its joints: an empty cache after a restart, a single upstream address in the configuration, and a predictably unpredictable first query.

When the name resolution service restarts, the local cache is reset, and the first query after the restart follows the full path — recursive traversal, signature validation, and, if the response is truncated, a retry over another transport.

At application startup there are dozens of such queries, they queue up, and service response in the first seconds noticeably drops. A persistent cache warmed at startup removes the effect: names are served from the local database while upstream servers are only being queried.

The second failure point is binding to a single upstream address: it times out or responds slowly, and the entire application waits, not just the auxiliary service.

The third is that the name resolution configuration file is overwritten by the network manager the next time the interface comes up, and the built-in resolver occupies the local address and conflicts with its own zones and shared directories.

The choice between a built-in mechanism and a separate service — systemd-resolved or Unbound — is a choice between "works out of the box" and "manageably configurable": a separate service provides negative caching, multiple upstream servers with availability checks, zone separation by domain, and query statistics. How each of these failure points is closed during DNS resolver setup is below.

Local Cache, Fault Tolerance, and Query Privacy

Local name cache changes the service load profile entirely. Instead of a network call on every request, the application gets a response from resolver memory, and repeated resolutions of the same names stop depending on the external network.

Application response time on a typical profile is determined by processing rather than waiting for resolution, and remains at the same level even when external servers are overloaded. Negative caching works the same way: a name that does not exist is not re-queried on every call.

Fault tolerance is built on backup resolution servers, not on the hope that the provider will not go down.

The configuration specifies several external addresses with priority and timeout: unavailability of one moves the query to the next rather than taking down resolution entirely.

Cache itself also provides resilience to provider unavailability — already known names continue to respond while the external channel is down, and the service does not lose connectivity with those it has already exchanged traffic with.

Privacy is a consequence of the same cache. Only a fraction of queries goes outside; the rest are absorbed locally, so an external observer sees not the full picture of the service's requests but a fragment of it. Transport to external servers is closed with encryption so queries are not read along the way.

What exactly to deploy is a matter of scenario. Unbound as a full recursive resolver gives control over zones, limits, and cache size, but requires its own operation; systemd-resolved is closer to the role of a local stub, cheaper to maintain, and fits most servers by default.

Both options cover caching, backup servers, and keeping traffic from going outside — the difference is who you give control over resolution to.

Options for Organizing Name Resolution: Comparison of Modes

Name resolution on a server almost never comes down to "install a resolver and forget it": what matters is who owns the node configuration and how resolution behaves when the upstream server stops responding.

The built-in resolution service lives alongside the network subsystem and is managed by the same tools, while a separate caching server is an independent process with its own config, cache, and forwarding rules.

In practice, a choice is made among three schemes, and the difference shows not in the speed of a single response but in how the scheme is maintained, observed, and debugged. Below are the real alternatives among which the choice most often lies.

Option When it fits Limitations
Built-in resolution service A single node or small environment where the system manager already controls the network Cache and statistics are limited, there is no fine-grained per-zone policy, and behavior depends on the distribution build
Separate caching server Multiple nodes, need a shared cache and your own local zone for internal names Requires its own config, monitoring, and updates — it is another service to maintain
Combined scheme with query forwarding Internal zones are served locally, external ones go to trusted upstream resolvers The query path goes through two links, debugging and zone separation are more complex

The key criterion is not "which option is more modern" but how many nodes you have, whether you need a local zone for internal names, and how easily you will find the cause when a specific name does not resolve. Describe your environment — we will return with an assessment and a migration plan.

Implementation Stages: From Audit of Current Settings to Handover

We arrange the work order so that changing the resolver does not turn into an outage: first we record the current picture, then we change it. Each stage ends with an artifact — a config, diagram, or verification report — so the solution remains reproducible.

  1. Audit of server settings. We collect who resolves names and how: interfaces and their state, static records, conditional forwarding for internal zones, overrides, which services access the local handler directly. We separately look at hosts where a third-party address is specified — usually they are the ones that produce discrepancies after switching.
  2. Scheme design. We compare systemd-resolved and Unbound for the task: whether signature validation is needed, your own zones, separation of internal and external names, a separate cache for services. We determine where the failure point will be and how it survives upstream server unavailability.
  3. Test bench. We deploy the configuration in isolation and compare responses with the current scheme for critical names: the same addresses, the same record TTLs, predictable behavior when the source is unavailable.
  4. Rollback plan. We save the original files and startup parameters before edits, and describe the return procedure line by line. We switch one node at a time, not the whole fleet at once — if there is a deviation, rollback takes minutes.
  5. Switching. We change the system name handlers, restart the service, and monitor the failure rate and response time. Growth in requests to external servers is the first sign that the cache has not warmed up.
  6. Post-switch verification. Control queries for internal and external zones, cache behavior, reaction to service restart and to loss of connection with the upstream server. We record the results in a report.
  7. Handover. Configs go to the repository, along with a diagram, zone update policy, and a short instruction for the on-call engineer: what to check and what to roll back.

Describe your current name resolution scheme — we will return with an assessment and work plan.

Configurations, Zone Diagrams, and Procedures: What Stays with You

A resolver stops being a black box when its entire configuration is stored in a repository and described in words.

We hand over not a set of "magic" files but a working system: using it, your engineer will bring up the same node from scratch, reproduce the configuration on a test bench, and roll back a change without deciphering someone else's notes.

  • Settings files — the main configuration and additional override files in version control, with edit history and a meaningful description of each change.
  • Zone and forwarding diagram — which domains resolve locally, which go to upstream resolvers, where conditional forwarding for internal zones is configured, and how this relates to the search domain.
  • Access rules — from which subnets queries to service ports are allowed, to whom recursion is open, what is closed to the outside and why.
  • Maintenance procedure — frequency of zone checks, root hints updates, rotation of service records, and service restart without downtime.
  • Failure procedure — where to start diagnostics, how to switch to a backup resolver, which command rolls the configuration back to the last working revision.
  • Infrastructure documentation — addresses and roles of nodes, monitoring points, responsible persons, resolver connections with other services.
  • Set of post-edit checks — response time, failure rate, availability of internal zones; alerts are tied specifically to these metrics. The package stays with you along with a call walkthrough: what to check after each edit and by what signs degradation is visible. Operations should not depend on one person.

Implementation Example: Name Resolution Stopped Depending on the Provider

The customer's server fleet — about 60 machines across two sites — went to the provider's resolvers directly for names, while on some hosts a local cache from the distribution was running, and the settings had diverged over time.

The share of failed queries at peak held around 4%, and the application service, which parses dozens of internal names at startup, responded twice as long as usual.

What Was Changed

We deployed a recursive resolver on Unbound and set up two independent nodes at different sites — failure of either no longer stops name resolution.

Local caches on hosts were disabled, machines were switched to two addresses via a managed parameter, and internal zones were described separately from external ones. Node availability, response time, and error rate were put into monitoring with automated checks.

Metrics Before and After

  • Share of failed queries: about 4% at peak → consistently below 0.2%, a single failure is covered by a retry on the second node.
  • Application service response time at startup was cut in half — due to caching and a predictable query route.
  • Name resolution incident requests: 8–10 per month → one per quarter, and even then for an internal zone.

The single point of failure was removed: external resolvers remained a backup path but stopped being the only source of answers. Next we are developing the scheme — adding zone separation by site and checks that catch configuration divergence before users notice it.

Built-in Resolver or Separate One: When Is the Latter Needed?

Short answer: the built-in service covers a single server, while a separate instance is needed when a fleet of machines, an isolated environment, or a requirement to see every query appears.

The built-in resolver starts with the system and serves cache to all local processes — that is enough as long as network settings are not changed underneath it.

The built-in resolver reads parameters from the network manager and rewrites upstream servers on every address update.

Its query logging is shared with the system journal, without breakdown by client, and cache size cannot be limited — on a loaded host this is the first thing you want to move outside.

A separate Unbound provides explicit zones, local overrides, a cache warmed with popular names, and a separate journal: you can see who asked what and when.

Server load becomes predictable — the process lives under its own resource limiter, and on a fleet of machines it is moved to a dedicated node with access by subnet list.

Option When it fits Limitations
Built-in service Single server, simple network Settings are rewritten by the network manager, no per-client journal
Separate instance on the same host Need local zones and query analysis One host — one failure point, shares resources with applications
Separate node for a fleet of machines Shared cache for dozens of servers Need access restriction and availability control
Resolver in an isolated environment Internal names must not go outside Only its own sources and the perimeter forwarder

In an isolated environment, the resolver does not go outside at all: internal zones are served by an authoritative source, external ones by the perimeter forwarder. Responses go only along permitted routes, and leakage of internal names through public resolvers is excluded.

Engineer Doubts: Cache, Encryption, Configuration Rollback

Before work starts, engineers ask the same set of questions: what will happen to the already accumulated cache, do queries go outside in cleartext, will name resolution break for services that are already deployed, and how to return to the previous scheme if something goes wrong. Below are short answers for each point.

What to do with stale records in the cache?

The cache lives by record TTL, so an old zone after a service migration is a normal occurrence. We have an explicit cache flush, and before changes we lower record TTLs and restore the previous value after verification.

Are queries transmitted outside in encrypted form?

Outgoing queries can be wrapped in encrypted transport so the provider and intermediate nodes do not see names. Inside the perimeter, the resolver responds on the usual port — otherwise containers and legacy services will stop resolving names.

Compatibility with services that already run?

Before replacement, we take an inventory of who asks DNS and how: system services, containers, VPNs, domains. Zone separation — internal locally, external outside — is configured before switching, so services see familiar names.

How does configuration rollback work?

Configurations are stored in version control; application and rollback are done by switching to the previous set of files. We do not remove the old resolver until the new scheme has run under load; rollback takes minutes and does not require a server reboot.

Let's Discuss the Task: How We Arrive at an Implementation Plan

So that the assessment is based on facts rather than guesses, a minimum of input data is needed: how the environments are structured, who resolves names now and how, and what requirements are imposed on query isolation.

This is exactly what determines the choice between a local caching resolver and Unbound with its own zones and forwarding to closed environments.

What we request as input:

  • Environment diagram: network segments, where consumers are located, how traffic moves between them.
  • List of servers and roles: where the local resolver is, where the caching one is, where the forwarder is.
  • Isolation requirements: which zones must not go to external resolvers, whether DNSSEC is needed, and how to handle responses with a signature error.
  • Current state: working configurations, method of distributing resolv.conf, management via configuration manager.
  • Switching window, acceptable name resolution downtime, access permissions, and acceptance owners.

In response you receive a stage-by-stage implementation plan with readiness criteria for each, scope of work with separation of responsibility zones, and a list of artifacts: configurations, unit files, caching and forwarding policies, and a rollback scheme to the previous resolver.

Separately, we agree on the order of switching consumers and post-switch checks, as well as the handover procedure for operations — metrics, alerts, and instructions for the on-call engineer. Describe the task — we will return with an assessment, plan, and scope of work.