Technical Articles
F5 SMEs share good practice.
cancel
Showing results for 
Search instead for 
Did you mean: 
Steve_Lyons
Legacy Employee
Legacy Employee

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.

0151T000003d7HyQAI.jpg

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]"
}

0151T000003d7HzQAI.jpg

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.

0151T000003d7I0QAI.jpg

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.

0151T000003d7I1QAI.jpg

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      
    } 
}
Comments
Stanislas_Piro2
Cumulonimbus
Cumulonimbus

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_Lyons
Legacy Employee
Legacy 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!

 

Kai_Wilke
MVP
MVP

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

[DNS::question name]
, performs a
[string trimright]
and stores the new value it into the variable
$queryName
. 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
DNS::return
command (aka. you didn't defined any [DNS::answer] so the response will be empty) ...

Additional Note: The command

[string trimright]
is not able to slice a given
string
from the right side of the provided
input
. The command will instead slice each single character specified in the
char-map
from the rigth side of the
input
as often as needed until a character appears in the
input
which is not defined in the
char-map
. Beside of this, your example has flipped the order of the
char-map
and
input
causing
[string trimright]
to remove the individual characters found in the
char-map
=
[DNS::question name]
from the hard coded
input
= "demo.lab".

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.

set d2
) within an interactive nslookup session, to see the differences of the individual iRules.

Cheers, Kai

Steve_Lyons
Legacy Employee
Legacy Employee

Kai, thanks for the feedback! Your comments are always very beneficial to the entire community.

 

Version history
Last update:
‎05-Jun-2023 21:51
Updated by: