powerdns_pipe is a Ruby library for developing PowerDNS pipe backend resolvers.
More information on the PowerDNS pipe backend can be found here.
sudo gem install powerdns_pipe
PowerDNS::Pipe works by handling all the communication with PowerDNS for you. It handles the
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:
The IO object to read requests from PowerDNS. Defaults to STDIN
The IO object to write responses to PowerDNS. Defaults to STDOUT
The IO object to write debugging information. Defaults to STDERR, but is rarely used.
A Range instance representing the Pipe protocol versions this backend supports. Defaults to 1..2
A string used in response to HELO requests from PowerDNS, is logged to the PowerDNS logs. Defaults to “Ruby PowerDNS::Pipe”
question object provides information about the query from the server:
The record being requested, e.g:
The request type, such as
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.
The request class, this is always
The IP address of the host making the dns request. You could use this to return different records for different geographic regions.
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.
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.
Returns true if this is a normal Q query.
Returns true if this is an axfr query.
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:
The record name, e.g:
www.example.com. Can usually just be set to
Time to Live in seconds. Defaults to 3600
The content of the response, so an IP address string for
Aanswers, or arbitrary text for
TXTanswers. For records with a priority (like MX records) put the priority first and then a tab and then the content, e.g:
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.
The class of this answer, defaults to
INand shouldn't be changed.
A record of
18.104.22.168 for all queries:
require 'powerdns_pipe' PowerDNS::Pipe.new.run! do answer :name => question.name, :type => 'A', :ttl => 60, :content => '22.214.171.124' end
Return the HTTP Server header as a TXT record for the host requested.
$ host -t txt www.ubuntu.com.example.com ubuntu.com.example.com descriptive text "Apache/2.2.8 (Ubuntu) mod_python/3.3.1"
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 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
John Leach (email@example.com)
Copyright © 2010-2018 John Leach
See also the ruby-pdns library which does things differently, with some limitations.