For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Disable DNS Express to allow recursion of a delegated sub-domain

Problem this snippet solves:

If you are using GTM to act both a authoritative slave with DNS Express and as a recursive cache, recursion will not work if a request is made for a delegated sub-domain if the parent domain exists in DNS Express. i.e. domain.com exists in DNS Express but has delegated the dev.domain.com sub-domain to a different set of name server. Any request to dev.domain.com will just get a referral rather than being recursed. This is because of the order of operations in GTM, https://support.f5.com/kb/en-us/solutions/public/14000/500/sol14510.html. Recursion is the very last process that could happen and since DNS Express makes an authoritative referral response no recursion will occur.

How to use this snippet:

To use this your listener and corresponding DNS profile need to have DNS Express configured and recursion enabled(cache). Then the iRule just needs to be attached to the listener.

Code :

when DNS_REQUEST {
#query DNS Express to look for a sub-domain delegation
set rrr [DNS::query dnsx [DNS::question name] [DNS::question type]]
#evaluate if the queried zone is defined in DNS Express
#empty response indicates DNS Express does not have the requested domain
#so we should exit and continue to recursion
if {$rrr equals "{} {} {}"}{return}
#check if DNS Express response is a delegated sub-domain referral
if { [lindex $rrr 0] equals "" && [DNS::type [lindex [lindex $rrr 1] 0]] equals "NS"} {
#no ANSWER was returned AND AUTHORITY is an NS record(not a SOA)
#this is a referral so we should disble DNS Express to allow for the subdomain to be recursed
DNS::disable dnsx
}
}

Tested this on version:

11.6
Published May 25, 2016
Version 1.0

6 Comments

  • Hey Guys,

    Glad I found this thread, I have the same issue. I have a zone that is created via BIND and I configured a DNS Express for that zone (test.com for example). And within that BIND config I have a delegation for security.test.com going to amazon DNS servers. I tried this irule but it looks like it's not working. my version is 14.1.4

    Thanks you! Hope you guys can help me. Ive been dealing for this issue for 6 months now 😄

  • Ok, we got the irule working with these modifications.

    when DNS_REQUEST {
    
      set rrr [DNS::query dnsx [DNS::question name] [DNS::question type]]
    
      set rname [lindex $rrr 0]
      set rtype [DNS::type [lindex $rrr 1]]
    
      log local0.debug "client=[IP::client_addr] name=$rname type=$rtype"
    
      if { $rname equals "" && $rtype equals "NS"} {
    
        log local0.debug "ns record detected"
        DNS::disable dnsx
    
      } elseif { [IP::addr [IP::client_addr] equals 192.168.0.0/24] } {
    
          pool /Common/ServerResolver
          log local0.debug "ServerResolver"
          return
    
      } else {
    
          pool /Common/UserResolver
          log local0.debug "UserResolver"
          return
    
      }
    
    
    }
    
  • I got it to work, but need to add additional functionality.

    Is it possible to add additional conditions to forward queries based on client ip to a specific dns pool after we have performed the recursive query for NS records of our DNS Express Zones?

    I can split this Irule into two parts (DNS Express Recursive Query Fix) and (Route based on source IP) independently. When I combine the irules it breaks. I have a feeling it has to do with the order in which the F5 processes the traffic. (CLIENT_ACCEPT before DNS_REQUEST)

    `when DNS_REQUEST {
        query DNS Express to look for a sub-domain delegation
        set rrr [DNS::query dnsx [DNS::question name] [DNS::question type]]
        evaluate if the queried zone is defined in DNS Express
        empty response indicates DNS Express does not have the requested domain
        check if DNS Express response is a delegated sub-domain referral
        if { [lindex $rrr 0] equals "" && [DNS::type [lindex [lindex $rrr 1] 0]] equals "NS"} {
        log local0.debug "ns record detected"
            no ANSWER was returned AND AUTHORITY is an NS record(not a SOA)
            this is a referral so we should disble DNS Express to allow for the subdomain to be recursed
            DNS::disable dnsx
            log local0.debug "Subdomain"
        } elseif { [IP::addr [IP::client_addr] equals 192.168.0.0/24] } {
            pool /Common/ServerResolver
            log local0.debug "ServerResolver"
            return
        } else {
            pool /Common/UserResolver
            log local0.debug "UserResolver"
            return
        }
    }`
    
  • I just verified this works all the way through 12.1.1, what does you listener and dns profile look like? Does recursion work for all other domains?

     

  • Hi Brad, I have this exact issue. :) I am testing using version 12.1.0. It doesn't appear that the irule is working. I set my logs to debug, but nothing helpful. I have you tested the irule on this version?