7
 min read
September 16, 2025
|
Updated: 

man 7 windows-nrpt

Engineering

When we started working with Windows NRPT, the guide we needed didn’t exist. So we wrote it ourselves. Learn its APIs, pitfalls, and best practices for safe deployment.

In this post we’d like to dive into how the Windows Name Resolution Policy Table (NRPT) works. We originally looked into NRPT while developing Island's ZTNA Product, and although we opted for a different, more robust approach, NRPT remains a reliable and suitable solution for many use cases. In this article, we’ve decided to document the main APIs and share the lessons learned from using NRPT in production. The official documentation for NRPT can be found here.

NRPT is a powerful feature in Windows that allows administrators to configure DNS client behavior for specific queries. In contrast to the common solution of a DNS server, which applies arbitrary logic on incoming requests, NRPT is a table of rules that the Windows DNS client checks before sending a DNS query. These rules can dictate how a query is resolved, including:

  • Which DNS servers to use: Specify different DNS servers for different namespaces
  • Security requirements: Enforce DNSSEC validation for certain names
  • Proxy settings: Tunnel specific queries through a proxy
  • Blocking resolutions: Prevent certain queries from resolving

NRPT is particularly useful in enterprise environments for managing complex network configurations, enhancing security, and optimizing DNS resolution performance.

With great power comes great responsibility. NRPT rules are persistent, and as such, they survive reboots and remain active until explicitly removed. They are not bound (in their lifetime) to a specific DNS resolver, proxy, or endpoint. While this persistence maintains continuity, it can also introduce unexpected behavior if rules become stale, misconfigured, or are applied inconsistently across environments. Implementing a failsafe mechanism - such as monitoring, automatic rule reconciliation, or rollback strategies - can be critical in large-scale production deployments. These measures enable NRPT to continue providing reliability and security without becoming a hidden source of outages.

How NRPT Works

When the DNS client on a Windows machine needs to resolve a domain name, it first consults the NRPT. The process typically follows these steps:

  1. Query Initiation: 
    • An application or service requests to resolve a hostname (e.g., www.example.com).
  2. NRPT Lookup: 
    • The DNS client checks if the requested name matches any entries in the NRPT. Entries can be specific names, suffixes, or even wildcards.
  3. Rule Application:
    • If a match is found, the DNS client applies the rules associated with that NRPT entry. These rules override the standard DNS client settings.
    • If no match is found, the DNS client proceeds with its default DNS configuration (e.g., using DNS servers obtained via DHCP).
  4. DNS Query: 
    • The DNS client sends the query to the appropriate DNS server(s) based on the NRPT rules or default settings.
  5. Resolution: 
    • The DNS server responds, and the client returns the resolved IP address to the requesting application.

Since NRPT only applies to resolutions that use the DNS client, some programs might bypass it completely. A notable example is nslookup. The modern Resolve-DnsName PowerShell cmdlet is built on the Windows DNS client APIs, so it fully honors NRPT rules. As a result, administrators often see confusing discrepancies: a query with nslookup might resolve differently from the same query made by an application or Resolve-DnsName. For testing and troubleshooting NRPT, Resolve-DnsName should always be preferred, since it accurately reflects what the system and applications using the Windows resolver will experience.

Adding an NRPT Rule

NRPT rules can be configured using several methods, depending on your environment and preference.

1. Group Policy

A Group Policy is a feature in Windows that lets IT administrators manage and configure settings for users and computers in an Active Directory environment. Instead of setting policies one machine at a time, admins define rules centrally in a GPO - things like password complexity, software installation, desktop restrictions, or security settings and NRPT. When a computer or user logs into the domain, these policies are automatically applied, maintaining consistent configuration and security across the organization. For domain-joined machines, Group Policy is the recommended method for centrally managing NRPT rules.

  • Open Group Policy Management Editor (gpedit.msc): 
    • Navigate to Computer Configuration > Windows Settings > Name Resolution Policy.
  • Create a New Rule: 
    • Right-click in the Name Resolution Policy pane and select Create Rule.
  • Configure Rule Settings:
    • For a name or suffix, specify the name or suffix the rule applies to (e.g., example.com, *.contoso.com).
    • For DNS servers, enter the IP addresses of the DNS servers to use for this rule.
    • For security, configure DNSSEC settings if required (e.g., Enable DNSSEC in this rule).
  • Apply and Update Policy: 
    • After configuring the rule, ensure the Group Policy is applied and updated on client machines (gpupdate /force).

2. PowerShell

PowerShell provides a command-line interface for scripting and automating NRPT rule creation.

The Add-DnsClientNrptRule Cmdlet is used to add new NRPT rules.

$nameServers = [string[]]("192.168.1.100", "192.168.1.101")
Add-DnsClientNrptRule -Namespace "example.com" -NameServers $nameServers
  • Namespace: The DNS namespace the rule applies to.
  • NameServers: A comma-separated list of DNS server IP addresses. 

You can explore other parameters like -Proxy, -QueryIpsecSettings, etc., for advanced configurations.

Thanks to the Get-DnsClientNrptRule Cmdlet, PowerShell is also a very convenient tool for looking at existing NRPT rules:

3. Registry

Creating a PowerShell process to add, list, or delete NRPT rules is highly inefficient. Beyond the overhead of process creation for each operation, PowerShell security scanning from third-party security tools, such as EDR solutions, further amplifies latency and resource consumption. As such, we opted to dive deep into Windows’ DNS client and figure out how to manually configure it ourselves.

The Windows DNS client service, known internally as DnsCache, is responsible for resolving domain names and caching the results to speed up future lookups and reduce network traffic. It applies NRPT rules when configured, so that certain domains are resolved using specific DNS servers or settings.

Much of its configuration is stored in the registry. Specifically, the registry paths for NRPT rules are:

  1. GPO policy:
    HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\WindowsNT\DNSClient\DnsPolicyConfig
  2. Local policy:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCache\Parameters\DnsPolicyConfig

Please note that if any Group Policy NRPT rule exists, all local NRPT rules will be ignored.

Each rule is defined as a subkey of one of these two keys. The name of the rule key does not matter, and could be anything. The only thing that matters is the values inside the key. All the value names and meanings are actually well documented by Microsoft here.

At the time of writing, these are all of the documented values:

ConfigOptions must be a combination of any of these flags:

  • 0x00000002 - Enable DNSSEC options (4,5,6,7)
  • 0x00000004 - Enable DirectAccess options (8,9,10,11,12)
  • 0x00000008 - Enable the generic DNS option (13)
  • 0x00000010 - Enable the IDN Configuration option (14)

DNSSECQueryIPSECEncryption and DirectAccessQueryIPSECEncryption must be one of these values:

  • 0x00000000 - No encryption
  • 0x00000001 - Low security (AES/DES with 128/192/256 key size)
  • 0x00000002 - Medium security (AES with 128/192/256 key size)
  • 0x00000003 - High security (AES with 192/256 key size)

DirectAccessProxyType and ProxyType must be one of these values:

  • 0x00000000 - No proxy for DirectAccess
  • 0x00000001 - Use the default proxy for DirectAccess
  • 0x00000002 - Use the proxy configured in (9) for DirectAccess

IDNConfig must be one of these values:

  • 0x00000000 - The query name MUST be encoded in UTF-8 without any mapping
  • 0x00000001 - The query name MUST be encoded in UTF-8 with mapping
  • 0x00000002 - The query name MUST be encoded in Punycode

For example, an NRPT rule could be represented by the registry key

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DnsCache\Parameters\DnsPolicyConfig\{4EAFD564-C20C-4736-8467-6AC606A5BAC5}
that looks like this:

Reloading the DNS client's configuration

Although the configuration is stored in the registry, simply modifying these keys won't actually do anything, as the configuration is mostly cached in the DNS client's memory. This can be solved by forcing it to refresh its configuration from the registry via sc control DnsCache paramchange (DnsCache is the actual name of the service).

If we want to do this with code, we'd have to:

1. Get a handle on the Service Manager

2. Request a handle for DnsCache (the DNS client service)

3. Send a PARAMCHANGE control code to DnsCache

In rust, using Microsoft's Windows crate, it would look like this:

unsafe {
   let service_manager =
       Win32::System::Services::OpenSCManagerW(None, None, SC_MANAGER_CONNECT)
           .context("Failed to open service control manager")?;
   let dns_service = Win32::System::Services::OpenServiceW(
       service_manager.0,
       windows::core::w!("DnsCache"),
       SERVICE_PAUSE_CONTINUE,
   )
   .context("Failed to open DnsCache service")?;
   let mut status: Win32::System::Services::SERVICE_STATUS = Default::default();
   Win32::System::Services::ControlService(
       dns_service.0,
       SERVICE_CONTROL_PARAMCHANGE,
       &mut status,
   )
   .context("Failed to send paramchange control command to DnsCache service")?;
}

The requested access level of SERVICE_PAUSE_CONTINUE to DnsCache is just high enough to allow us to send a PARAMCHANGE control command, but also low enough for the Service Manager to allow for a privileged service such as DnsCache.

The Mystery of the Missing rules

During early internal testing, users reported that the VPN occasionally failed. Our investigation revealed that the NRPT rules were being removed. After carefully reviewing the code and logs, we confirmed that Island itself was not responsible. This pointed to other possible causes - such as interference from a third-party component or unexpected operating system behavior.

At this point, our options were limited. We could have built a watchdog to monitor the rules, but doing so without understanding the root cause risked introducing race conditions and other side effects. Our priority, therefore, was to identify who was deleting the rules; only then could we determine why. To that end, we set up a Procmon filter focused on the relevant registry path.

Within a single workday, the results pointed us to an interesting culprit: DnsCache. It was the process responsible for removing the rules.

While this explained who, we still needed to understand why. To dig deeper, we attached WinDbg and set a breakpoint on the function in question. At first, nothing happened - hours passed without a single trigger. The following day, however, as soon as the laptop was detached from the docking station, the breakpoint finally fired. The key factor was the network transition: moving from Ethernet (via docking station) to Wi-Fi.

Once identified, the issue was easy to reproduce. Any network configuration change between Wi-Fi and Ethernet consistently caused the NRPT rules to disappear.

After finding the root cause of this issue, there are several mitigations to choose from. Implementing either a watchdog to monitor and adjust the rules, or an event-based mechanism that applies logic based on network changes (Ethernet <> WiFi).

Discovering More DNS Configuration Settings

The Local Group Policy Editor tool (gpedit.msc) contains lots of settings, and is a great way to discover new features. These settings aren’t actually hard-coded, but are read from definition files under C:\Windows\PolicyDefinitions. That’s great for us, as we can simply look at these files directly to help us figure out what registry keys are related to each setting.

Let’s take a look at Smart Multihoming under DnsClient.admx:

<policy name="DNS_SmartMultiHomedNameResolution" class="Machine" displayName="$(string.DNS_SmartMultiHomedNameResolution)" explainText="$(string.DNS_SmartMultiHomedNameResolution_Help)" key="Software\Policies\Microsoft\Windows NT\DNSClient" valueName="DisableSmartNameResolution">
   <parentCategory ref="DNS_Client" />
   <supportedOn ref="windows:SUPPORTED_Windows8" />
   <enabledValue>
       <decimal value="1" />
   </enabledValue>
   <disabledValue>
       <decimal value="0" />
   </disabledValue>
</policy>

We can clearly see the relevant registry key, value name, and possible values!

Please note that, similarly to NRPT configuration in the registry, we need to force the DNS client to reload its configuration from the registry for the things we write to take effect. Luckily, we already know how to do that - by sending a PARAMCHANGE control command to the DnsCache service.

Summary

NRPT has some pitfalls but is most useful and often easier to manage when you need per-domain DNS rules rather than applying one DNS setting universally. In scenarios like DirectAccess, NRPT automatically ensures corporate domains resolve through internal DNS servers while public domains use local internet DNS. It also simplifies enforcing DNSSEC validation for sensitive domains without impacting all traffic, and makes it straightforward to route only specific namespaces (such as corp.example.com) through designated servers while leaving others untouched. Compared to pushing a single DNS server via DHCP or Group Policy, NRPT provides greater flexibility with less administrative overhead, since you can target only the domains that matter instead of rewriting system-wide DNS settings. In short, NRPT is most effective and easier when you require granular, domain-specific DNS control - particularly in managed, domain-joined enterprise environments.


The Island Enterprise Browser fundamentally transforms how the world’s leading organizations work by embedding enterprise-grade IT, security, network controls, data protections, app access, and productivity enhancements directly into the browser itself, enabling secure access to any application, protecting sensitive data, streamlining IT operations, and delivering a superior end-user experience while actually boosting productivity.

To learn more about how we're reimagining the enterprise workspace from the browser up, start here. If you’re interested in building something that’s changing everything, check out our open positions here.

Adir Makmel

Adir is a Technical Leader at Island who specializes in Chromium. Before Island, Adir spent years working in both small startups and large enterprises. His wide-ranging background includes developing an x86 hypervisor with full nesting support, building large Windows kernel components, and conducting low-level kernel research. You can follow Adir's work at https://www.linkedin.com/in/adir-makmel

Daniel Firer

Daniel is a senior software engineer at Island, working as part of the networking group responsible for Island's ZTNA solution. With years of experience in security research, Daniel has a background in and much love for OS internals, cryptography and network protocols.

No items found.