Incorrect usage of Name from NRPT table
I believe there is a misunderstanding of the purpose the Name field within the NRPT table. The code is placing the Name value into the DnsSuffix property of the NameServer instance.
The Name value is not a DNS suffix that is meant to be searched, rather it is a suffix that is used to determine the target DNS server. For example, if the NRPT table has a Name of ".contso.com" any DNS queries using that suffix should be sent directly to the matching NameServer instance.
This setting in the NRPT table is commonly used with Split Tunnel VPN connections. It ensures that DNS lookups for the target domain are made through the VPN rather than local DNS configuration.
It would be beneficial for DNS queries to select the target NameServer instances based on these settings.
DnsSuffix is used for finding the proper DNS server for a query, yes. NSLookup is also using it to append the suffix to queries which do not have a domain name or don't yield results. E.g. if you ask for your machine name, without a domain suffix, you might not get anything back, but appending the suffix might help (if you then use the right DNS server).
Anyways, so far, I haven't added any logic to the library which would use the suffix. This was also explained here: #122
I kinda agree that prioritizing the configured list of DNS servers based on the query contains a matching suffix might be a good idea. I'm still not so sure about the NSlookup way of using the suffix
The Name from the NRPT table isn't actually used as part of the DNS Suffix Search List. It's used a namespace to limit DNS queries to a specific network interface (or set of network interfaces).
If you use the powershell command Get-DnsClientNrptRule (and you have some NRPT entries) you'll see the Name field is actually referred to as Namespace.
I am planning to add support for targeted DNS queries that will be able to handle the NRTP table and implement parallel queries (at least on the async side) simultaneously. Are you open to a pull request for that?
Could you explain what you have in mind for the first part a bit more?
Luckily my work VPN actually uses the feature and I do see ~15 NRPT records. That's still just a set of suffixes for DNS Server IP addresses though. The only thing which I see the library here isn't handling is that you can have more than one suffix per server. At least in my case here I got 10 different domains all using the same DNS server and then a bunch of other domains use a generic public one or something else.
So I could see the NameServer.DnsSuffix should probably be a list, not just one. And then, the query path could check if certain labels are matching with any of the suffixes of the NameServer and then prioritize those..
But anyways, could you explain what you plan to do
And yes, feel free to send a PR, but maybe discuss what you want to do beforehand, so that you don't waste your time ;)
The namespaces from NRPT tables aren't used as DNS Search Suffixes. The DNS Search Suffixes are appended to queries as you already know, the namespace is only used to target DNS queries to specific servers. It's highly probable that your corporate VPN is configuring a namespace and adding a DNS Search Suffix for the same domain.
Regarding the NRPT rules, my intent is:
Add a new property to the NameServer instance. Off the top of my head, that property would be named Namespace. When processing the NRPT rules (from the registry) rather than putting the Name value into DnsSuffix, it would be put into Namespace. I'd remove the current filter that eliminates namespace elements that do not start with a '.'
During a query, the server list would be filtered to either include only matching NameServer instances or exclude all NameServer instances with a defined namespace depending on the name being queried.
I believe that will replicate Windows usage of the NRPT table.
Hi @williamb1024 I had a bit time to look into this a bit again. I don't think the code is doing anything wrong by using the name field to get the suffixes, that's for some reason the field name in the registry used to store the list of namespaces.
Here is an example:
I created a dummy rule looks as follows when looking at PowerShell:
As you can see, I got 2 namespaces.
When reading that rule with the existing code, it correctly gets the 2 namespaces from the name field:
So, this means, nothing to change here.
Regarding the filtering discussion:
I will change the filter for suffixes and excluding namespaces not starting with . to include anything.
I'll also change the code a bit so that I can have multiple nameservers with different namespaces stored as suffix.
Also, DnsString has concatenation support, I will extend that a bit to allow easy domain name concatenation.
I'll also add a Contains to DnsString, for easy checking if a suffix of a nameserver is part of your query string for example...
With all those tools, it should be possible to implement any kind of name server filtering and targeted queries you want. I just think that implementing those things in this library would be very opinionated and I'd rather not do that per default. At least for now.
see #207
Here is an example:
var lookup = new LookupClient();
var useDomain = "<some incoming query>";
var parsedDnsString = DnsString.Parse(useDomain);
foreach (var server in lookup.NameServers
.Where(p => p.DnsSuffix != null && parsedDnsString.Contains(p.DnsSuffix)))
{
var serverResult = await lookup.QueryServerAsync(new[] { server }, useDomain, useQType).ConfigureAwait(false);
Console.WriteLine(serverResult.AuditTrail);
return 0;
}
var result = await lookup.QueryAsync(useDomain, useQType).ConfigureAwait(false);
Console.WriteLine(result.AuditTrail);
I appreciate that you took the time to consider this further, but ultimately there appears to still be a disconnect between the usage of the NRPT table and the purpose of the NRPT table.
Mind sharing what exactly you mean @williamb1024 ? If you just mean that the DnsClient library doesn't use the NRPT table information out of the box, then, sure. I get that. I might change or add that later. I'm just not 100% sure about the flow in combination with all the existing fallbacks and error handling settings the library has.
So, for now, you can implement whatever logic you need yourself, with the API this library provides. In some later version I might add some server filtering or priority mechanism based on NRPT and other things.
My apologies, I'd convinced myself that the library was adding the DnsSuffix to queries automatically. After reviewing the code again, I see that is only happening in your minidig example.