]> git.ipfire.org Git - thirdparty/pdns.git/blob - docs/dnsupdate.rst
Merge pull request #12769 from neilcook/patch-1
[thirdparty/pdns.git] / docs / dnsupdate.rst
1 Dynamic DNS Update (RFC 2136)
2 =============================
3
4 Starting with the PowerDNS Authoritative Server 3.4.0, DNS update
5 support is available. There are a number of items NOT supported:
6
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....
11
12 The implementation requires the backend to support a number of new
13 operations. Currently, the following backends have been modified to
14 support DNS update:
15
16 - :doc:`gmysql <backends/generic-mysql>`
17 - :doc:`gpgsql <backends/generic-postgresql>`
18 - :doc:`gsqlite3 <backends/generic-sqlite3>`
19 - :doc:`godbc <backends/generic-odbc>`
20
21 .. _dnsupdate-configuration-options:
22
23 Configuration options
24 ---------------------
25
26 There are two configuration parameters that can be used within the
27 powerdns configuration file.
28
29 ``dnsupdate``
30 ~~~~~~~~~~~~~
31
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``.
36
37 ``allow-dnsupdate-from``
38 ~~~~~~~~~~~~~~~~~~~~~~~~
39
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.
48
49 ``forward-dnsupdate``
50 ~~~~~~~~~~~~~~~~~~~~~
51
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
59 successful.
60
61 .. _dnsupdate-lua-dnsupdate-policy-script:
62
63 ``lua-dnsupdate-policy-script``
64 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65
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
70 examples.
71
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.
75
76 Secondly, if a zone has a ``TSIG-ALLOW-DNSUPDATE`` metadata setting, that
77 must match too.
78
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.
83
84 Further information can be found :ref:`below <dnsupdate-how-it-works>`.
85
86 .. _dnsupdate-metadata:
87
88 Per zone settings
89 -----------------
90
91 For permissions, a number of per zone settings are available via the
92 :doc:`domain metadata <domainmetadata>`.
93
94 .. _metadata-allow-dnsupdate-from:
95
96 ALLOW-DNSUPDATE-FROM
97 ~~~~~~~~~~~~~~~~~~~~
98
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::
103
104 pdnsutil set-meta example.org ALLOW-DNSUPDATE-FROM 198.51.100.0/8 203.0.113.2/32
105
106 .. _metadata-tsig-allow-dnsupdate:
107
108 TSIG-ALLOW-DNSUPDATE
109 ~~~~~~~~~~~~~~~~~~~~
110
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
114 `test`::
115
116 $ pdnsutil generate-tsig-key test hmac-sha512
117 Create new TSIG key test hmac-sha512 [base64-encoded key]
118
119 $ pdnsutil list-tsig-keys | grep test
120 test. hmac-sha512. [base64-encoded key]
121
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::
125
126 $ pdnsutil add-meta example.org TSIG-ALLOW-DNSUPDATE test
127 Set 'example.org' meta TSIG-ALLOW-DNSUPDATE = test
128
129 $ pdnsutil get-meta example.org TSIG-ALLOW-DNSUPDATE
130 TSIG-ALLOW-DNSUPDATE = test
131
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)::
134
135 $ nsupdate <<!
136 server 127.0.0.1 53
137 zone example.org
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]
141 send
142 !
143
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"
147
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.
151
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.
155
156 .. _metadata-forward-dnsupdate:
157
158 FORWARD-DNSUPDATE
159 ~~~~~~~~~~~~~~~~~
160
161 See :ref:`Configuration options <dnsupdate-configuration-options>` for what it does,
162 but per domain::
163
164 pdnsutil set-meta example.org FORWARD-DNSUPDATE 'yes'
165
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
170 per domain.
171
172 .. _metadata-notify-dnsupdate:
173
174 NOTIFY-DNSUPDATE
175 ~~~~~~~~~~~~~~~~
176
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
179 verification::
180
181 pdnsutil set-meta example.org NOTIFY-DNSUPDATE 1
182
183 .. _metadata-soa-edit-dnsupdate:
184
185 SOA-EDIT-DNSUPDATE
186 ~~~~~~~~~~~~~~~~~~
187
188 This configures how the soa serial should be updated. See
189 :ref:`below <dnsupdate-soa-serial-updates>`.
190
191 .. _dnsupdate-soa-serial-updates:
192
193 SOA Serial Updates
194 ------------------
195
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.
200
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.
204
205 .. note::
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.
209
210 An example::
211
212 pdnsutil set-meta example.org SOA-EDIT-DNSUPDATE INCREASE
213
214 This will make the SOA Serial increase by one, for every successful
215 update.
216
217 SOA-EDIT-DNSUPDATE settings
218 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
219
220 These are the settings available for **SOA-EDIT-DNSUPDATE**.
221
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,
228 aka unixtime.
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.
236
237 DNS update How-to: Setup dyndns/rfc2136 with dhcpd
238 --------------------------------------------------
239
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).
244
245 Setting up dhcpd
246 ~~~~~~~~~~~~~~~~
247
248 We're going to use a TSIG key for security. We're going to generate a
249 key using the following command:
250
251 .. code-block:: shell
252
253 dnssec-keygen -a hmac-md5 -b 128 -n USER dhcpdupdate
254
255 This generates two files (Kdhcpdupdate.*.key and
256 Kdhcpdupdate.*.private). You're interested in the .key file:
257
258 .. code-block:: shell
259
260 # ls -l Kdhcp*
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
263
264 # cat Kdhcpdupdate.+157+20493.key
265 dhcpdupdate. IN KEY 0 3 157 FYhvwsW1ZtFZqWzsMpqhbg==
266
267 The important bits are the name of the key (**dhcpdupdate**) and the
268 hash of the key (**FYhvwsW1ZtFZqWzsMpqhbg==**
269
270 Using the details from the key you've just generated. Add the following
271 to your dhcpd.conf:
272
273 ::
274
275 key "dhcpdupdate" {
276 algorithm hmac-md5;
277 secret "FYhvwsW1ZtFZqWzsMpqhbg==";
278 };
279
280 You must also tell dhcpd that you want dynamic dns to work, add the
281 following section:
282
283 ::
284
285 ddns-updates on;
286 ddns-update-style interim;
287 update-static-leases on;
288
289 This tells dhcpd to:
290
291 1. Enable Dynamic DNS
292 2. Which style it must use (interim)
293 3. Update static leases as well
294
295 For more information on this, consult the dhcpd.conf manual.
296
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.
299
300 ::
301
302 ddns-domainname "example.org";
303 ddns-rev-domainname "in-addr.arpa.";
304
305 zone example.org {
306 primary 127.0.0.1;
307 key dhcpdupdate;
308 }
309
310 zone 1.168.192.in-addr.arpa. {
311 primary 127.0.0.1;
312 key dhcpdupdate;
313 }
314
315 This tells **dhcpd** a number of things:
316
317 1. Which domain to use (**ddns-domainname "example.org";**)
318 2. Which reverse-domain to use (**ddns-rev-domainname
319 "in-addr.arpa.";**)
320 3. For the zones, where the primary master is located (**primary
321 127.0.0.1;**)
322 4. Which TSIG key to use (**key dhcpdupdate;**). We defined the key
323 earlier.
324
325 This concludes the changes that are needed to the **dhcpd**
326 configuration file.
327
328 Setting up PowerDNS
329 ~~~~~~~~~~~~~~~~~~~
330
331 A number of small changes are needed to powerdns to make it accept
332 dynamic updates from **dhcpd**.
333
334 Enabled DNS update (:rfc:`2136`) support functionality in PowerDNS by adding
335 the following to the PowerDNS configuration file (pdns.conf).
336
337 .. code-block:: ini
338
339 dnsupdate=yes
340 allow-dnsupdate-from=
341
342 This tells PowerDNS to:
343
344 1. Enable DNS update support(:ref:`setting-dnsupdate`)
345 2. Allow updates from NO ip-address (":ref:`setting-allow-dnsupdate-from`\ =")
346
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.
352
353 ::
354
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
357
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**.
360
361 Another thing we want to do, is add TSIG security. This can only be done
362 via the domainmetadata table:
363
364 ::
365
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
369
370 This will:
371
372 1. Add the 'dhcpdupdate' key to our PowerDNS installation
373 2. Associate the domains with the given TSIG key
374
375 Restart PowerDNS and you should be ready to go!
376
377 .. _dnsupdate-how-it-works:
378
379 How it works
380 ------------
381
382 This is a short description of how DNS update messages are processed by
383 PowerDNS.
384
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
391 setting is 'no'.
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
421 purged.
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
424 purged.
425 14. The transaction with the backend is committed. If this fails,
426 ServFail is returned.
427 15. NoError is returned.
428
429 .. _dnsupdate-update-policy:
430
431 Update policy
432 -------------
433
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.
440
441 The object has following methods available:
442
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``)
452
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.
455 Example:
456
457 .. code-block:: lua
458
459 resolve("www.google.com", pdns.A)
460
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.
464
465 Simple example script:
466
467 .. code-block:: lua
468
469 --- This script is not suitable for production use
470
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)
475 end
476
477 function updatepolicy(input)
478 princ = input:getPeerPrincipal()
479
480 if princ == ""
481 then
482 return false
483 end
484
485 if princ == "admin@DOMAIN" or input:getRemote():toString() == "192.168.1.1"
486 then
487 return true
488 end
489
490 if (input:getQType() == pdns.A or input:getQType() == pdns.AAAA) and princ:sub(5,5) == '/' and strpos(princ, "@", 0) ~= false
491 then
492 i = strpos(princ, "@", 0)
493 if princ:sub(i) ~= "@DOMAIN"
494 then
495 return false
496 end
497 hostname = princ:sub(6, i-1)
498 if input:getQName():toString() == hostname .. "." or input:getQName():toString() == hostname .. "." .. input:getZoneName():toString()
499 then
500 return true
501 end
502 end
503
504 return false
505 end
506
507 Additional updatepolicy example scripts can be found in our
508 `Wiki <https://github.com/PowerDNS/pdns/wiki/Lua-Examples-(Authoritative)>`__.