Linux DNS routing: keep system capture and domain policy separate
Understand the boundary between the Linux resolver, a local DNS proxy, and enterprise DNS—and how to avoid upstream loops and internal-name leaks.
DNS capture is often reduced to “change the system DNS.” A reliable implementation has to answer two separate questions: how the operating system hands queries to the client, and how the client selects an upstream server.
Two separate responsibilities
The Linux integration layer connects applications that use the system resolver to a local DNS proxy. The Go proxy applies domain-suffix policy and chooses either enterprise DNS or the endpoint’s original DNS. Keeping these layers separate makes it possible to verify system integration and policy execution independently.
On systems using systemd-resolved, first identify the service state, the target of /etc/resolv.conf, and the active network manager. Then apply configuration through the supported runtime interface. If the resolver sends ordinary queries to the local proxy, the proxy can listen on a dedicated loopback port and avoid competing with the system stub address.
Preserve upstreams before capture
Discover and save external DNS upstreams from the active network before changing resolver state. Reading system resolver configuration after capture may return the local proxy itself and create a forwarding loop.
Enterprise DNS is best configured with IP addresses. The proxy should use direct UDP/TCP DNS clients for enterprise and endpoint upstreams, rather than calling the system resolver and sending the query back to itself.
Fail closed for internal names
Queries matching enterprise suffixes should go only to enterprise DNS. If enterprise DNS is unavailable, internal name resolution should fail instead of falling back to a public resolver. External names can continue to use the endpoint DNS servers saved before capture.
Verify this behavior with proxy logs and packet capture. Seeing an IP address returned by a command does not prove that the query reached only the intended upstream.
Capture must be reversible
Save resolver state and ownership before applying changes. Network switches, DHCP updates, resolver restarts, and client shutdown all require state reconciliation. Before restoring state, confirm the configuration is still managed by the client so that a later user or network-manager change is not overwritten.
System DNS capture covers applications that follow the system resolver. Apps with their own DNS client, DoH/DoT, or an embedded resolver may bypass it. Enforcing policy for those applications requires a separate network-layer design.
