Forum Discussion

Domwilko's avatar
Domwilko
Icon for Altocumulus rankAltocumulus
May 02, 2019

Simple iRule For DNS Intercept on Big IP DNS

Within our network we are using Big IP DNS for all of our DHCP clients, so all DNS requests come to the BIG IP DNS first for resolution. If there as no Wide IP setup for the DNS request, then the request is just forwarded to our Windows DNS servers for resolution. This all works fine; however due to various mergers we now have a situation whereby we have a FQDN is handled on the Windows DNS servers by use of conditional forwarders for that FQDN domain. Unfortunately, the DNS servers which are in another country are resolving the IP Address of this specific IP address (which is a NAT address) which we cannot route to from our country. The specific server which provides the services for this FQDN is actually based in our country and we can route to the 'real' IP address (but not the NAT), but for operational reasons, we need to use the conditional forwarders and the DNS resolution from the overseas DNS servers. So, all I want to do is put a very simple iRule on the F5 Big IP DNS which sits behind the FQDN, which I will present as a Wide IP, so that if any of the DHCP clients, which use the F5 Big IP DNS for DNS resolution does a lookup for that specific FQDN, then the iRule will return the 'real' IP address of the server and the DNS request will have been intercepted before it reaches the Windows DNS servers. I'm sure that this is something REALLY simple to achieve, but not being an iRule expert, I just cannot seem to get the syntax correct to make this happen. I'm sure this is probably a 3 line iRule, but I'm failing to find a simple example anywhere! All it needs to do is:

 

Create a Wide IP of "ABC.DOMAIN.PRIVATE"

 

and apply the simple iRule of:

 

if DNS lookup = "ABC.DOMAIN.PRIVATE" then return DNS response "123.123.123.123" else process requests as normal

 

Surely this is possible?

 

Can anyone help with an example iRule?

 

Any help appreciated.

 

Dom.

 

  • Do you have a cache enabled and selected in your DNS Profile? I've found that this is a requirement for this to work correctly.

     

  • Thanks for the quick response. What you have replied with is what I actually did, as it seemed to make sense to me; however, it's still not working. I have a LTM DNS VIP which load balancing to 2 Windows DNS servers. I've applied a DNS profile to the VIP and applied the iRule to the VIP, but if I do a NSLOOKUP for 'abc.domain.private' against the VIP address, which is where I'd expect the query to get intercepted by the iRule it just comes back "*** [10.222.42.4] can't find abc.domain.private: Non-existent domain".

     

    I also have GTM DNS listeners configured too, but I'm pointing the NSLOOKUP to the LTM DNS VIP. I've also tried implementing Youssef's GTM example, at a GTM level, but I get a syntax error with that.

     

    I was hoping to try and solve this myself, but it looks like time to reach out to our F5 SE. Thanks for attempting to help me. Much appreciated.

     

  • Hi R.Hickman,

     

    Please assume I know NOTHING about creating these iRules or Data Groups. Can you post an example of what the Data Group should look like to match my example? i.e. wanting abc.domain.private to resolve to 123.123.123.123?

     

    I've tried using @Youssef's examples both at a LTM and GTM level, but I still can't get them to work. It's so frustrating that something so simple should be so complicated. It would be also really helpful if there was a "Complete idiots guide" to getting started with iRules. I'm trying to learn, but most online resources assume you know some of the basics already.

     

    Any help appreciated.

     

    Dom

     

  • If you wanted to do a DataGroup - I took @youssef's code and modified it to use DG. Your DG would need to be the string format as well as exist before you create the irule. Works like a champ for me.

     

    when DNS_REQUEST {
    
    set type [DNS::question type]
    
    if {$type equals "A" } {
        set host [DNS::question name]
        if { [class match $host equals dns_List_DG ] } {
            DNS::answer clear
            DNS::answer insert "[DNS::question name]. 111 [DNS::question class] [DNS::question type] [class match -value $host equals dns_List_DG ]"
            DNS::return
        }
    }
    }
  • Hi,

    try this:

    when DNS_REQUEST {
    
    set type [DNS::question type]
    
    if {$type equals "A" } {
        set host [DNS::question name]
        if {$host contains "abc.domain.private" } {
            DNS::answer insert "[DNS::question name]. 111 [DNS::question class] [DNS::question type] 123.123.123.123"
            DNS::return
        }
    }
    
    }
    

    let me know if you need more details.

    regards