Ruby PowerDNS Pipe Backend Abstraction

powerdns_pipe is a Ruby library for developing PowerDNS pipe backend resolvers.

More information on the PowerDNS pipe backend can be found here.

Installation

sudo gem install powerdns_pipe

Documentation

PowerDNS::Pipe works by handling all the communication with PowerDNS for you. It handles the HELO and PING and stuff, but calls a block when a query or axfr request is made. The block has access to a question object which has information about the query from PowerDNS, and the answer method, which provides responses to PowerDNS.

PowerDNS::Pipe.new takes a hash of options, all are optional and the defaults are usually all you need:

:input

The IO object to read requests from PowerDNS. Defaults to STDIN

:output

The IO object to write responses to PowerDNS. Defaults to STDOUT

:err

The IO object to write debugging information. Defaults to STDERR, but is rarely used.

:version_range

A Range instance representing the Pipe protocol versions this backend supports. Defaults to 1..2

:banner

A string used in response to HELO requests from PowerDNS, is logged to the PowerDNS logs. Defaults to “Ruby PowerDNS::Pipe”

question object

The question object provides information about the query from the server:

name

The record being requested, e.g: www.example.com

qtype

The request type, such as A or MX. PowerDNS often uses ANY, to which you should return all valid records for the name and PowerDNS worries about returning the right one to the client. You must support this type.

qclass

The request class, this is always IN.

remote_ip_address

The IP address of the host making the dns request. You could use this to return different records for different geographic regions.

local_ip_address

The server IP address the request came into. Useful if your PowerDNS server is listening on multiple IPs and you want to consider that in your answers.

id

The id of the last answer to this question provided to PowerDNS by this backend for this. This might be useful to you to speed up subsequent lookups. -1 by default and can be ignored.

query?

Returns true if this is a normal Q query.

axfr?

Returns true if this is an axfr query.

answer method

The answer method is used to return records to PowerDNS. It can be called multiple times to return multiple records. Any exceptions are caught for you so garbage is not returned to PowerDNS. If you have nothing to return, just don’t call answer at all.

It takes the following options:

:name

The record name, e.g: www.example.com. Can usually just be set to question.name

:ttl

Time to Live in seconds. Defaults to 3600

:content

The content of the response, so an IP address string for A answers, or arbitrary text for TXT answers. For records with a priority (like MX records) put the priority first and then a space and then the content, e.g: 10 mail.example.com

:id

An integer id for this answer. PowerDNS will remember this and pass it back for subsequent requests for the same record. You might use this to pass around a primary key or something to speed up subsequent lookups. Defaults to -1 and can be ignored.

:class

The class of this answer, defaults to IN and shouldn’t be changed.

Basic example

Return an A record of 1.2.3.4 for all queries:

require 'powerdns_pipe'
PowerDNS::Pipe.new.run! do
  answer :name => question.name, :type => 'A', :ttl => 60, :content => '1.2.3.4'
end

Advanced example

Return the HTTP Server header as a TXT record for the host requested.

Example usage:

$ host -t txt www.ubuntu.com.example.com
ubuntu.com.example.com descriptive text "Apache/2.2.8 (Ubuntu) mod_python/3.3.1"

Code:

require 'powerdns_pipe'
require 'net/http'
re = Regexp.new("^(.+)\.example\.com$")
pipe = PowerDNS::Pipe.new :banner => 'HTTP Server Header TXT Pipe'
pipe.run! do
  if m = re.match(question.name)
    domain = m[1]
    case question.qtype
    when "TXT", "ANY"
      res = Net::HTTP.get_response(URI.parse("http://" + domain))
      answer :name => question.name , :type => 'TXT', :ttl => 3600, 
        :content => res['Server']
    end
  end
end

More Info

Author

John Leach ([email protected])

Copyright

Copyright © 2010 John Leach

License

MIT

Github

github.com/johnl/powerdns_pipe/tree/master

See also the ruby-pdns library which does things differently, with some limitations.