mirror of
https://github.com/coredns/coredns.git
synced 2026-10-09 03:55:21 -04:00
Signed-off-by: coredns[bot] <bot@coredns.io> Co-authored-by: coredns[bot] <bot@coredns.io>
327 lines
12 KiB
Groff
327 lines
12 KiB
Groff
.\" Generated by Mmark Markdown Processor - mmark.miek.nl
|
|
.TH "COREDNS-DYNUPDATE" 7 "September 2026" "CoreDNS" "CoreDNS Plugins"
|
|
|
|
.SH "NAME"
|
|
.PP
|
|
\fIdynupdate\fP \- accepts authenticated RFC 2136 DNS UPDATE messages for an
|
|
explicit, opt\-in authoritative zone.
|
|
|
|
.SH "DESCRIPTION"
|
|
.PP
|
|
The \fIdynupdate\fP plugin serves one writable authoritative zone through the
|
|
normal CoreDNS authoritative file implementation and may be used only once
|
|
per server block. Use separate server blocks for separate writable zones.
|
|
An RFC 1035\-style zone file provides the initial data and is never modified.
|
|
Configure \fB\fCdatabase\fR for a
|
|
persistent primary: a successful UPDATE is committed to the local database
|
|
before its new snapshot becomes visible or the success response is sent.
|
|
Without \fB\fCdatabase\fR, updates are in memory only and are lost on restart or
|
|
Corefile reload; this mode is intended for temporary data and testing.
|
|
|
|
.PP
|
|
UPDATE requests must carry a TSIG that has been validated by the \fItsig\fP
|
|
plugin. The \fIdynupdate\fP plugin does not receive or store TSIG secrets. Every
|
|
mutation must also match an explicit \fB\fCallow\fR rule containing the key name,
|
|
owner name, and RR type. Use \fB\fC*\fR as the owner name or RR type only when that
|
|
broader permission is intentional. Configure \fB\fCrequire_opcode UPDATE\fR in the
|
|
\fItsig\fP plugin so unsigned UPDATE requests are rejected at the protocol
|
|
boundary. UPDATE requests for a different zone receive NOTAUTH; they do not
|
|
fall through to query\-only backends. Ordinary queries outside the dynamic
|
|
zone still pass to the next plugin.
|
|
|
|
.PP
|
|
The implementation supports RFC 2136 prerequisites, add and delete
|
|
operations, CNAME and apex SOA/NS invariants, automatic SOA serial updates,
|
|
and the current snapshot for AXFR. SOA serial zero is rejected because RFC
|
|
2136 recommends avoiding it for interoperability, and automatic increments
|
|
skip zero after wraparound. DNSSEC records and related zone\-integrity metadata
|
|
(\fB\fCSIG\fR, \fB\fCKEY\fR, \fB\fCNXT\fR, \fB\fCDS\fR, \fB\fCRRSIG\fR, \fB\fCNSEC\fR, \fB\fCDNSKEY\fR, \fB\fCNSEC3\fR, \fB\fCNSEC3PARAM\fR,
|
|
\fB\fCTALINK\fR, \fB\fCCDS\fR, \fB\fCCDNSKEY\fR, \fB\fCTA\fR, \fB\fCDLV\fR, and \fB\fCZONEMD\fR) are rejected because
|
|
the plugin cannot regenerate them after an update. IXFR and automatic DNSSEC
|
|
re\-signing are not supported. The plugin is experimental; it does not provide
|
|
multi\-primary replication or atomic transactions across zones. Do not expose
|
|
the UPDATE service without network controls in addition to TSIG authentication.
|
|
|
|
.PP
|
|
The \fIcache\fP plugin automatically bypasses dynamic zones, so their authoritative
|
|
queries always read the current snapshot, including after negative or positive
|
|
answers. Other middleware, such as \fIheader\fP, still processes those requests and
|
|
responses, and unrelated zones remain cacheable. External recursive
|
|
caches can still retain old answers until their TTL expires. AXFR requests
|
|
pass through \fItransfer\fP and its access controls. Successful changes trigger
|
|
best\-effort NOTIFY; bursts are coalesced to one in\-flight notification per zone
|
|
instance.
|
|
|
|
.SS "PERSISTENCE"
|
|
.PP
|
|
\fB\fCdatabase\fR uses an embedded bbolt
|
|
\[la]https://github.com/etcd-io/bbolt\[ra] database;
|
|
no etcd server or container is required. Its parent directory must exist and
|
|
be writable by CoreDNS. Use a local filesystem with working file locks and
|
|
sync semantics, not a shared network filesystem. The database is private to
|
|
one zone and one CoreDNS process. Overlapping instances in that process share
|
|
transactions and snapshots during a Corefile reload, so prerequisites cannot
|
|
race and an old instance cannot overwrite a newer generation.
|
|
|
|
.PP
|
|
Configuration validation does not create or modify the database. A missing
|
|
database is initialized from \fB\fCfile\fR on the first query, transfer or
|
|
authenticated UPDATE after startup. This prevents a failed startup from
|
|
preserving an obsolete seed. Until that first access, the seed must remain
|
|
available; creation errors return SERVFAIL rather than acknowledging an update.
|
|
Subsequently, the database, including the SOA serial, is authoritative;
|
|
editing or removing the seed does not replace dynamic data. Corrupt, incompatible, wrong\-zone, or
|
|
over\-limit databases cause an error, not a fallback to the seed. A failed
|
|
commit returns SERVFAIL without publishing the candidate snapshot or serial.
|
|
After an abrupt process exit, the database reopens at a committed transaction.
|
|
|
|
.PP
|
|
Stop CoreDNS before copying the database for an offline backup or restoring
|
|
it. Never edit, replace, or delete a live database. To deliberately reset the
|
|
zone, stop CoreDNS, back up and remove the database, then restart with the
|
|
desired seed. If initial creation fails, remove the uninitialized database
|
|
before retrying. Do not lower limits below the existing zone's size when
|
|
reloading. Database files can retain reusable free pages after records are
|
|
deleted; \fB\fCmax_bytes\fR limits live uncompressed DNS data, not on\-disk file size.
|
|
|
|
.SH "SYNTAX"
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
dynupdate [ZONE] {
|
|
file DBFILE
|
|
database PATH
|
|
allow KEY NAME TYPE [TYPE...]
|
|
max\_records COUNT
|
|
max\_bytes BYTES
|
|
max\_update\_records COUNT
|
|
}
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.IP \(bu 4
|
|
\fBZONE\fP is the single authoritative zone. If omitted, the server block
|
|
must define exactly one zone.
|
|
.IP \(bu 4
|
|
\fBDBFILE\fP is the RFC 1035\-style seed zone file. A relative path is resolved
|
|
below the path configured by the \fIroot\fP plugin. Required, but read only when
|
|
initializing a new database or starting in memory\-only mode.
|
|
.IP \(bu 4
|
|
\fB\fCdatabase\fR is optional. \fBPATH\fP is a local database file, also resolved
|
|
relative to \fIroot\fP. The database is created with mode 0600 on systems that
|
|
support Unix file permissions.
|
|
.IP \(bu 4
|
|
\fBKEY\fP is the normalized TSIG key name configured in the \fItsig\fP plugin.
|
|
.IP \(bu 4
|
|
\fBNAME\fP is an exact owner name, \fB\fC@\fR for the zone apex, or \fB\fC*\fR for all names
|
|
in the zone.
|
|
.IP \(bu 4
|
|
\fBTYPE\fP is one or more RR types, \fB\fCANY\fR to authorize deleting all RRsets at
|
|
one owner name, or \fB\fC*\fR for all supported update operations. A wildcard type
|
|
must be the only type in the rule.
|
|
.IP \(bu 4
|
|
\fB\fCmax_records\fR defaults to 10000 records in the zone.
|
|
.IP \(bu 4
|
|
\fB\fCmax_bytes\fR defaults to 8388608 bytes of uncompressed DNS record data.
|
|
.IP \(bu 4
|
|
\fB\fCmax_update_records\fR defaults to 1024 records total in an UPDATE's
|
|
Prerequisite and Update sections.
|
|
|
|
|
|
.PP
|
|
Limits must be positive integers. Requests exceeding the configured limits
|
|
are refused atomically with REFUSED; seed or stored data above the zone limits
|
|
is rejected during startup. Updates are serialized and rebuild the bounded
|
|
zone snapshot, so this backend is intended for small dynamic zones, not
|
|
high\-volume bulk loading.
|
|
|
|
.PP
|
|
At least one \fB\fCallow\fR rule is required. The plugin owns the configured zone;
|
|
do not configure a second authoritative backend for the same zone unless its
|
|
independent behavior is explicitly intended.
|
|
|
|
.SH "EXAMPLES"
|
|
.PP
|
|
For temporary ACME challenge records, load a seed zone and permit one key to
|
|
update TXT records at the challenge owner. This example uses memory\-only mode.
|
|
Generate a private key for your deployment; the example secret is public.
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
example.org {
|
|
tsig {
|
|
secret update\-key.example.org. i9M+00yrECfVZG2qCjr4mPpaGim/Bq+IWMiNrLjUO4Y=
|
|
require\_opcode UPDATE
|
|
}
|
|
dynupdate {
|
|
file example.org.zone
|
|
allow update\-key.example.org. \_acme\-challenge.example.org. TXT
|
|
}
|
|
}
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
For a persistent zone, add \fB\fCdatabase\fR. A client that needs several record
|
|
types at selected names can use separate narrow rules:
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
example.org {
|
|
tsig {
|
|
secret update\-key.example.org. i9M+00yrECfVZG2qCjr4mPpaGim/Bq+IWMiNrLjUO4Y=
|
|
require\_opcode UPDATE
|
|
}
|
|
dynupdate {
|
|
file example.org.zone
|
|
database example.org.db
|
|
allow update\-key.example.org. host.example.org. A AAAA
|
|
allow update\-key.example.org. \_acme\-challenge.example.org. TXT
|
|
}
|
|
}
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
A minimal seed file is:
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
$ORIGIN example.org.
|
|
@ 60 IN SOA ns.example.org. hostmaster.example.org. 1 3600 600 86400 60
|
|
@ 60 IN NS ns.example.org.
|
|
ns 60 IN A 192.0.2.53
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
With a BIND\-format TSIG key file, \fB\fCnsupdate -k update.key\fR can submit:
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
server 127.0.0.1 53
|
|
zone example.org.
|
|
prereq nxrrset host.example.org. A
|
|
update add host.example.org. 60 A 192.0.2.10
|
|
send
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
Use \fB\fCnsupdate -v -k update.key\fR for TCP. Query \fB\fChost.example.org. A\fR directly
|
|
on this server to see the change. With \fB\fCdatabase\fR configured it remains after
|
|
restart. For DHCP forward and reverse updates, configure each zone in its own
|
|
server block with its own seed, database and least\-privilege \fB\fCallow\fR rules.
|
|
The DHCP server remains responsible for lease expiry, record cleanup, and
|
|
coordinating its forward and reverse requests.
|
|
|
|
.SS "DHCP CLIENT PERMISSIONS"
|
|
.PP
|
|
The required permissions depend on the UPDATE messages sent by the DHCP
|
|
implementation, not just the address records it creates. For example, Kea
|
|
2.0.2 D2 writes DHCID records in both the forward and reverse zones and uses
|
|
an \fB\fCANY\fR deletion when releasing a name. Allowing only A/AAAA or PTR lets
|
|
some steps succeed but refuses later steps. Forward and reverse updates are
|
|
separate transactions: a rejected reverse update does not undo a successful
|
|
forward update.
|
|
|
|
.PP
|
|
For a DHCP\-managed \fB\fChost.example.org.\fR at \fB\fC192.0.2.10\fR, the forward\-zone
|
|
rule can be:
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
allow update\-key.example.org. host.example.org. A AAAA DHCID ANY
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
The corresponding rule in \fB\fC2.0.192.in-addr.arpa.\fR can be:
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
allow update\-key.example.org. 10.2.0.192.in\-addr.arpa. PTR DHCID ANY
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
\fB\fCANY\fR explicitly permits deleting all RRsets at the authorized name; it
|
|
does not mean only the other types listed in the rule. Do not place unrelated
|
|
static records at those names. Use \fB\fC*\fR for the name only when the DHCP
|
|
updater is trusted to manage the entire zone. Keep DHCID conflict resolution
|
|
enabled on the DHCP side; a TSIG key identifies the updater, not the client
|
|
that owns a lease.
|
|
|
|
.SS "INTEROPERABILITY AND SIZING"
|
|
.PP
|
|
With BIND \fB\fCnsupdate\fR and Kea \fB\fCkea-dhcp-ddns\fR installed, run:
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
go test \-race ./test \-run '^TestDynUpdate' \-count=3
|
|
go test ./plugin/dynupdate \-run '^$' \-bench '^BenchmarkUpdate$' \-benchmem \-count=3
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
The Kea test supplies synthetic lease\-change notifications to a real D2
|
|
process and verifies IPv4 and IPv6 forward/reverse creation, renewal,
|
|
ownership conflicts, removal, and name reuse. It is not a DHCP address
|
|
allocation, lease\-expiration, or physical\-network test. Missing client
|
|
binaries skip the corresponding local tests; Linux CI installs both.
|
|
Distribution confinement may require approved paths for the Kea test
|
|
process. \fB\fCCOREDNS_KEA_CONFIG_DIR\fR, \fB\fCKEA_PIDFILE_DIR\fR, and \fB\fCKEA_LOCKFILE_DIR\fR
|
|
can select prepared writable directories. Linux CI uses this facility to
|
|
keep Ubuntu's AppArmor policy enabled. Do not point a test at runtime
|
|
directories used by a live Kea service.
|
|
|
|
.PP
|
|
The benchmark changes a record in 100\-, 1000\-, and 10000\-record zones,
|
|
with and without synchronous persistence and four concurrent query workers.
|
|
\fB\fCns/op\fR measures one protocol\-engine transaction, excluding transport and
|
|
TSIG verification, while the query metrics report concurrent query latency
|
|
and throughput. Allocations include the query workers when
|
|
enabled. Measure on the filesystem and hardware used for deployment:
|
|
updates rebuild the entire zone and queries can wait for the update and
|
|
disk commit. The record limits bound accepted data, not update latency or
|
|
peak process memory. This backend is intended for small, infrequently
|
|
updated zones, not a high\-throughput DHCP service.
|
|
|
|
.SH "SEE ALSO"
|
|
.PP
|
|
See the \fIfile\fP, \fItransfer\fP, and \fItsig\fP plugins for authoritative data,
|
|
AXFR/NOTIFY, and TSIG authentication configuration.
|
|
|
|
.IP \(bu 4
|
|
RFC 2136
|
|
\[la]https://www.rfc-editor.org/rfc/rfc2136\[ra] defines DNS UPDATE.
|
|
.IP \(bu 4
|
|
RFC 1982
|
|
\[la]https://www.rfc-editor.org/rfc/rfc1982\[ra] defines DNS serial
|
|
number arithmetic.
|
|
|
|
|