1 Dynamic DNS Update (RFC 2136)
2 =============================
4 Starting with the PowerDNS Authoritative Server 3.4.0, DNS update
5 support is available. There are a number of items NOT supported:
7 - There is no support for SIG (TSIG and GSS\*TSIG are supported);
8 - WKS records are specifically mentioned in the RFC, we don't
9 specifically care about WKS records;
10 - Anything we forgot....
12 The implementation requires the backend to support a number of new
13 operations. Currently, the following backends have been modified to
16 - :doc:`gmysql <backends/generic-mysql>`
17 - :doc:`gpgsql <backends/generic-postgresql>`
18 - :doc:`gsqlite3 <backends/generic-sqlite3>`
19 - :doc:`godbc <backends/generic-odbc>`
21 .. _dnsupdate-configuration-options:
26 There are two configuration parameters that can be used within the
27 powerdns configuration file.
32 A setting to enable/disable DNS update support completely. The default
33 is no, which means that DNS updates are ignored by PowerDNS (no message
34 is logged about this!). Change the setting to ``dnsupdate=yes`` to
35 enable DNS update support. Default is ``no``.
37 ``allow-dnsupdate-from``
38 ~~~~~~~~~~~~~~~~~~~~~~~~
40 A list of IP ranges that are allowed to perform updates on any domain.
41 The default is ``127.0.0.0/8``, which means that all loopback addresses are accepted.
42 Multiple entries can be used on this line
43 (``allow-dnsupdate-from=198.51.100.0/8 203.0.113.2/32``). The option can
44 be left empty to disallow everything, this then should be used in
45 combination with the ``ALLOW-DNSUPDATE-FROM`` :doc:`domain metadata <domainmetadata>` setting per
46 zone. Setting a range here and in ``ALLOW-DNSUPDATE-FROM`` enables updates
47 from either address range.
52 Tell PowerDNS to forward to the master server if the zone is configured
53 as slave. Masters are determined by the masters field in the domains
54 table. The default behaviour is enabled (yes), which means that it will
55 try to forward. In the processing of the update packet, the
56 ``allow-dnsupdate-from`` and ``TSIG-ALLOW-DNSUPDATE`` are processed
57 first, so those permissions apply before the ``forward-dnsupdate`` is
58 used. It will try all masters that you have configured until one is
61 .. _dnsupdate-lua-dnsupdate-policy-script:
63 ``lua-dnsupdate-policy-script``
64 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66 Use this Lua script containing function ``updatepolicy`` to validate
67 each update. This will ``TURN OFF`` all other
68 authorization methods, and you are expected to take care of everything
69 yourself. See :ref:`dnsupdate-update-policy` for details and
72 The semantics are that first a dynamic update has to be allowed either
73 by the global :ref:`setting-allow-dnsupdate-from` setting, or by a per-zone
74 ``ALLOW-DNSUPDATE-FROM`` metadata setting.
76 Secondly, if a zone has a ``TSIG-ALLOW-DNSUPDATE`` metadata setting, that
79 So to only allow dynamic DNS updates to a zone based on TSIG key, and
80 regardless of IP address, set :ref:`setting-allow-dnsupdate-from` to empty, set
81 ``ALLOW-DNSUPDATE-FROM`` to "0.0.0.0/0" and "::/0" and set the
82 ``TSIG-ALLOW-DNSUPDATE`` to the proper key name.
84 Further information can be found :ref:`below <dnsupdate-how-it-works>`.
86 .. _dnsupdate-metadata:
91 For permissions, a number of per zone settings are available via the
92 :doc:`domain metadata <domainmetadata>`.
94 .. _metadata-allow-dnsupdate-from:
99 This setting has the same function as described in the configuration
100 options (See :ref:`above <dnsupdate-configuration-options>`).
101 This will allow 198.51.100.0/8 and 203.0.113.2/32 to send DNS update
102 messages for the example.org domain::
104 pdnsutil set-meta example.org ALLOW-DNSUPDATE-FROM 198.51.100.0/8 203.0.113.2/32
106 .. _metadata-tsig-allow-dnsupdate:
111 This setting allows you to set the TSIG key required to do an DNS
112 update. If you have GSS-TSIG enabled, you can use Kerberos principals
113 here. Here is an example using :program:`pdnsutil` to create a key named
116 $ pdnsutil generate-tsig-key test hmac-sha512
117 Create new TSIG key test hmac-sha512 [base64-encoded key]
119 $ pdnsutil list-tsig-keys | grep test
120 test. hmac-sha512. [base64-encoded key]
122 This adds the key with the name `test` to the zone's metadata. Note, the
123 keys need to be added separately with `add-meta`, not as a comma or
124 space-separated list::
126 $ pdnsutil add-meta example.org TSIG-ALLOW-DNSUPDATE test
127 Set 'example.org' meta TSIG-ALLOW-DNSUPDATE = test
129 $ pdnsutil get-meta example.org TSIG-ALLOW-DNSUPDATE
130 TSIG-ALLOW-DNSUPDATE = test
132 This is an example of using the new `test` TSIG key with the :program:`nsupdate`
133 command (see the manpage for :program:`nsupdate` for full details)::
138 update add test1.example.org 3600 A 1.2.3.4
139 update add test1.example.org 3600 TXT "this is a test"
140 key hmac-sha512:test [base64-encoded key]
144 $ dig +noall +answer -t any test1.example.org @127.0.0.1
145 test1.example.org. 3600 IN A 1.2.3.4
146 test1.example.org. 3600 IN TXT "this is a test"
148 If any TSIG keys are listed in a zone's ``TSIG-ALLOW-DNSUPDATE`` metadata, one
149 of them is required for updates. If ``ALLOW-DNSUPDATE-FROM`` is also set,
150 both requirements need to be satisfied before an update will be accepted.
152 By default, an update can add, update or delete any resource records in
153 the zone. See :ref:`dnsupdate-update-policy` for finer-grained
154 control of what an update is allowed to do.
156 .. _metadata-forward-dnsupdate:
161 See :ref:`Configuration options <dnsupdate-configuration-options>` for what it does,
164 pdnsutil set-meta example.org FORWARD-DNSUPDATE 'yes'
166 The existence of the entry (even with an empty value) enables the forwarding.
167 This domain-specific setting is only useful when the configuration
168 option :ref:`setting-forward-dnsupdate` is set to 'no', as that will disable it
169 globally. Using the domainmetadata setting than allows you to enable it
172 .. _metadata-notify-dnsupdate:
177 Send a notification to all slave servers after every update. This will
178 speed up the propagation of changes and is very useful for acme
181 pdnsutil set-meta example.org NOTIFY-DNSUPDATE 1
183 .. _metadata-soa-edit-dnsupdate:
188 This configures how the soa serial should be updated. See
189 :ref:`below <dnsupdate-soa-serial-updates>`.
191 .. _dnsupdate-soa-serial-updates:
196 After every update, the soa serial is updated as this is required by
197 section 3.7 of :rfc:`2136`. The behaviour is configurable via domainmetadata
198 with the ``SOA-EDIT-DNSUPDATE`` option. It has a number of options listed
199 below. If no behaviour is specified, DEFAULT is used.
201 :rfc:`2136, Section 3.6 <2136#section-3.6>` defines some specific behaviour for updates of SOA
202 records. Whenever the SOA record is updated via the update message, the
203 logic to change the SOA is not executed.
206 Powerdns will always use :ref:`metadata-soa-edit` when serving SOA
207 records, thus a query for the SOA record of the recently updated domain,
208 might have an unexpected result due to a SOA-EDIT setting.
212 pdnsutil set-meta example.org SOA-EDIT-DNSUPDATE INCREASE
214 This will make the SOA Serial increase by one, for every successful
217 SOA-EDIT-DNSUPDATE settings
218 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
220 These are the settings available for **SOA-EDIT-DNSUPDATE**.
222 - DEFAULT: Generate a soa serial of YYYYMMDD01. If the current serial
223 is lower than the generated serial, use the generated serial. If the
224 current serial is higher or equal to the generated serial, increase
225 the current serial by 1.
226 - INCREASE: Increase the current serial by 1.
227 - EPOCH: Change the serial to the number of seconds since the EPOCH,
229 - SOA-EDIT: Change the serial to whatever SOA-EDIT would provide. See
230 :doc:`Domain metadata <domainmetadata>`
231 - SOA-EDIT-INCREASE: Change the serial to whatever SOA-EDIT would
232 provide. If what SOA-EDIT provides is lower than the current serial,
233 increase the current serial by 1.
234 Exception: with SOA-EDIT=INCEPTION-EPOCH, the serial is bumped to at
235 least the current EPOCH time.
237 DNS update How-to: Setup dyndns/rfc2136 with dhcpd
238 --------------------------------------------------
240 DNS update is often used with DHCP to automatically provide a hostname
241 whenever a new IP-address is assigned by the DHCP server. This section
242 describes how you can setup PowerDNS to receive DNS updates from ISC's
243 dhcpd (version 4.1.1-P1).
248 We're going to use a TSIG key for security. We're going to generate a
249 key using the following command:
251 .. code-block:: shell
253 dnssec-keygen -a hmac-md5 -b 128 -n USER dhcpdupdate
255 This generates two files (Kdhcpdupdate.*.key and
256 Kdhcpdupdate.*.private). You're interested in the .key file:
258 .. code-block:: shell
261 -rw------- 1 root root 53 Aug 26 19:29 Kdhcpdupdate.+157+20493.key
262 -rw------- 1 root root 165 Aug 26 19:29 Kdhcpdupdate.+157+20493.private
264 # cat Kdhcpdupdate.+157+20493.key
265 dhcpdupdate. IN KEY 0 3 157 FYhvwsW1ZtFZqWzsMpqhbg==
267 The important bits are the name of the key (**dhcpdupdate**) and the
268 hash of the key (**FYhvwsW1ZtFZqWzsMpqhbg==**
270 Using the details from the key you've just generated. Add the following
277 secret "FYhvwsW1ZtFZqWzsMpqhbg==";
280 You must also tell dhcpd that you want dynamic dns to work, add the
286 ddns-update-style interim;
287 update-static-leases on;
291 1. Enable Dynamic DNS
292 2. Which style it must use (interim)
293 3. Update static leases as well
295 For more information on this, consult the dhcpd.conf manual.
297 Per subnet, you also have to tell **dhcpd** which (reverse-)domain it
298 should update and on which master domain server it is running.
302 ddns-domainname "example.org";
303 ddns-rev-domainname "in-addr.arpa.";
310 zone 1.168.192.in-addr.arpa. {
315 This tells **dhcpd** a number of things:
317 1. Which domain to use (**ddns-domainname "example.org";**)
318 2. Which reverse-domain to use (**ddns-rev-domainname
320 3. For the zones, where the primary master is located (**primary
322 4. Which TSIG key to use (**key dhcpdupdate;**). We defined the key
325 This concludes the changes that are needed to the **dhcpd**
331 A number of small changes are needed to powerdns to make it accept
332 dynamic updates from **dhcpd**.
334 Enabled DNS update (:rfc:`2136`) support functionality in PowerDNS by adding
335 the following to the PowerDNS configuration file (pdns.conf).
340 allow-dnsupdate-from=
342 This tells PowerDNS to:
344 1. Enable DNS update support(:ref:`setting-dnsupdate`)
345 2. Allow updates from NO ip-address (":ref:`setting-allow-dnsupdate-from`\ =")
347 We just told powerdns (via the configuration file) that we accept
348 updates from nobody via the :ref:`setting-allow-dnsupdate-from`
349 parameter. That's not very useful, so we're going to give permissions
350 per zone (including the appropriate reverse zone), via the
351 domainmetadata table.
355 pdnsutil set-meta example.org ALLOW-DNSUPDATE-FROM 127.0.0.1
356 pdnsutil set-meta 1.168.192.in-addr.arpa ALLOW-DNSUPDATE-FROM 127.0.0.1
358 This gives the ip '127.0.0.1' access to send update messages. Make sure
359 you use the ip address of the machine that runs **dhcpd**.
361 Another thing we want to do, is add TSIG security. This can only be done
362 via the domainmetadata table:
366 pdnsutil import-tsig-key dhcpdupdate hmac-md5 FYhvwsW1ZtFZqWzsMpqhbg==
367 pdnsutil set-meta example.org TSIG-ALLOW-DNSUPDATE dhcpdupdate
368 pdnsutil set-meta 1.168.192.in-addr.arpa TSIG-ALLOW-DNSUPDATE dhcpdupdate
372 1. Add the 'dhcpdupdate' key to our PowerDNS installation
373 2. Associate the domains with the given TSIG key
375 Restart PowerDNS and you should be ready to go!
377 .. _dnsupdate-how-it-works:
382 This is a short description of how DNS update messages are processed by
385 1. The DNS update message is received. If it is TSIG signed, the TSIG
386 is validated against the tsigkeys table. If it is not valid, Refused
387 is returned to the requestor.
388 2. A check is performed on the zone to see if it is a valid zone.
389 ServFail is returned when not valid.
390 3. The **dnsupdate** setting is checked. Refused is returned when the
392 4. If update policy Lua script is provided then skip up to 7.
393 5. If the **ALLOW-DNSUPDATE-FROM** has a value (from both
394 domainmetadata and the configuration file), a check on the value is
395 performed. If the requestor (sender of the update message) does not
396 match the values in **ALLOW-DNSUPDATE-FROM**, Refused is returned.
397 6. If the message is TSIG signed, the TSIG keyname is compared with the
398 TSIG keyname in domainmetadata. If they do not match, a Refused is
399 send. The TSIG-ALLOW-DNSUPDATE domainmetadata setting is used to
400 find which key belongs to the domain.
401 7. The backends are queried to find the backend for the given domain.
402 8. If the domain is a slave domain, the **forward-dnsupdate** option
403 and domainmetadata settings are checked. If forwarding to a master
404 is enabled, the message is forward to the master. If that fails, the
405 next master is tried until all masters are tried. If all masters
406 fail, ServFail is returned. If a master succeeds, the result from
407 that master is returned.
408 9. A check is performed to make sure all updates/prerequisites are for
409 the given zone. NotZone is returned if this is not the case.
410 10. The transaction with the backend is started.
411 11. The prerequisite checks are performed (section 3.2 of :rfc:`2136 <2136#section-3.2>`). If a
412 check fails, the corresponding RCode is returned. No further
413 processing will happen.
414 12. Per record in the update message, a the prescan checks are
415 performed. If the prescan fails, the corresponding RCode is
416 returned. If the prescan for the record is correct, the actual
417 update/delete/modify of the record is performed. If the update fails
418 (for whatever reason), ServFail is returned. After changes to the
419 records have been applied, the ordername and auth flag are set to
420 make sure DNSSEC remains working. The cache for that record is
422 13. If there are records updated and the SOA record was not modified,
423 the SOA serial is updated. See :ref:`dnsupdate-soa-serial-updates`. The cache for this record is
425 14. The transaction with the backend is committed. If this fails,
426 ServFail is returned.
427 15. NoError is returned.
429 .. _dnsupdate-update-policy:
434 You can define a Lua script to handle DNS UPDATE message
435 authorization. The Lua script is to contain at least function called
436 ``updatepolicy`` which accepts one parameter. This parameter is an
437 object, containing all the information for the request. To permit
438 change, return true, otherwise return false. The script is called for
439 each record at a time and you can approve or reject any or all.
441 The object has following methods available:
443 - ``DNSName getQName()`` - name to update
444 - ``DNSName getZoneName()`` - zone name
445 - ``int getQType()`` - record type, it can be 255(ANY) for delete.
446 - ``ComboAddress getLocal()`` - local socket address
447 - ``ComboAddress getRemote()`` - remote socket address
448 - ``Netmask getRealRemote()`` - real remote address (or netmask if EDNS Subnet is used)
449 - ``DNSName getTsigName()`` - TSIG **key** name (you can assume it is validated here)
450 - ``string getPeerPrincipal()`` - Return peer principal name (``user@DOMAIN``,
451 ``service/machine.name@DOMAIN``, ``host/MACHINE$@DOMAIN``)
453 There are many same things available as in recursor Lua scripts, but
454 there is also ``resolve(qname, qtype)`` which returns array of records.
459 resolve("www.google.com", pdns.A)
461 You can use this to perform DNS lookups. If your resolver cannot find
462 your local records, then this will not find them either. In other words,
463 resolve does not perform local lookup.
465 Simple example script:
469 --- This script is not suitable for production use
471 function strpos (haystack, needle, offset)
472 local pattern = string.format("(%s)", needle)
473 local i = string.find (haystack, pattern, (offset or 0))
474 return (i ~= nil and i or false)
477 function updatepolicy(input)
478 princ = input:getPeerPrincipal()
485 if princ == "admin@DOMAIN" or input:getRemote():toString() == "192.168.1.1"
490 if (input:getQType() == pdns.A or input:getQType() == pdns.AAAA) and princ:sub(5,5) == '/' and strpos(princ, "@", 0) ~= false
492 i = strpos(princ, "@", 0)
493 if princ:sub(i) ~= "@DOMAIN"
497 hostname = princ:sub(6, i-1)
498 if input:getQName():toString() == hostname .. "." or input:getQName():toString() == hostname .. "." .. input:getZoneName():toString()
507 Additional updatepolicy example scripts can be found in our
508 `Wiki <https://github.com/PowerDNS/pdns/wiki/Lua-Examples-(Authoritative)>`__.