Control recursive DNS queries

evt_aoievt_aoi Member
Hi all,
I'm wondering if/how in aFlex I might be able to allow or deny recursive DNS queries based off a source IP list. For example, if a remote IP not on the list has the recursive bit set in the query, the A10 will block the query outright instead of forwarding it to the DNS server.
Tagged:

Comments

  • dshindshin Member
    edited December 2015
    Using an aFleX per your DNS requirements will not work. The A10 aFleX scripting does not have the capability to store any prior request by the same source IP into memory. I would suggest to contact your regional SE to discuss and post a feature request if no other option available.

    Genard
  • evt_aoievt_aoi Member
    edited December 2015
    Maybe I am simplifying or not fully understanding, but I don't want to store previous requests in memory. I want to define something like a class list (F5 terminology) and have aFlex check requests against that list.
  • edited February 2016
    This aFlex can allow or deny recursive DNS queries based in one IPlist. This must have the source ip address.

    You will need create a class-list (in this example the class list name is HOST_LIST)

    You will need change the comments to do what you want, if you want to drop the connection you need change the comment by the command 'drop'.

    aFlex Code:

    when RULE_INIT {
    set ::HOSTLIST HOST_LIST ;# Class List used for hosts and configured in partition
    }

    when CLIENT_ACCEPTED {
    set ::IPADDR [IP::client_addr] ;# Ip address of client
    }

    when DNS_REQUEST {
    if { [DNS::header rd] == 1 } { # verify if is a recursive DNS
    if { not [CLASS::match $::IPADDR $::HOSTLIST ip] } {
    # do something if IP isn't in the class_list, could be drop
    } else {
    # do other thing if IP is in the class_list
    }
    } else {
    # do something if query is not recursive
    }
    }
  • evt_aoievt_aoi Member
    edited February 2016
    Thanks for the response. I ended up opening a ticket with A10 and they helped me create a script:
    when DNS_REQUEST {
            if {!([DNS::question name] equals ".")} {
            set fqdn .[DNS::question name]
            }
            if { ([CLASS::match $fqdn ends_with auth_dns]) and not ([CLASS::match [IP::client_addr] local-ips ip]) } {
            forward
            } elseif { [CLASS::match [IP::client_addr] local-ips ip] } {
            forward 
            } elseif { [DNS::header rd] equals "1" } {
                    if { not [CLASS::match [IP::client_addr] local-ips ip] } {
                    DNS::header qr 1
                    DNS::header rcode 5
                    DNS::return
                    }
            }
    }

    I ended up having to create two class-lists, one with IP addresses that are allowed to recurse and one with locally-hosted zone files:
    class-list auth_dns string 
     str .foo.com forward
     str .bar.com forward
    class-list local-ips  
     192.168.103.0 /24
     172.19.52.0 /24
     172.21.31.0 /24

    The locally hosted zone file list is required because by default, normal DNS queries have the RD bit set, so we needed to allow those requests through, even though they are locally hosted zone files.

    I also needed to create a pretty much exact copy for IPv6 addresses, too. I wasn't sure if I'd be able to add both v4 and v6 into the same aFlex script, given that the script is applied on a per-VIP basis.
Sign In or Register to comment.