]> git.ipfire.org Git - thirdparty/pdns.git/blob - docs/dnsupdate.rst
Merge pull request #7677 from rgacogne/dnsdist-logging-facility
[thirdparty/pdns.git] / docs / dnsupdate.rst
1 Dynamic DNS Update (RFC2136)
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 GSS\*TSIG and SIG (TSIG is 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:`goracle <backends/generic-oracle>`
20 - :doc:`godbc <backends/generic-odbc>`
21
22 .. _dnsupdate-configuration-options:
23
24 Configuration options
25 ---------------------
26
27 There are two configuration parameters that can be used within the
28 powerdns configuration file.
29
30 ``dnsupdate``
31 ~~~~~~~~~~~~~
32
33 A setting to enable/disable DNS update support completely. The default
34 is no, which means that DNS updates are ignored by PowerDNS (no message
35 is logged about this!). Change the setting to ``dnsupdate=yes`` to
36 enable DNS update support. Default is ``no``.
37
38 ``allow-dnsupdate-from``
39 ~~~~~~~~~~~~~~~~~~~~~~~~
40
41 A list of IP ranges that are allowed to perform updates on any domain.
42 The default is ``127.0.0.0/8``, which means that all loopback addresses are accepted.
43 Multiple entries can be used on this line
44 (``allow-dnsupdate-from=198.51.100.0/8 203.0.113.2/32``). The option can
45 be left empty to disallow everything, this then should be used in
46 combination with the ``ALLOW-DNSUPDATE-FROM`` :doc:`domain metadata <domainmetadata>` setting per
47 zone. Setting a range here and in ``ALLOW-DNSUPDATE-FROM`` enables updates
48 from either address range.
49
50 ``forward-dnsupdate``
51 ~~~~~~~~~~~~~~~~~~~~~
52
53 Tell PowerDNS to forward to the master server if the zone is configured
54 as slave. Masters are determined by the masters field in the domains
55 table. The default behaviour is enabled (yes), which means that it will
56 try to forward. In the processing of the update packet, the
57 ``allow-dnsupdate-from`` and ``TSIG-ALLOW-DNSUPDATE`` are processed
58 first, so those permissions apply before the ``forward-dnsupdate`` is
59 used. It will try all masters that you have configured until one is
60 successful.
61
62 .. _dnsupdate-lua-dnsupdate-policy-script:
63
64 ``lua-dnsupdate-policy-script``
65 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
66
67 Use this Lua script containing function ``updatepolicy`` to validate
68 each update. This will ``TURN OFF`` all other
69 authorization methods, and you are expected to take care of everything
70 yourself. See :ref:`dnsupdate-update-policy` for details and
71 examples.
72
73 The semantics are that first a dynamic update has to be allowed either
74 by the global :ref:`setting-allow-dnsupdate-from` setting, or by a per-zone
75 ``ALLOW-DNSUPDATE-FROM`` metadata setting.
76
77 Secondly, if a zone has a ``TSIG-ALLOW-DNSUPDATE`` metadata setting, that
78 must match too.
79
80 So to only allow dynamic DNS updates to a zone based on TSIG key, and
81 regardless of IP address, set :ref:`setting-allow-dnsupdate-from` to empty, set
82 ``ALLOW-DNSUPDATE-FROM`` to "0.0.0.0/0" and "::/0" and set the
83 ``TSIG-ALLOW-DNSUPDATE`` to the proper key name.
84
85 Further information can be found :ref:`below <dnsupdate-how-it-works>`.
86
87 .. _dnsupdate-metadata:
88
89 Per zone settings
90 -----------------
91
92 For permissions, a number of per zone settings are available via the
93 :doc:`domain metadata `<domainmetadata>`.
94
95 .. _metadata-allow-dnsupdate-from:
96
97 ALLOW-DNSUPDATE-FROM
98 ~~~~~~~~~~~~~~~~~~~~
99
100 This setting has the same function as described in the configuration
101 options (See ref:`above <dnsupdate-configuration-options>`). Only one item is
102 allowed per row, but multiple rows can be added. An example:
103
104 ::
105
106 sql> select id from domains where name='example.org';
107 5
108 sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘ALLOW-DNSUPDATE-FROM’,’198.51.100.0/8’);
109 sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘ALLOW-DNSUPDATE-FROM’,’203.0.113.2/32’);
110
111 This will allow 198.51.100.0/8 and 203.0.113.2/32 to send DNS update
112 messages for the example.org domain.
113
114 .. _metadata-tsig-allow-dnsupdate:
115
116 TSIG-ALLOW-DNSUPDATE
117 ~~~~~~~~~~~~~~~~~~~~
118
119 This setting allows you to set the TSIG key required to do an DNS
120 update. If you have GSS-TSIG enabled, you can use Kerberos principals
121 here. An example, using :program:`pdnsutil` to create the key:
122
123 ::
124
125 pdnsutil generate-tsig-key test hmac-md5
126 Create new TSIG key test hmac-md5 kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys=
127
128 sql> insert into tsigkeys (name, algorithm, secret) values ('test', 'hmac-md5', 'kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys=');
129 sql> select id from domains where name='example.org';
130 5
131 sql> insert into domainmetadata (domain_id, kind, content) values (5, 'TSIG-ALLOW-DNSUPDATE', 'test');
132
133 An example of how to use a TSIG key with the :program:`nsupdate` command:
134
135 ::
136
137 nsupdate <<!
138 server <ip> <port>
139 zone example.org
140 update add test1.example.org 3600 A 203.0.113.1
141 key test kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys=
142 send
143 !
144
145 If a TSIG key is set for the domain, it is required to be used for the
146 update. The TSIG is an alternative means of securing updates, instead of using the
147 ``ALLOW-DNSUPDATE-FROM`` setting. If a TSIG key is set, and if ``ALLOW-DNSUPDATE-FROM`` is set,
148 the IP(-range) of the updater still needs to be allowed via ``ALLOW-DNSUPDATE-FROM``.
149
150 .. _metadata-forward-dnsupdate:
151
152 FORWARD-DNSUPDATE
153 ~~~~~~~~~~~~~~~~~
154
155 See `Configuration options <dnsupdate-configuration-options>` for what it does,
156 but per domain.
157
158 ::
159
160 sql> select id from domains where name='example.org';
161 5
162 sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘FORWARD-DNSUPDATE’,’’);
163
164 There is no content, the existence of the entry enables the forwarding.
165 This domain-specific setting is only useful when the configuration
166 option :ref:`setting-forward-dnsupdate` is set to 'no', as that will disable it
167 globally. Using the domainmetadata setting than allows you to enable it
168 per domain.
169
170 .. _metadata-notify-dnsupdate:
171
172 NOTIFY-DNSUPDATE
173 ~~~~~~~~~~~~~~~~
174
175 Send a notification to all slave servers after every update. This will
176 speed up the propagation of changes and is very useful for acme
177 verification.
178
179 ::
180
181 sql> select id from domains where name='example.org';
182 5
183 sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘NOTIFY-DNSUPDATE’,’1’);
184
185 .. _metadata-soa-edit-dnsupdate:
186
187 SOA-EDIT-DNSUPDATE
188 ~~~~~~~~~~~~~~~~~~
189
190 This configures how the soa serial should be updated. See
191 :ref:`below <dnsupdate-soa-serial-updates>`.
192
193 .. _dnsupdate-soa-serial-updates:
194
195 SOA Serial Updates
196 ------------------
197
198 After every update, the soa serial is updated as this is required by
199 section 3.7 of :rfc:`2136`. The behaviour is configurable via domainmetadata
200 with the ``SOA-EDIT-DNSUPDATE`` option. It has a number of options listed
201 below. If no behaviour is specified, DEFAULT is used.
202
203 :rfc:`2136, Section 3.6 <2136#section-3.6>` defines some specific behaviour for updates of SOA
204 records. Whenever the SOA record is updated via the update message, the
205 logic to change the SOA is not executed.
206
207 .. note::
208 Powerdns will always use :ref:`metadata-soa-edit` when serving SOA
209 records, thus a query for the SOA record of the recently update domain,
210 might have an unexpected result due to a SOA-EDIT setting.
211
212 An example:
213
214 ::
215
216 sql> select id from domains where name='example.org';
217 5
218 sql> insert into domainmetadata(domain_id, kind, content) values(5, ‘SOA-EDIT-DNSUPDATE’,’INCREASE’);
219
220 This will make the SOA Serial increase by one, for every successful
221 update.
222
223 SOA-EDIT-DNSUPDATE settings
224 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
225
226 These are the settings available for **SOA-EDIT-DNSUPDATE**.
227
228 - DEFAULT: Generate a soa serial of YYYYMMDD01. If the current serial
229 is lower than the generated serial, use the generated serial. If the
230 current serial is higher or equal to the generated serial, increase
231 the current serial by 1.
232 - INCREASE: Increase the current serial by 1.
233 - EPOCH: Change the serial to the number of seconds since the EPOCH,
234 aka unixtime.
235 - SOA-EDIT: Change the serial to whatever SOA-EDIT would provide. See
236 :doc:`Domain metadata <domainmetadata>`
237 - SOA-EDIT-INCREASE: Change the serial to whatever SOA-EDIT would
238 provide. If what SOA-EDIT provides is lower than the current serial,
239 increase the current serial by 1.
240
241 DNS update How-to: Setup dyndns/rfc2136 with dhcpd
242 --------------------------------------------------
243
244 DNS update is often used with DHCP to automatically provide a hostname
245 whenever a new IP-address is assigned by the DHCP server. This section
246 describes how you can setup PowerDNS to receive DNS updates from ISC's
247 dhcpd (version 4.1.1-P1).
248
249 Setting up dhcpd
250 ~~~~~~~~~~~~~~~~
251
252 We're going to use a TSIG key for security. We're going to generate a
253 key using the following command:
254
255 ::
256
257 dnssec-keygen -a hmac-md5 -b 128 -n USER dhcpdupdate
258
259 This generates two files (Kdhcpdupdate.*.key and
260 Kdhcpdupdate.*.private). You're interested in the .key file:
261
262 ::
263
264 # ls -l Kdhcp*
265 -rw------- 1 root root 53 Aug 26 19:29 Kdhcpdupdate.+157+20493.key
266 -rw------- 1 root root 165 Aug 26 19:29 Kdhcpdupdate.+157+20493.private
267
268 # cat Kdhcpdupdate.+157+20493.key
269 dhcpdupdate. IN KEY 0 3 157 FYhvwsW1ZtFZqWzsMpqhbg==
270
271 The important bits are the name of the key (**dhcpdupdate**) and the
272 hash of the key (**FYhvwsW1ZtFZqWzsMpqhbg==**
273
274 Using the details from the key you've just generated. Add the following
275 to your dhcpd.conf:
276
277 ::
278
279 key "dhcpdupdate" {
280 algorithm hmac-md5;
281 secret "FYhvwsW1ZtFZqWzsMpqhbg==";
282 };
283
284 You must also tell dhcpd that you want dynamic dns to work, add the
285 following section:
286
287 ::
288
289 ddns-updates on;
290 ddns-update-style interim;
291 update-static-leases on;
292
293 This tells dhcpd to:
294
295 1. Enable Dynamic DNS
296 2. Which style it must use (interim)
297 3. Update static leases as well
298
299 For more information on this, consult the dhcpd.conf manual.
300
301 Per subnet, you also have to tell **dhcpd** which (reverse-)domain it
302 should update and on which master domain server it is running.
303
304 ::
305
306 ddns-domainname "example.org";
307 ddns-rev-domainname "in-addr.arpa.";
308
309 zone example.org {
310 primary 127.0.0.1;
311 key dhcpdupdate;
312 }
313
314 zone 1.168.192.in-addr.arpa. {
315 primary 127.0.0.1;
316 key dhcpdupdate;
317 }
318
319 This tells **dhcpd** a number of things:
320
321 1. Which domain to use (**ddns-domainname "example.org";**)
322 2. Which reverse-domain to use (**dnssec-rev-domainname
323 "in-addr.arpa.";**)
324 3. For the zones, where the primary master is located (**primary
325 127.0.0.1;**)
326 4. Which TSIG key to use (**key dhcpdupdate;**). We defined the key
327 earlier.
328
329 This concludes the changes that are needed to the **dhcpd**
330 configuration file.
331
332 Setting up PowerDNS
333 ~~~~~~~~~~~~~~~~~~~
334
335 A number of small changes are needed to powerdns to make it accept
336 dynamic updates from **dhcpd**.
337
338 Enabled DNS update (:rfc:`2136`) support functionality in PowerDNS by adding
339 the following to the PowerDNS configuration file (pdns.conf).
340
341 ::
342
343 dnsupdate=yes
344 allow-dnsupdate-from=
345
346 This tells PowerDNS to:
347
348 1. Enable DNS update support(:ref:`setting-dnsupdate`)
349 2. Allow updates from NO ip-address (":ref:`setting-allow-dnsupdate-from`\ =")
350
351 We just told powerdns (via the configuration file) that we accept
352 updates from nobody via the :ref:`setting-allow-dnsupdate-from`
353 parameter. That's not very useful, so we're going to give permissions
354 per zone (including the appropriate reverse zone), via the
355 domainmetadata table.
356
357 ::
358
359 sql> select id from domains where name='example.org';
360 5
361 sql> insert into domainmetadata(domain_id, kind, content) values(5, 'ALLOW-DNSUPDATE-FROM','127.0.0.1');
362 sql> select id from domains where name='1.168.192.in-addr.arpa';
363 6
364 sql> insert into domainmetadata(domain_id, kind, content) values(6, 'ALLOW-DNSUPDATE-FROM','127.0.0.1');
365
366 This gives the ip '127.0.0.1' access to send update messages. Make sure
367 you use the ip address of the machine that runs **dhcpd**.
368
369 Another thing we want to do, is add TSIG security. This can only be done
370 via the domainmetadata table:
371
372 ::
373
374 sql> insert into tsigkeys (name, algorithm, secret) values ('dhcpdupdate', 'hmac-md5', 'FYhvwsW1ZtFZqWzsMpqhbg==');
375 sql> select id from domains where name='example.org';
376 5
377 sql> insert into domainmetadata (domain_id, kind, content) values (5, 'TSIG-ALLOW-DNSUPDATE', 'dhcpdupdate');
378 sql> select id from domains where name='1.168.192.in-addr.arpa';
379 6
380 sql> insert into domainmetadata (domain_id, kind, content) values (6, 'TSIG-ALLOW-DNSUPDATE', 'dhcpdupdate');
381
382 This will:
383
384 1. Add the 'dhcpdupdate' key to our PowerDNSinstallation
385 2. Associate the domains with the given TSIG key
386
387 Restart PowerDNS and you should be ready to go!
388
389 .. _dnsupdate-how-it-works:
390
391 How it works
392 ------------
393
394 This is a short description of how DNS update messages are processed by
395 PowerDNS.
396
397 1. The DNS update message is received. If it is TSIG signed, the TSIG
398 is validated against the tsigkeys table. If it is not valid, Refused
399 is returned to the requestor.
400 2. A check is performed on the zone to see if it is a valid zone.
401 ServFail is returned when not valid.
402 3. The **dnsupdate** setting is checked. Refused is returned when the
403 setting is 'no'.
404 4. If update policy Lua script is provided then skip up to 7.
405 5. If the **ALLOW-DNSUPDATE-FROM** has a value (from both
406 domainmetadata and the configuration file), a check on the value is
407 performed. If the requestor (sender of the update message) does not
408 match the values in **ALLOW-DNSUPDATE-FROM**, Refused is returned.
409 6. If the message is TSIG signed, the TSIG keyname is compared with the
410 TSIG keyname in domainmetadata. If they do not match, a Refused is
411 send. The TSIG-ALLOW-DNSUPDATE domainmetadata setting is used to
412 find which key belongs to the domain.
413 7. The backends are queried to find the backend for the given domain.
414 8. If the domain is a slave domain, the **forward-dnsupdate** option
415 and domainmetadata settings are checked. If forwarding to a master
416 is enabled, the message is forward to the master. If that fails, the
417 next master is tried until all masters are tried. If all masters
418 fail, ServFail is returned. If a master succeeds, the result from
419 that master is returned.
420 9. A check is performed to make sure all updates/prerequisites are for
421 the given zone. NotZone is returned if this is not the case.
422 10. The transaction with the backend is started.
423 11. The prerequisite checks are performed (section 3.2 of :rfc:`2136 <2136#section-3.2>`). If a
424 check fails, the corresponding RCode is returned. No further
425 processing will happen.
426 12. Per record in the update message, a the prescan checks are
427 performed. If the prescan fails, the corresponding RCode is
428 returned. If the prescan for the record is correct, the actual
429 update/delete/modify of the record is performed. If the update fails
430 (for whatever reason), ServFail is returned. After changes to the
431 records have been applied, the ordername and auth flag are set to
432 make sure DNSSEC remains working. The cache for that record is
433 purged.
434 13. If there are records updated and the SOA record was not modified,
435 the SOA serial is updated. See :ref:`dnsupdate-soa-serial-updates`. The cache for this record is
436 purged.
437 14. The transaction with the backend is committed. If this fails,
438 ServFail is returned.
439 15. NoError is returned.
440
441 .. _dnsupdate-update-policy:
442
443 Update policy
444 -------------
445
446 .. versionadded:: 4.1.0
447
448 You can define a Lua script to handle DNS UPDATE message
449 authorization. The Lua script is to contain at least function called
450 ``updatepolicy`` which accepts one parameter. This parameter is an
451 object, containing all the information for the request. To permit
452 change, return true, otherwise return false. The script is called for
453 each record at a time and you can approve or reject any or all.
454
455 The object has following methods available:
456
457 - DNSName getQName() - name to update
458 - DNSName getZonename() - zone name
459 - int getQType() - record type, it can be 255(ANY) for delete.
460 - ComboAddress getLocal() - local socket address
461 - ComboAddress getRemote() - remote socket address
462 - Netmask getRealRemote() - real remote address (or netmask if EDNS Subnet is used)
463 - DNSName getTsigName() - TSIG **key** name (you can assume it is validated here)
464 - string getPeerPrincipal() - Return peer principal name (user@DOMAIN, service/machine.name@DOMAIN, host/MACHINE$@DOMAIN)
465
466 There are many same things available as in recursor Lua scripts, but
467 there is also resolve(qname, qtype) which returns array of records.
468 Example:
469
470 ::
471
472 resolve("www.google.com", pdns.A)
473
474 You can use this to perform DNS lookups. If your resolver cannot find
475 your local records, then this will not find them either. In other words,
476 resolve does not perform local lookup.
477
478 Simple example script:
479
480 .. code:: lua
481
482 --- This script is not suitable for production use
483
484 function strpos (haystack, needle, offset)
485 local pattern = string.format("(%s)", needle)
486 local i = string.find (haystack, pattern, (offset or 0))
487 return (i ~= nil and i or false)
488 end
489
490 function updatepolicy(input)
491 princ = input:getPeerPrincipal()
492
493 if princ == ""
494 then
495 return false
496 end
497
498 if princ == "admin@DOMAIN" or input:getRemote():toString() == "192.168.1.1"
499 then
500 return true
501 end
502
503 if (input:getQType() == pdns.A or input:getQType() == pdns.AAAA) and princ:sub(5,5) == '/' and strpos(princ, "@", 0) ~= false
504 then
505 i = strpos(princ, "@", 0)
506 if princ:sub(i) ~= "@DOMAIN"
507 then
508 return false
509 end
510 hostname = princ:sub(6, i-1)
511 if input:getQName():toString() == hostname .. "." or input:getQName():toString() == hostname .. "." .. input:getZoneName():toString()
512 then
513 return true
514 end
515 end
516
517 return false
518 end