Table of Contents
This appendix lists several of the available backends in more detail
Table A.1. PipeBackend capabilities
Native | Yes |
Master | No |
Slave | No |
Superslave | No |
Autoserial | No |
Case | Depends |
DNSSEC | Partial, no delegation, no key storage |
Module name | pipe |
Launch name | pipe |
The PipeBackend allows for easy dynamic resolution based on a 'Coprocess' which can be written in any programming language that can read a question on standard input and answer on standard output.
To configure, the following settings are available:
Command to launch as backend. Mandatory.
Number of milliseconds to wait for an answer from the backend. If this time is ever exceeded, the backend is declared dead and a new process is spawned. Available since 2.7.
If set, only questions matching this regular expression are even sent to the backend. This makes sure that most of PowerDNS does not slow down if you you deploy a slow backend. A query for the A record of 'www.powerdns.com' would be presented to the regex as 'www.powerdns.com;A'. A matching regex would be '^www.powerdns.com;.*$'.
To match only ANY and A queries for www.powerdns.com, use '^www.powerdns.com;(A|ANY)$'. Please be aware that the single quotes used in this document should not be present in the configuration file, and only on the command line. In the configuration file, the previous example would be stored as: pipe-regex=^www.powerdns.com;(A|ANY)$
Available since 2.8.
This is the version of the question format that is sent to the co-process (pipe-command) for the pipe backend.
If not set the default pipebackend-abi-version is 1. When set to 2, the local-ip-address field is added after the remote-ip-address. (the local-ip-address refers to the IP address the question was received on). When set to 3, the real remote IP/subnet is added based on edns-subnet support (this also requires enabling 'edns-subnet-processing').
Questions come in over a file descriptor, by default standard input. Answers are sent out over another file descriptor, standard output by default. Questions and answers are terminated by single newline ('\n') characters.
PowerDNS sends out 'HELO\t1', indicating that it wants to speak the protocol as defined in this document, version 1. For abi-version 2 or 3, PowerDNS sends 'HELO\t2' or 'HELO\t3'. A PowerDNS Coprocess must then send out a banner, prefixed by 'OK\t', indicating it launched successfully. If it does not support the indicated version, it should respond with FAIL, but not exit. Suggested behaviour is to try and read a further line, and wait to be terminated.
Questions come in three forms and are prefixed by a tag indicating the type:
Regular queries
List requests, which mean that an entire zone should be listed
Check if the coprocess is functioning
The question format, for type Q questions:
pipebackend-abi-version = 1 [default]
Q qname qclass qtype id remote-ip-address
pipebackend-abi-version = 2
Q qname qclass qtype id remote-ip-address local-ip-address
pipebackend-abi-version = 3
Q qname qclass qtype id remote-ip-address local-ip-address edns-subnet-address
Fields are tab separated, and terminated with a single \n. The remote-ip-address is the IP address of the nameserver asking the question; the local-ip-address is the IP address on which the question was received.
Type is the tag above, qname is the domain the question is about. qclass is always 'IN' currently, denoting an INternet question. qtype is the kind of information desired, the record type, like A, CNAME or AAAA. id can be specified to help your backend find an answer if the id is already known from an earlier query. You can ignore it unless you want to support AXFR.
remote-ip-address is the ip-address of the nameserver asking the question. local-ip-address is the ip-address that was queried locally. edns-subnet-address is the actual client subnet as provided via edns-subnet support. Note that for the SOA query that precedes an AXFR, edns-subnet is always set to 0.0.0.0/0.
AXFR-queries look like this:
AXFR id
The id is gathered from the answer to a SOA query.
Each answer starts with a tag, possibly followed by a TAB and more data.
Indicating a successful line of DATA.
Indicating the end of an answer - no further data.
Indicating a lookup failure. Also serves as 'END'. No further data.
For specifying things that should be logged. Can only be sent after a query and before an END line. After the tab, the message to be logged.
So, letting it be known that there is no data consists of sending 'END' without anything else. The answer format (for abi-version 1 and 2):
DATA qname qclass qtype ttl id content
'content' is as specified in Chapter 22, Supported record types and their storage. For MX and SRV, content consists of the priority, followed by a tab, followed by the actual content.
A sample dialogue may look like this (note that in reality, almost all queries will actually be for the ANY qtype):
Q www.ds9a.nl IN CNAME -1 213.244.168.210 DATA www.ds9a.nl IN CNAME 3600 1 ws1.ds9a.nl END Q ws1.ds9a.nl IN CNAME -1 213.244.168.210 END Q wd1.ds9a.nl IN A -1 213.244.168.210 DATA ws1.ds9a.nl IN A 3600 1 1.2.3.4 DATA ws1.ds9a.nl IN A 3600 1 1.2.3.5 DATA ws1.ds9a.nl IN A 3600 1 1.2.3.6 END
This would correspond to a remote webserver 213.244.168.210 wanting to resolve the IP address of www.ds9a.nl, and PowerDNS traversing the CNAMEs to find the IP addresses of ws1.ds9a.nl Another dialogue might be:
Q ds9a.nl IN SOA -1 213.244.168.210 DATA ds9a.nl IN SOA 86400 1 ahu.ds9a.nl ... END AXFR 1 DATA ds9a.nl IN SOA 86400 1 ahu.ds9a.nl ... DATA ds9a.nl IN NS 86400 1 ns1.ds9a.nl DATA ds9a.nl IN NS 86400 1 ns2.ds9a.nl DATA ns1.ds9a.nl IN A 86400 1 213.244.168.210 DATA ns2.ds9a.nl IN A 86400 1 63.123.33.135 . . END
This is a typical zone transfer.
For abi-version 3, DATA-responses get two extra fields:
DATA scopebits auth qname qclass qtype ttl id content
scopebits indicates how many bits from the subnet provided in the question (originally from edns-subnet) were used in determining this answer. This can aid caching (although PowerDNS does not currently use this value). The auth field indicates whether this response is authoritative; this is for DNSSEC.
#!/usr/bin/perl -w # sample PowerDNS Coprocess backend # use strict; $|=1; # no buffering my $line=<>; chomp($line); unless($line eq "HELO\t1") { print "FAIL\n"; print STDERR "Received '$line'\n"; <>; exit; } print "OK Sample backend firing up\n"; # print our banner while(<>) { print STDERR "$$ Received: $_"; chomp(); my @arr=split(/\t/); if(@arr<6) { print "LOG PowerDNS sent unparseable line\n"; print "FAIL\n"; next; } my ($type,$qname,$qclass,$qtype,$id,$ip)=split(/\t/); if(($qtype eq "A" || $qtype eq "ANY") && $qname eq "webserver.example.com") { print STDERR "$$ Sent A records\n"; print "DATA $qname $qclass A 3600 -1 1.2.3.4\n"; print "DATA $qname $qclass A 3600 -1 1.2.3.5\n"; print "DATA $qname $qclass A 3600 -1 1.2.3.6\n"; } elsif(($qtype eq "CNAME" || $qtype eq "ANY") && $qname eq "www.example.com") { print STDERR "$$ Sent CNAME records\n"; print "DATA $qname $qclass CNAME 3600 -1 webserver.example.com\n"; } elsif($qtype eq "MBOXFW") { print STDERR "$$ Sent MBOXFW records\n"; print "DATA $qname $qclass MBOXFW 3600 -1 powerdns\@example.com\n"; } print STDERR "$$ End of data\n"; print "END\n"; }
Besides regular query types, the DNS also knows the 'ANY' query type. When a server receives a question for this ANY type, it should reply with all record types available.
Backends should therefore implement being able to answer 'ANY' queries in this way, and supply all record types they have when they receive such an 'ANY' query. This is reflected in the sample script above, which for every qtype answers if the type matches, or if the query is for 'ANY'.
However, since backends need to implement the ANY query anyhow, PowerDNS makes use of this. Since almost all DNS queries internally need to be translated first into a CNAME query and then into the actual query, possibly followed by a SOA or NS query (this is how DNS works internally), it makes sense for PowerDNS to speed this up, and just ask the ANY query of a backend.
When it has done so, it gets the data about SOA, CNAME and NS records in one go. This speeds things up tremendously.
The upshot of the above is that for any backend, including the PIPE backend, implementing the ANY query is NOT optional. And in fact, a backend may see almost exclusively ANY queries. This is not a bug.