DNS::question name - Modifying a DNS Suffix When Your Windows Client Appends It During Recursive Lookups
Quite some time ago I was asked about a 2-second delay when performing recursive lookups against the BIG-IP. My first thought was that there was an issue with transport. I then decided to deploy it in my own lab. To my surprise, I was experiencing the exact same issue though I know there were no transport problems in my own environment.
So to give a little more color to the use case at hand, my Windows domain controller is performing recursive lookups against my BIG-IP. My BIG-IP is configured as a recursive DNS server using a transparent cache. This simply means that I am forwarding the request to another upstream DNS server and caching its response. Pretty simple right? Well, there is a little more to it as we will get into.
My next step was to look at the DNS query to see what it looked like at the BIG-IP. After a quick search on DevCentral for an iRule to log it, I applied it to my DNS listener and tailed the log.
when DNS_REQUEST {
log local0. "my question name: [DNS::question name]"
}
Interesting enough I found that the DNS query from the DC was actually appending the DNS suffix using its actual domain name. Then I also ran a tcpdump from the BIG-IP to see the actual request which indeed confirmed the results of my logs.
I then logged into my DC to identify the network connection settings. Everything looked OK but I am of course no expert at Windows network settings. As far as I know, this is how every DC is configured by default as I have not modified any of these settings.
Now I am stuck and pretty sure the only way to modify the query is to go to the magical language of Tcl. I admit I am no expert so I did some DevCentral searches and reached out to my team who provided some great feedback. In the end, I applied the following iRule and DNS resolution is occurring without the appended DNS suffix. Hope this helps!
when DNS_REQUEST {
if { [DNS::question name] ends_with "demo.lab" } {
set queryName [string trimright {“.demo.lab”} [DNS::question name] ]
log local0. "My new question name: $queryName"
DNS::return
} }
- Stanislas_Piro2Cumulonimbus
if you don't want domain appended, you must end the request with a dot.
nslookup www.google.com
will first request with domain appended, then fallback to initial request
nslookup www.google.com.
will request only
- Steve_LyonsRet. Employee
Agreed and to be completely transparent, this article was really derived from a customers request that the user experience was not the same when performing manual lookups against the BIG-IP as it was when performing lookups against other name resolution providers. I can't say with 100% certainty though I believe they were only referring to AD which I agreed with them does not require a following . when performing a nslookup. Either way, if a customer feels there is a problem whether there is or isn't they have a solution. The basic iRule also provides some with an example of how to modify DNS queries if a particular suffix is matched. I appreciate the response Stanislas!
Hi Steve,
your iRule does actually not rewrite the DNS request before sending it to your upstream DNS resolvers.
Your iRule is more or less just DNS reponding on behalt of the DNS Server with an empty DNS response (a DNS response without any RRs) for every DNS request ending with "domain.lab". This will cause nslookup to skip slightly faster through your systems DNS-Suffix list resulting in a faster total response time...
The provided rewrite part...
set queryName [string trimright {".demo.lab"} [DNS::question name] ] log local0. "My new question name: $queryName" DNS::return
... basically just extracts the
, performs a[DNS::question name]
and stores the new value it into the variable[string trimright]
. The$queryName
is then only be used for logging but not to overwrite the DNS query in progress. The empty DNS response is send by calling the$queryName
command (aka. you didn't defined any [DNS::answer] so the response will be empty) ...DNS::return
Additional Note: The command
is not able to slice a given[string trimright]
from the right side of the providedstring
. The command will instead slice each single character specified in theinput
from the rigth side of thechar-map
as often as needed until a character appears in theinput
which is not defined in theinput
. Beside of this, your example has flipped the order of thechar-map
andchar-map
causinginput
to remove the individual characters found in the[string trimright]
=char-map
from the hard coded[DNS::question name]
= "demo.lab".input
The shortcut of your iRule is basically this one:
when DNS_REQUEST { if { [DNS::question name] ends_with ".demo.lab" } then { Send an empty DNS response DNS::return } }
To rewrite DNS requests as proposed in your article you will need an iRule like this one...
when DNS_REQUEST { if { [DNS::question name] ends_with ".demo.lab" } then { Remove ".demo.lab" DNS-Suffix from the DNS query name and forward the request set queryName [string range [DNS::question name] 0 end-9] DNS::question name $queryName } }
Note: You may want to enable the debugging mode (aka.
) within an interactive nslookup session, to see the differences of the individual iRules.set d2
Cheers, Kai
- Steve_LyonsRet. Employee
Kai, thanks for the feedback! Your comments are always very beneficial to the entire community.