When DNS Forwarding Meets Recursion: Understanding Conditional Forwarders in Windows

When DNS Forwarding Meets Recursion: Understanding Conditional Forwarders in Windows

Original text by https://it-pro-berlin.de

The article analyzes how conditional forwarders and recursion interact in Windows DNS servers, clarifying a common misconception among administrators. The author investigates a claim that disabling recursion globally on a Windows DNS server would also disable conditional forwarders. Through experiments and configuration analysis, the article shows that conditional forwarders can actually override the server-wide recursion setting on a per-zone basis. This behavior is not clearly visible in the standard DNS management console but can be configured and inspected using PowerShell or registry settings

The author demonstrates several scenarios involving different DNS configurations, such as when the target server hosts a primary or secondary zone, when a stub zone is used, or when external DNS infrastructure participates in resolution. Depending on these setups, recursion may occur either on the forwarding server, the target DNS server, or not at all. In some cases, disabling recursion can lead to SERVFAIL responses, while in others the query still succeeds because the authoritative server answers directly. The key takeaway is that DNS resolution behavior depends on zone authority, forwarding configuration, and recursion settings, and administrators must understand these relationships to avoid troubleshooting problems in enterprise DNS environments. 


You know how „it’s always DNS“? A really great feature of DNS is its ability to delegate getting results of a query instead of hosting the world’s worth of name resolution locally. But to make sure your setup works as intended, it’s important to remember how the technology works under the covers. I wrote it up so I – and you – won’t forget.

What is this about?

A couple of days ago, someone asked on a support forum:

Our MSP says if we disable recursion on our Windows DNS, it will also disable Conditional Forwarders. A test suggests otherwise, is there anything definitive where we can look that up?

A great question! My Google-Fu didn’t fare any better than theirs, but I did remember from previous digging that Conditional Forwarders in Windows DNS can be set to use recursion or not on a per-zone basis. This is not surfaced in the MMC, but can be set (and viewed) via PowerShell and/or registry. The PowerShell documentation also says,

This parameter overrides the Use Recursion setting for a DNS server.

which, if we remember that the default setting for this is True, explains why Conditional Forwarders seemingly remain unaffected if we disable recursion server-wide. Conversely, if we disable recursion on a particular zone, this should override whatever is set on the server.

Scenarios

Let’s see how it works in practice. In all tests, clients will query the DNS server we’ll be calling local, This DNS server has a Conditional Forwarder for a certain DNS zone configured to a different DNS server that we’ll be calling target. Both of them have global forwarders to the public DNS infrastructure configured, and there is also another private DNS server, called master, that will be used later:

Depending on whether the zone being conditionally forwarded by local is actually being hosted on targetand in what form, the behavior from the client’s point of view will vary if we start enabling or disabling recursion along the signal chain.

Scenario 1: Primary or Secondary zone

Let’s start with a scenario very commonly encountered, for example, in on-premises infrastructures trusting one another. To facilitate this, target actually hosts the zone being queried, either as primary or as secondary. In any case, target is authoritative for this zone from its own point of view.

In this scenario, recursion does not come into play AT ALL. It is also of no consequence if a zone by the same name is being hosted on public DNS infrastructure or not. Any queried record that exists internally will return the expected internal reply, any record that does not exist in the target zone causes the local DNS server to return NXDOMAIN to the client. As long as the target server is responding, either reply is nearly immediate:

Recursion on target DNSRecursion on local DNSRecursion on forwarderResult – hosted on targetResult – not hosted on target
enabledenabledenabledResult (immediate)NXDOMAIN (immediate)
enabledenableddisabledResult (immediate)NXDOMAIN (immediate)
enableddisabledenabledResult (immediate)NXDOMAIN (immediate)
enableddisableddisabledResult (immediate)NXDOMAIN (immediate)
disabledenabledenabledResult (immediate)NXDOMAIN (immediate)
disabledenableddisabledResult (immediate)NXDOMAIN (immediate)
disableddisabledenabledResult (immediate)NXDOMAIN (immediate)
disableddisableddisabledResult (immediate)NXDOMAIN (immediate)

Scenario 2: Stub zone whose master local DNS can also reach

In the second scenario, target only hosts a stub for the zone being queried. The master copy of the zone can be hosted on either private or public DNS, but both local and target can reach the master server by means of their gloabl forwarders:

As long as recursion is enabled on target, so that the stub zone functionality is actually invoked, no recursion settings on local influence the behavior – if the record being queried exists in the master copy, it is returned to the client, and if it does not exist, NXDOMAIN is returned. The lookup in the master copy is done by target.

If we disable recusion on target, the behavior is determined by the recursion setting on the Conditional Forwarder. If that is disabled, the client will get SERVFAIL for any query; if it is enabled, the expected result is returned to the client:

Recursion on target DNSRecursion on local DNSRecursion on forwarderResult – hosted on masterExternal lookup by
enabledenabledenabledResult (immediate)target
enabledenableddisabledResult (immediate)target
enableddisabledenabledResult (immediate)target
enableddisableddisabledResult (immediate)target
disabledenabledenabledResult (immediate)local
disabledenableddisabledSERVFAIL (immediate)N/A
disableddisabledenabledResult (immediate)local
disableddisableddisabledSERVFAIL (immediate)N/A

Scenario 3: Stub zone only the forwarding target can reach

If the stub zone is hosted on the master DNS server that can be reached by target but not by local, the latter obviously cannot perform the lookup by itself.

As long as recursion on target is enabled, the behavior stays the same as in the previous scenario – the queried record is returned if it exists, otherwise NXDOMAIN is returned. If recursion is disabled on both target and the Conditional Forwarder, the behavior also stays the same – the client will see a SERVFAIL without any delay. However, if recursion is disabled on target but enabled on the Conditional Forwarder, target will try to resolve the query using its global forwarders (which do not point to master), resulting in a timeout as set in the forwarder configuration:

Recursion on target DNSRecursion on local DNSRecursion on forwarderResult – hosted on masterResult – missing record
enabledenabledenabledResult (immediate)NXDOMAIN (immediate)
enabledenableddisabledResult (immediate)NXDOMAIN (immediate)
enableddisabledenabledResult (immediate)NXDOMAIN (immediate)
enableddisableddisabledResult (immediate)NXDOMAIN (immediate)
disabledenabledenabledTimeoutTimeout
disabledenableddisabledSERVFAIL (immediate)SERVFAIL (immediate)
disableddisabledenabledTimeoutTimeout
disableddisableddisabledSERVFAIL (immediate)SERVFAIL (immediate)

Scenario 4: External zone both DNS servers can reach

If, for whatever reason, target does not host anything related to the forwarded zone, but local still has a Conditional Forwarder pointing to target for it, one could half expect the resolution to succeed in all cases, since both server involved can perform name resolution against the external (public) DNS infrastructure:

This is not, however, what ends up happening. As soon as recursion is disabled on target, name resolution stops working. If recursion is also disabled on the Conditional Forwarder, an immediate SERVFAIL is returned. Otherwise, a timeout occurs, just like in the previous case!

Recursion on target DNSRecursion on local DNSRecursion on forwarderResult – hosted on masterResult – missing recordLookup by
enabledenabledenabledResult (immediate)NXDOMAIN (immediate)target
enabledenableddisabledResult (immediate)NXDOMAIN (immediate)target
enableddisabledenabledResult (immediate)NXDOMAIN (immediate)target
enableddisableddisabledResult (immediate)NXDOMAIN (immediate)target
disabledenabledenabledTimeoutTimeoutN/A
disabledenableddisabledSERVFAIL (immediate)SERVFAIL (immediate)N/A
disableddisabledenabledTimeoutTimeoutN/A
disableddisableddisabledSERVFAIL (immediate)SERVFAIL (immediate)N/A

Happy forwarding! Or recursing… Or just cursing, but that’s DNS for you!

Comments are closed.