From: Ruben d'Arco Date: Tue, 4 Dec 2012 07:20:35 +0000 (+0100) Subject: RFC2136 documentation X-Git-Tag: rec-3.6.0-rc1~556^2~3^2~92 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=542a744ab99e2adf22275d961ced3da696dfae71;p=thirdparty%2Fpdns.git RFC2136 documentation Including ugly fix to allow me to write rfc2136! --- diff --git a/pdns/docs/pdns.xml b/pdns/docs/pdns.xml index ab42a2df2c..2ae70be770 100644 --- a/pdns/docs/pdns.xml +++ b/pdns/docs/pdns.xml @@ -8895,12 +8895,6 @@ doing. Stability is expected to return with 2.9.1, as are the binary builds. Zone2sql in PostgreSQL mode now populates the 'domains' table for easy master, slave or native replication support. - - - Ability to disable those annoying Windows DNS Dynamic Update messages from appearing in the log. See log-failed-updates - in . - - Ability to run on IPv6 transport only @@ -11715,8 +11709,7 @@ local0.err /var/log/pdns.err Logging truly kills performance as answering a question from the cache is an order of magnitude less work than logging a - line about it. Busy sites will prefer to turn log-dns-details and log-failed-updates - off. + line about it. Busy sites will prefer to turn log-dns-details off. Packet Cache @@ -13002,6 +12995,30 @@ sql> insert into domainmetadata (domain_id, kind, content) values (7,'ALLOW-AXFR + + ALLOW-2136-FROM + + + See + + + + + TSIG-ALLOW-2136 + + + See + + + + + SOA-EDIT-2136 + + + See + + + ALSO-NOTIFY @@ -13144,6 +13161,341 @@ sql> insert into domainmetadata (domain_id, kind, content) values (7,'ALLOW-AXFR + RFC2136 Support (Dynamic DNS Update) + Starting with the PowerDNS Authoritative Server 3.2, RFC2136 support is available. There are a number of items NOT supported: + + When operating as slave for a zone, forwarding to master is not supported. (Chapter 6 of RFC2136); + There is no support for GSS-TSIG and SIG (TSIG is supported); + WKS records are specifically mentioned in the RFC, we don't specifically care about WKS records; + Anything we forgot.... + + + The implementation requires the backend to support a number of new oparations. Currently, the following backends have been modified to support RFC2136: + + gmysql + gpgsql + gsqlite3 + + + Configuration options + There are two configuration parameters that can be used within the powerdns configuration file. + + + disable-rfc2136 [=yes] + + + A setting to enable/disable RFC2136 support completely. The default is yes, which means that RFC2136 updates are ignored by PowerDNS (no message is logged about this!). + Change the setting to disable-rfc2136=no to enable RFC2136 support. + + + + + allow-2136-from + + + A list of IP ranges that are allowed to perform updates on any domain. The default is 0.0.0.0/0, which means that all ranges are accepted. + Multiple entries can be used on this line (allow-2136-from=10.0.0.0/8 192.168.1.2/32). + The option can be left empty to disallow everything, this then should be used in combination with the allow-2136-from domainmetadata + setting per zone. + + + + + + + Per zone settings + For permissions, a number of per zone settings are available via the domain metadata (See ). + + + ALLOW-2136-FROM + + + This setting has the same function as described in the configuration options (See ). + Only one item is allowed per row, but multiple rows can be added. + An example: + +sql> select id from domains where name='powerdnssec.org'; +5 +sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘ALLOW-2136-FROM’,’10.0.0.0/8’); +sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘ALLOW-2136-FROM’,’192.168.1.2/32’); + + + This will allow 10.0.0.0/8 and 192.168.1.2/32 to send RFC2136 update messages for the powerdnssec.org domain. + + + + + TSIG-ALLOW-2136 + + + This setting allows you to set the TSIG key required to do an RFC2136 update. + An example: + + +sql> insert into tsigkeys (name, algorithm, secret) values ('test', 'hmac-md5', 'kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys='); +sql> select id from domains where name='powerdnssec.org'; +5 +sql> insert into domainmetadata (domain_id, kind, content) values (5, 'TSIG-ALLOW-2136', 'test'); + + + An example of how to use a TSIG key with the nsupdate command: + +nsupdate <<! +server <ip> <port> +zone powerdnssec.org +update add test1.powerdnssec.org 3600 A 192.168.1.1 +key test kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys= +send +! + + + If a TSIG key is set for the domain, it is required to be used for the update. + The TSIG is extra security on top of the ALLOW-2136-FROM setting. + If a TSIG key is set, the IP(-range) still needs to be allowed via ALLOW-2136-FROM. + + + + + SOA-EDIT-2136 + + This configures how the soa serial should be updated. See . + + + + + SOA Serial Updates + + After every update, the soa serial is updated as this is required by section 3.7 of RFC2136. + The behaviour is configurable via domainmetadata with the SOA-EDIT-2136 option. It has a number of + options listed below. If no behaviour is specified, DEFAULT is used. + + + RFC2136 (Section 3.6) defines some specific behaviour for updates of SOA records. Whenever the SOA record is updated + via the update message, the logic to change the SOA is not executed. + + + Powerdns will always use SOA-EDIT when serving SOA records, thus a query for the SOA record of + the recently update domain, might have an unexpected result due to a SOA-EDIT setting. + + + An example: + +sql> select id from domains where name='powerdnssec.org'; +5 +sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘SOA-EDIT-2136’,’INCREASE’); + + This will make the SOA Serial increase by one, for every succesful update. + + SOA-EDIT-2136 settings + These are the settings available for SOA-EDIT-2136. + + + DEFAULT + + + Generate a soa serial of YYYYMMDD01. If the current serial is lower than the generated serial, + use the generated serial. If the current serial is higher or equal to the generated serial, increase the + current serial by 1. + + + + + INCREASE + + Increase the current serial by 1. + + + + EPOCH + + Change the serial to the number of seconds since the EPOCH, aka unixtime. + + + + SOA-EDIT + + Change the serial to whatever SOA-EDIT would provide. See + + + + SOA-EDIT-INCREASE + + + Change the serial to whatever SOA-EDIT would provide. If what SOA-EDIT provides is lower than the current serial, + increase the current serial by 1. + + + + + + + RFC2136 How-to: Setup dyndns/rfc2136 with dhcpd + + RFC2136 is often used with DHCP to automatically provide a hostname whenever a new IP-address is assigned by the DHCP server. + This section describes how you can setup PowerDNS to receive RFC2136 updates from ISC's dhcpd (version 4.1.1-P1). + + Setting up dhcpd + + We're going to use a TSIG key for security. We're going to generate a key using the following command: + +dnssec-keygen -a hmac-md5 -b 128 -n USER dhcpdupdate + + This generates two files (Kdhcpdupdate.*.key and Kdhcpdupdate.*.private). You're interested in the .key file: + +# ls -l Kdhcp* +-rw------- 1 root root 53 Aug 26 19:29 Kdhcpdupdate.+157+20493.key +-rw------- 1 root root 165 Aug 26 19:29 Kdhcpdupdate.+157+20493.private + +# cat Kdhcpdupdate.+157+20493.key +dhcpdupdate. IN KEY 0 3 157 FYhvwsW1ZtFZqWzsMpqhbg== + + The important bits are the name of the key (dhcpdupdate) and the hash of the key (FYhvwsW1ZtFZqWzsMpqhbg== + + + Using the details from the key you've just generated. Add the following to your dhcpd.conf: + +key "dhcpdupdate" { + algorithm hmac-md5; + secret "FYhvwsW1ZtFZqWzsMpqhbg=="; +}; + + + + You must also tell dhcpd that you want dynamic dns to work, add the following section: + +ddns-updates on; +ddns-update-style interim; +update-static-leases on; + + This tells dhcpd to: + + Enable Dynamic DNS + Which style it must use (interim) + Update static leases as well + + For more information on this, consult the dhcpd.conf manual. + + + Per subnet, you also have to tell dhcpd which (reverse-)domain it should update and + on which master domain server it is running. + +ddns-domainname "powerdnssec.org"; +ddns-rev-domainname "in-addr.arpa."; + +zone powerdnssec.org { + primary 127.0.0.1; + key dhcpdupdate; +} + +zone 1.168.192.in-addr.arpa. { + primary 127.0.0.1; + key dhcpdupdate; +} + + This tells dhcpd a number of things: + + Which domain to use (ddns-domainname "powerdnssec.org";) + Which reverse-domain to use (dnssec-rev-domainname "in-addr.arpa.";) + For the zones, where the primary master is located (primary 127.0.0.1;) + Which TSIG key to use (key dhcpdupdate;). We defined the key earlier. + + + This concludes the changes that are needed to the dhcpd configuration file. + + Setting up PowerDNS + A number of small changes are needed to powerdns to make it accept dynamic updates from dhcpd. + + Enabled RFC2136 (dynamic update) support functionality in PowerDNS by adding the following to the + PowerDNS configuration file (pdns.conf). + +disable-rfc2136=no +allow-2136-from= + + This tells PowerDNS to: + + Enable RFC2136 support(disable-rfc21356) + Allow updates from NO ip-address (allow-2136-from=) + + + + We just told powerdns (via the configuration file) that we accept updates from nobody via the + allow-2136-from parameter. That's not very useful, so we're going to give permissions + per zone, via the domainmetadata table. + +sql> select id from domains where name='powerdnssec.org'; +5 +sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘ALLOW-2136-FROM’,’127.0.0.1’); + + This gives the ip '127.0.0.1' access to send update messages. Make sure you use the ip address of the machine that + runs dhcpd. + + + Another thing we want to do, is add TSIG security. This can only be done via the domainmetadata table: + +sql> insert into tsigkeys (name, algorithm, secret) values ('dhcpdupdate', 'hmac-md5', 'FYhvwsW1ZtFZqWzsMpqhbg=='); +sql> select id from domains where name='powerdnssec.org'; +5 +sql> insert into domainmetadata (domain_id, kind, content) values (5, 'TSIG-ALLOW-2136', 'dhcpdupdate'); +sql> select id from domains where name='1.168.192.in-addr.arpa'; +6 +sql> insert into domainmetadata (domain_id, kind, content) values (6, 'TSIG-ALLOW-2136', 'dhcpdupdate'); + + This will: + + Add the 'dhcpdupdate' key to our PowerDNSinstallation + Associate the domains with the given TSIG key + + + Restart PowerDNS and you should be ready to go! + + + + How it works + This is a short description of how RFC2136 (update) messages are processed by PowerDNS. + + + + The RFC2136 message is received. If it is TSIG signed, the TSIG is validated against the tsigkeys table. + If it is not valid, Refused is returned to the requestor. + + A check is performed on the zone to see if it is a valid zone. ServFail is returned when not valid. + The disable-rfc2136 setting is checked. Refused is returned when the setting is 'yes'. + + If the ALLOW-2136-FROM has a value (from both domainmetadata and the configuration file), a check on the value is performed. + If the requestor (sender of the update message) does not match the values in ALLOW-2136-FROM, Refused is returned. + + + If the message is TSIG signed, the TSIG keyname is compared with the TSIG keyname in domainmetadata. If they do not match, a Refused is send. + The TSIG-ALLOW-2136 domainmetadata setting is used to find which key belongs to the domain. + + The backends are queried to find the backend for the given domain. + If the powerdns instance is a slave for the given domain, NotImp is returned. + + A check is performed to make sure all updates/prerequisites are for the given zone. NotZone is returned if this is not the case. + + The transaction with the backend is started. + + The prerequisite checks are performed (section 3.2 of RFC2136). + If a check fails, the corresponding RCode is returned. No further processing will happen. + + + Per record in the update message, a the prescan checks are performed. If the prescan fails, the corresponding RCode is returned. + If the prescan for the record is correct, the actual update/delete/modify of the record is performed. + If the update fails (for whatever reason), ServFail is returned. + After changes to the records have been applied, the ordername and auth flag are set to make sure DNSSEC remains working. + The cache for that record is purged. + + + If there are records updated and the SOA record was not modified, the SOA serial is updated. See . + The cache for this record is purged. + + The transaction with the backend is commited. If this fails, ServFail is returned. + NoError is returned. + + + + + Recursion (only available from 1.99.8 and onwards, recursing component available since 2.9.5) @@ -15069,10 +15421,6 @@ To enable a Lua script for a particular slave zone, determine the domain_id for The port on which we listen. Only one port possible. - log-failed-updates=... - - If set to 'no', failed Windows Dynamic Updates will not be logged. - log-dns-details=... If set to 'no', informative-only DNS details will not even be sent to syslog, improving performance. Available from 2.5 @@ -21852,6 +22200,87 @@ static RandomLoader randomloader; + RFC2136 support + + To make your backend RFC2136 compatible, it needs to implement a number of new functions and functions already used for slave-operation. + The new functions are not RFC2136 specific and might be used for other update/remove functionality at a later stage. + +class DNSBackend { +public: + /* ... */ + virtual bool startTransaction(const string &qname, int id); + virtual bool commitTransaction(); + virtual bool abortTransaction(); + virtual bool feedRecord(const DNSResourceRecord &rr); + virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset) + virtual bool listSubZone(const string &zone, int domain_id); + /* ... */ +} + + + + + + + + + virtual bool startTransaction(const string &qname, int id); + + + See . Please note that this function now receives a negative number (-1), which indicates that + the current zone data should NOT be deleted. + + + + + virtual bool commitTransaction(); + + See . + + + + virtual bool abortTransaction(); + + See . Method is called when an exception is received. + + + + virtual bool feedRecord(const DNSResourceRecord &rr); + + See . Please keep in mind that the zone is not empty because startTransaction() was called different. + + + + virtual bool listSubZone(const string &name, int domain_id); + + + This method is needed for rectification of a zone after NS-records have been added. For DNSSEC, we need to know which records + are below the currently added record. + listSubZone() is used like list() which means PowerDNS will call get() + after this method. + The default SQL query looks something like this: + +// First %s is 'sub.zone.com', second %s is '*.sub.zone.com' +select content,ttl,prio,type,domain_id,name from records where (name='%s' OR name like '%s') and domain_id=%d + + The method is not only used when adding records, but also to correct ENT-records in powerdns. Make sure it returns every record in the tree + below the given record. + + + + + virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset); + + + This method should remove all the records with qname of type qt. qt + might also be ANY, which means all the records with that qname need to be removed. + After removal, the records in rrset must be added to the zone. rrset might be empty. + + + + + + Compiling PowerDNS Compiling PowerDNS on Unix