vADC Docs

HowTo: Implement a simple DNS resolver using libDNS.rts

by on ‎04-10-2013 08:30 AM - edited on ‎05-13-2016 05:35 AM by PaulWallace (1,701 Views)

This article uses the libDNS.rts trafficscript library as described in libDNS.rts: Interrogating and managing DNS traffic in Stingray.

 

In this example, we intercept DNS requests and respond directly for known A records.

 

The request rule

 

import libDNS.rts as dns;

# Map domain names to lists of IP addresses they should resolve to

$ipAddresses = [

   "dev1.ha.company.internal." => [ "10.1.1.1", "10.2.1.1" ],

   "dev2.ha.company.internal." => [ "10.1.1.2", "10.2.1.2" ]

];

$packet = dns.convertRawDataToObject( request.get(), "udp" );

# Ignore unparsable packets and query responses to avoid

# attacks like the one described in CVE-2004-0789.

if( hash.count( $packet ) == 0 || $packet["qr"] == "1" ) {

   break;

}

$host = $packet["question"]["host"];


if( hash.contains( $ipAddresses, $host )) {

   foreach( $ip in $ipAddresses[$host] ) {

      $packet = dns.addResponse($packet, "answer", $host, $ip, "A", "IN", "60", []);

   }

   $packet["aa"] = "1"; # Make the answer authorative

} else {

   $packet["rcode"] = "0011"; # Set NXDOMAIN error

}

$packet["qr"] = "1"; # Changes the packet to a response

$packet["ra"] = "1"; # Pretend that we support recursion

request.sendResponse( dns.convertObjectToRawData($packet, "udp"));
Comments
by kalipinde
on ‎09-20-2017 07:01 AM

Hi Paul,

 

 This looks great and I'm currently testing this out as it might help me out with a geolocating issue.

 

 Is there a way to use libDNS.rt to send all DNS requests back to the client using one DNS server pool (my internal servers) but if the client is requesting a specific domain name such as "example.differentdomain.com" that we can send this DNS request to a different server pool (a public DNS server)?

 

Regards.

 

Kal.

 

 

by mbodding
on ‎09-22-2017 07:05 AM

Hi Kal,

 

Sure that's quite simple. You would just parse the packet and pull out the host, check to see if the request is in a domain which should be handled by your internal servers, and if not pool.use() to send the packout out to a public resolver. Something like:

 

import libDNS.rts as dns;

$mydomains = [ "foo.com", "bar.net"];

$packet = dns.convertRawDataToObject( request.get(), "udp" );
if( hash.count( $packet ) == 0 || $packet["qr"] == "1" ) {
   break;
}
$host = $packet["question"]["host"];

$local=0;
foreach ( $name in $mydomains ) {
  if (string.endswith($host, $name)) {
    $local=1;
  }
}

if ( $local == 0 ) {
# use public DNS pool.use("public-dns"); }

# fall through to internal DNS pool.

Cheers,

Mark

by kalipinde
on ‎09-22-2017 07:12 AM

Hi Mark,

 

 Thank you so much for the quick response. I will test it out!

 

Regards,

 

Kal.

Contributors