random technical thoughts from the Nominet technical team

Some examples of dnsruby in action

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...
Posted by alexd on May 19th, 2009

In this post, I’d like to look at how to use dnsruby to accomplish some common tasks.

Getting started

To follow these examples, you’ll need to install dnsruby :

$ gem install dnsruby

I’ll run these examples in Ruby’s interactive shell :

$ irb

First, I need to include Dnsruby :

>> require 'rubygems'
>> require 'dnsruby'
>> include Dnsruby

Now I’ll load the system’s default resolvers :

>> res = Resolver.new

And display them :

>> res.single_resolvers.each {|s| print "Server address : #{s.server}n"}
Server address : 192.168.1.1
Server address : 192.168.2.2

Now I’ll use them to run a couple of queries :

>> ret = res.query("example.com") # Defaults to A record
>> print ret.answer
example.com.	172789	IN	A	208.77.188.166=> nil
>> res.query("example.com", "MX") # Query the MX record

This time, I’ll use some defined nameservers :

>> res = Resolver.new({:nameserver => ["ns1.nic.uk",
        "ns1.nic.uk"]})

Asynchronous Queries

To run an asynchronous query, I’ll define a Queue to hold the results, and then prepare the query. This time, I’ll construct a Message to hold the query data, and set the RD (recursion desired) bit on the header to 0 :

>> queue = Queue.new
>> m = Message.new("co.uk", Types.NS)
>> m.header.rd = false
>> message_id = res.send_async(m, queue, 1)

Now my code can get on with other tasks, until I’m ready to get the response. Queue#pop is a blocking call, but you can check if it is empty using Queue#empty?.

>> id, reply, error = queue.pop # id == message_id

The [id, reply, error] tuple is popped off the queue. The id identifies which query the response is for (it should match the id returned by the send_async call), reply holds the best response that was received, and any errors will be held in error (which should be nil in this example).

Message Options

Now I’ll ask for a Message to be sent without checking (or the response being stored in) the cache. I’ll also make sure that no DNSSEC validation is performed on the response :

>> m.do_caching = false
>> m.do_validation = false
>> res.send_message(m)

I can ask for a Message to be sent without any pre- or post-processing. No EDNS headers are applied, the header flags are not adjusted, and no caching or validation is performed. This method is most useful for tools authors :

>> res.send_plain_message(Message.new("nic.uk"))

TSIG and Dynamic Updates

I can also use TSIG signatures to communicate securely with a resolver. In this example, I’ll use TSIG to sign a dynamic update. First, I’ll have to define the server to use, and the TSIG key to speak to it with :

>> res = Dnsruby::Resolver.new("ns0.validation-test-servers.nominet.org.uk")
>> res.dnssec = false
>> tsig = Dnsruby::RR.create({
        :name        => "rubytsig",
        :type        => "TSIG",
         :key         => "8n6gugn4aJ7MazyNlMccGKH1WxD2B3UvN/O/RA6iBupO2/03u9CTa3Ewz3gBWTSBCH3crY4Kk+tigNdeJBAvrw==",
      })

Now I’ll create the dynamic update packet :

>> update = Dnsruby::Update.new("validation-test-servers.nominet.org.uk")
>> # ... add stuff to the update
>> update.absent("notthere.update.validation-test-servers.nominet.org.uk", 'TXT')

And apply the TSIG signature and send the message :

>> tsig.apply(update)
>> response = res.send_message(update)
>> print "TSIG response was verified? : #{response.verified?}n"

I could also have configured the Resolver to sign *all* packets with TSIG :

>> res.tsig=tsig.name, tsig.key

Recursive Queries

In addition to defining nameservers to do recursive queries on my behalf, I can also get Dnsruby to query recursively from the root. A static cache is built up, so the more client queries that are run, the less packets need be sent per client query.

>> rec = Recursor.new
>> ret = rec.query("uk-dnssec.nic.uk", "NS")

In my next article, I’ll look at how use Dnsruby with DNSSEC.

One Response

  1. techblog » Blog Archive » Examples of using Dnsruby with DNSSEC Says:

    […] this post, I’d like to look at how to use Dnsruby with DNSSEC. As before, I’ll run these examples in irb, and assume that you’ve included Dnsruby […]

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Recent Posts

Highest Rated

Categories

Archives

Meta: