From 311a9915da9a6540d411d6f499c9ddddb4cf5f92 Mon Sep 17 00:00:00 2001 From: Ben Kochie Date: Thu, 8 Oct 2026 10:21:06 +0200 Subject: [PATCH] Improve RFC links (#8612) The `tools.ietf.org` site now redirects to `www.rfc-editor.org`. * Update various URLs to the new site. * Make links to `www.rfc-editor.org` consistent. Signed-off-by: SuperQ --- README.md | 6 +- core/dnsserver/quic.go | 2 +- core/dnsserver/server_quic.go | 8 +- man/coredns-any.7 | 6 +- man/coredns-auto.7 | 5 +- man/coredns-azure.7 | 17 +++- man/coredns-bufsize.7 | 4 +- man/coredns-cache.7 | 7 +- man/coredns-dns64.7 | 6 +- man/coredns-dnssec.7 | 4 +- man/coredns-dnstap.7 | 107 +++++++++++++++++++++++- man/coredns-dynupdate.7 | 54 ++++++------ man/coredns-erratic.7 | 10 +-- man/coredns-etcd.7 | 47 +++++++++-- man/coredns-file.7 | 47 +++++++++-- man/coredns-forward.7 | 146 ++++++++++++++++++++++++++++----- man/coredns-geoip.7 | 6 +- man/coredns-grpc.7 | 8 +- man/coredns-hosts.7 | 69 +++++++++++++++- man/coredns-https.7 | 13 ++- man/coredns-https3.7 | 5 +- man/coredns-kubernetes.7 | 2 +- man/coredns-local.7 | 14 ++-- man/coredns-log.7 | 58 ++++++++++++- man/coredns-metrics.7 | 15 +++- man/coredns-nsid.7 | 6 +- man/coredns-proxyproto.7 | 66 +++++++++++++-- man/coredns-secondary.7 | 38 ++++++++- man/coredns-shed.7 | 30 +++---- man/coredns-siit.7 | 18 ++-- man/coredns-template.7 | 83 +++++++++++++++++-- man/coredns-timeouts.7 | 51 ++++++++++-- man/coredns-tls.7 | 89 +++++++++++++++++++- man/coredns-trace.7 | 3 +- man/coredns-transfer.7 | 24 +++++- man/coredns-tsig.7 | 42 ++++++++-- man/coredns-view.7 | 12 ++- man/corefile.5 | 17 +++- notes/coredns-008.md | 2 +- notes/coredns-1.0.1.md | 2 +- notes/coredns-1.5.1.md | 2 +- notes/coredns-1.6.2.md | 2 +- plugin/any/README.md | 4 +- plugin/bufsize/README.md | 2 +- plugin/dns64/README.md | 4 +- plugin/dns64/dns64.go | 2 +- plugin/dnssec/black_lies.go | 2 +- plugin/dynupdate/README.md | 4 +- plugin/erratic/README.md | 6 +- plugin/file/README.md | 4 +- plugin/forward/README.md | 6 +- plugin/geoip/README.md | 2 +- plugin/hosts/README.md | 2 +- plugin/hosts/hostsfile_test.go | 4 +- plugin/nsid/README.md | 4 +- plugin/siit/README.md | 6 +- plugin/siit/siit.go | 4 +- plugin/template/README.md | 8 +- plugin/tls/README.md | 2 +- plugin/tsig/README.md | 2 +- 60 files changed, 1006 insertions(+), 215 deletions(-) diff --git a/README.md b/README.md index 605ce0141..ea60b5c32 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,10 @@ provided out of the box you can add it by [writing a plugin](https://coredns.io/ CoreDNS can listen for DNS requests coming in over: * UDP/TCP (go'old DNS). -* TLS - DoT ([RFC 7858](https://tools.ietf.org/html/rfc7858)). -* DNS over HTTP/2 - DoH ([RFC 8484](https://tools.ietf.org/html/rfc8484)). +* TLS - DoT ([RFC 7858](https://www.rfc-editor.org/info/rfc7858/)). +* DNS over HTTP/2 - DoH ([RFC 8484](https://www.rfc-editor.org/info/rfc8484/)). * DNS over HTTP/3 - DoH3 -* DNS over QUIC - DoQ ([RFC 9250](https://tools.ietf.org/html/rfc9250)). +* DNS over QUIC - DoQ ([RFC 9250](https://www.rfc-editor.org/info/rfc9250/)). * [gRPC](https://grpc.io) (not a standard). Currently CoreDNS is able to: diff --git a/core/dnsserver/quic.go b/core/dnsserver/quic.go index 029f89206..5dfcffa9a 100644 --- a/core/dnsserver/quic.go +++ b/core/dnsserver/quic.go @@ -45,7 +45,7 @@ func (w *DoQWriter) WriteMsg(m *dns.Msg) error { // The server MUST send the response(s) on the same stream and MUST // indicate, after the last response, through the STREAM FIN // mechanism that no further data will be sent on that stream. -// See https://www.rfc-editor.org/rfc/rfc9250#section-4.2-7 +// See https://www.rfc-editor.org/info/rfc9250/#section-4.2-7 func (w *DoQWriter) Close() error { if w.stream == nil { return errors.New("stream is nil") diff --git a/core/dnsserver/server_quic.go b/core/dnsserver/server_quic.go index 438702e0b..5713b0922 100644 --- a/core/dnsserver/server_quic.go +++ b/core/dnsserver/server_quic.go @@ -260,7 +260,7 @@ func (s *ServerQUIC) serveQUICStream(stream *quic.Stream, conn *quic.Conn) { // fatal error. It SHOULD forcibly abort the connection using QUIC's // CONNECTION_CLOSE mechanism and SHOULD use the DoQ error code // DOQ_PROTOCOL_ERROR. - // See https://www.rfc-editor.org/rfc/rfc9250#section-4.3.3-3 + // See https://www.rfc-editor.org/info/rfc9250/#section-4.3.3-3 s.closeQUICConn(conn, DoQCodeProtocolError) return @@ -362,7 +362,7 @@ func (s *ServerQUIC) closeQUICConn(conn *quic.Conn, code quic.ApplicationErrorCo } // validRequest checks for protocol errors in the unpacked DNS message. -// See https://www.rfc-editor.org/rfc/rfc9250.html#name-protocol-errors +// See https://www.rfc-editor.org/info/rfc9250/#name-protocol-errors func validRequest(req *dns.Msg) (ok bool) { // 1. a client or server receives a message with a non-zero Message ID. if req.Id != 0 { @@ -404,7 +404,7 @@ func readDOQMessage(r io.Reader) ([]byte, error) { // All DNS messages (queries and responses) sent over DoQ connections MUST // be encoded as a 2-octet length field followed by the message content as // specified in [RFC1035]. - // See https://www.rfc-editor.org/rfc/rfc9250.html#section-4.2-4 + // See https://www.rfc-editor.org/info/rfc9250/#section-4.2-4 sizeBuf := make([]byte, 2) _, err := io.ReadFull(r, sizeBuf) if err != nil { @@ -422,7 +422,7 @@ func readDOQMessage(r io.Reader) ([]byte, error) { // A client or server receives a STREAM FIN before receiving all the bytes // for a message indicated in the 2-octet length field. - // See https://www.rfc-editor.org/rfc/rfc9250#section-4.3.3-2.2 + // See https://www.rfc-editor.org/info/rfc9250/#section-4.3.3-2.2 if size != uint16(len(buf)) { // #nosec G115 -- buf length fits in uint16 return nil, fmt.Errorf("message size does not match 2-byte prefix") } diff --git a/man/coredns-any.7 b/man/coredns-any.7 index a578a8bf4..98d2d13ef 100644 --- a/man/coredns-any.7 +++ b/man/coredns-any.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-ANY" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ANY" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -9,7 +9,7 @@ .PP \fIany\fP basically blocks ANY queries by responding to them with a short HINFO reply. See RFC 8482 -\[la]https://tools.ietf.org/html/rfc8482\[ra] for details. +\[la]https://www.rfc-editor.org/info/rfc8482/\[ra] for details. .SH "SYNTAX" .PP @@ -49,5 +49,5 @@ example.org. 8482 IN HINFO "ANY obsoleted" "See RFC 8482" .SH "SEE ALSO" .PP RFC 8482 -\[la]https://tools.ietf.org/html/rfc8482\[ra]. +\[la]https://www.rfc-editor.org/info/rfc8482/\[ra]. diff --git a/man/coredns-auto.7 b/man/coredns-auto.7 index 6253b9072..fd22a1980 100644 --- a/man/coredns-auto.7 +++ b/man/coredns-auto.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-AUTO" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-AUTO" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -35,7 +35,8 @@ used to extract the origin. \fBORIGIN_TEMPLATE\fP will be used as a template for like \fB\fC{}\fR are replaced with the respective matches in the file name, e.g. \fB\fC{1}\fR is the first match, \fB\fC{2}\fR is the second. The default is: \fB\fCdb\.(.*) {1}\fR i.e. from a file with the name \fB\fCdb.example.com\fR, the extracted origin will be \fB\fCexample.com\fR. \fBREGEXP\fP must not be longer -than 10000 characters. +than 10000 characters. \fBREGEXP\fP is unanchored; use \fB\fC^\fR and \fB\fC$\fR to require matching the full +file name, for example \fB\fC^(.*)\.zone$\fR to avoid matching backup files like \fB\fCexample.org.zone.bak\fR. .IP \(bu 4 \fB\fCreload\fR interval to perform reloads of zones if SOA version changes and zonefiles. It specifies how often CoreDNS should scan the directory to watch for file removal and addition. Default is one minute. Value of \fB\fC0\fR means to not scan for changes and reload. eg. \fB\fC30s\fR checks zonefile every 30 seconds diff --git a/man/coredns-azure.7 b/man/coredns-azure.7 index 07286280d..a77637cb2 100644 --- a/man/coredns-azure.7 +++ b/man/coredns-azure.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-AZURE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-AZURE" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -11,6 +11,21 @@ The azure plugin is useful for serving zones from Microsoft Azure DNS. The \fIaz all the DNS records supported by Azure, viz. A, AAAA, CNAME, MX, NS, PTR, SOA, SRV, and TXT record types. NS record type is not supported by azure private DNS. +.PP +Zone data is loaded asynchronously after startup and refreshed every minute. +An unavailable zone or zone-listing error is logged without preventing CoreDNS from +starting or other configured zones from being updated. Each zone listing, +including retries and pagination, has a one-minute timeout. +Configuration and credential initialization errors still prevent startup. + +.PP +Until a zone has been successfully loaded, queries for it return SERVFAIL unless +\fB\fCfallthrough\fR is explicitly configured. Only complete, successful updates replace +the in-memory zone. Failed updates, including a deleted Azure zone returning an +error, retain the last successfully loaded data and are retried. Remove the zone +from the Corefile to stop serving this retained data. Snapshots are not persisted +across restarts or configuration reloads. + .SH "SYNTAX" .PP .RS diff --git a/man/coredns-bufsize.7 b/man/coredns-bufsize.7 index e21a92618..f00d19728 100644 --- a/man/coredns-bufsize.7 +++ b/man/coredns-bufsize.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-BUFSIZE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-BUFSIZE" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -14,7 +14,7 @@ It prevents IP fragmentation, mitigating certain DNS vulnerabilities. It cannot increase UDP size requested by the client, it can be reduced only. This will only affect queries that have an OPT RR (EDNS(0) -\[la]https://www.rfc-editor.org/rfc/rfc6891\[ra]). +\[la]https://www.rfc-editor.org/info/rfc6891/\[ra]). .SH "SYNTAX" .PP diff --git a/man/coredns-cache.7 b/man/coredns-cache.7 index 2e1a1e9fe..8527f9b85 100644 --- a/man/coredns-cache.7 +++ b/man/coredns-cache.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-CACHE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-CACHE" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -82,6 +82,9 @@ Popular means \fBAMOUNT\fP queries have been seen with no gaps of \fBDURATION\fP \fBDURATION\fP defaults to 1m. Prefetching will happen when the TTL drops below \fBPERCENTAGE\fP, which defaults to \fB\fC10%\fR, or latest 1 second before TTL expiration. Values should be in the range \fB\fC[10%, 90%]\fR. Note the percent sign is mandatory. \fBPERCENTAGE\fP is treated as an \fB\fCint\fR. +Concurrent requests that trigger a prefetch for the same cache entry dispatch at most one +background fetch, so prefetch load scales with the number of distinct eligible entries rather +than request rate. .IP \(bu 4 \fB\fCserve_stale\fR, when serve_stale is set, cache will always serve an expired entry to a client if there is one available as long as it has not been expired for longer than \fBDURATION\fP (default 1 hour). By default, the \fIcache\fP plugin will @@ -92,6 +95,8 @@ responses have a TTL of 0. \fBREFRESH_MODE\fP controls the timing of the expired checking to see if the entry is available from the source. \fBREFRESH_MODE\fP defaults to \fB\fCimmediate\fR. Setting this value to \fB\fCverify\fR can lead to increased latency when serving stale responses, but will prevent stale entries from ever being served if an updated response can be retrieved from the source. +In \fB\fCimmediate\fR mode, concurrent requests for the same expired entry dispatch at most one +background refresh. .IP \(bu 4 \fB\fCservfail\fR cache SERVFAIL responses for \fBDURATION\fP. Setting \fBDURATION\fP to 0 will disable caching of SERVFAIL responses. If this option is not set, SERVFAIL responses will be cached for 5 seconds. \fBDURATION\fP may not be diff --git a/man/coredns-dns64.7 b/man/coredns-dns64.7 index 749146038..c3ee00c84 100644 --- a/man/coredns-dns64.7 +++ b/man/coredns-dns64.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-DNS64" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-DNS64" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -156,11 +156,11 @@ Support "mapping of separate IPv4 ranges to separate IPv6 prefixes" Resolve PTR records .IP \(bu 4 Make resolver DNSSEC aware. See: RFC 6147 Section 3 -\[la]https://tools.ietf.org/html/rfc6147#section-3\[ra] +\[la]https://www.rfc-editor.org/info/rfc6147/#section-3\[ra] .SH "SEE ALSO" .PP See RFC 6147 -\[la]https://tools.ietf.org/html/rfc6147\[ra] for more information on the DNS64 mechanism. +\[la]https://www.rfc-editor.org/info/rfc6147/\[ra] for more information on the DNS64 mechanism. diff --git a/man/coredns-dnssec.7 b/man/coredns-dnssec.7 index d4c724973..e3701df99 100644 --- a/man/coredns-dnssec.7 +++ b/man/coredns-dnssec.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-DNSSEC" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-DNSSEC" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -91,7 +91,7 @@ This command reads the contents of the \fB\fC.key\fR and \fB\fC.private\fR files .PP AWS SDK for Go V2 -\[la]https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials\[ra] is used +\[la]https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/configure-auth.html\[ra] is used for authentication with AWS Secrets Manager. Make sure the provided AWS credentials have the necessary permissions (e.g., \fB\fCsecretsmanager:GetSecretValue\fR) to access the specified secrets in AWS Secrets Manager. diff --git a/man/coredns-dnstap.7 b/man/coredns-dnstap.7 index a94c5c421..1fd721e32 100644 --- a/man/coredns-dnstap.7 +++ b/man/coredns-dnstap.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-DNSTAP" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-DNSTAP" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -16,6 +16,7 @@ Every message is sent to the socket as soon as it comes in, the \fIdnstap\fP plu 10000 messages, above that number dnstap messages will be dropped (this is logged). .SH "SYNTAX" +.SS "OUTGOING CONNECTIONS (CONNECT TO SINK)" .PP .RS @@ -49,6 +50,44 @@ dnstap SOCKET [full] [writebuffer] [queue] { \fB\fCskipverify\fR to skip tls verification during connection. Default to be secure +.SS "INCOMING CONNECTIONS (ACCEPT FROM SINKS)" +.PP +.RS + +.nf +dnstap listen SOCKET [full] { + [identity IDENTITY] + [version VERSION] + [extra EXTRA] + [tls CERT KEY [CA]] + [skipverify] +} + +.fi +.RE + +.IP \(bu 4 +\fB\fClisten\fR indicates this is a listening socket that accepts incoming connections from dnstap sinks. +.IP \(bu 4 +\fBSOCKET\fP is the socket address to listen on (e.g., \fB\fCtcp://127.0.0.1:6000\fR, \fB\fCunix:///tmp/dnstap.sock\fR). +.IP \(bu 4 +\fB\fCfull\fR to include the wire-format DNS message. +.IP \(bu 4 +\fBIDENTITY\fP to override the identity of the server. Defaults to the hostname. +.IP \(bu 4 +\fBVERSION\fP to override the version field. Defaults to the CoreDNS version. +.IP \(bu 4 +\fBEXTRA\fP to define "extra" field in dnstap payload, metadata +\[la]../metadata/\[ra] replacement available here. +.IP \(bu 4 +\fB\fCtls CERT KEY [CA]\fR to enable TLS for the listener. \fBCERT\fP and \fBKEY\fP are paths to the server certificate and key files. Optional \fBCA\fP is the path to the CA certificate for client verification. +.IP \(bu 4 +\fB\fCskipverify\fR to skip client certificate verification. Default is to verify client certificates. Equivalent to the \fBCA\fP option above being unspecified. + + +.PP +\fBNote:\fP Incoming connections use unbuffered channels to broadcast events. If a connected sink becomes slow or disconnected, messages are dropped for that sink only, and the connection is closed. + .SH "EXAMPLES" .PP Log information about client requests and responses to \fI/tmp/dnstap.sock\fP. @@ -155,6 +194,59 @@ dnstap tls://127.0.0.1:6000 full { .fi .RE +.PP +Listen for incoming dnstap sink connections on a Unix socket. + +.PP +.RS + +.nf +dnstap listen /tmp/dnstap.sock full + +.fi +.RE + +.PP +Listen for incoming dnstap sink connections on TCP. + +.PP +.RS + +.nf +dnstap listen tcp://127.0.0.1:6000 full + +.fi +.RE + +.PP +Listen for incoming dnstap sink connections on TLS with mTLS client authentication. + +.PP +.RS + +.nf +dnstap listen tls://127.0.0.1:6000 full { + tls /path/to/server\-cert.pem /path/to/server\-key.pem /path/to/ca.pem +} + +.fi +.RE + +.PP +Listen for incoming dnstap sink connections on TLS without client certificate verification. + +.PP +.RS + +.nf +dnstap listen tls://127.0.0.1:6000 full { + tls /path/to/server\-cert.pem /path/to/server\-key.pem + skipverify +} + +.fi +.RE + .PP You can use \fIdnstap\fP more than once to define multiple taps. The following logs information including the wire-format DNS message about client requests and responses to \fI/tmp/dnstap.sock\fP, @@ -170,6 +262,19 @@ dnstap tcp://example.com:6000 .fi .RE +.PP +You can also combine outgoing connections with incoming listeners: + +.PP +.RS + +.nf +dnstap tcp://remote\-collector.example.com:6000 full +dnstap listen tcp://127.0.0.1:6001 full + +.fi +.RE + .SH "COMMAND LINE TOOL" .PP Dnstap has a command line tool that can be used to inspect the logging. The tool can be found diff --git a/man/coredns-dynupdate.7 b/man/coredns-dynupdate.7 index 3eabec96f..bfadad46a 100644 --- a/man/coredns-dynupdate.7 +++ b/man/coredns-dynupdate.7 @@ -1,17 +1,17 @@ -.\" Generated by Mmark Markdown Processor - mmark.miek.nl -.TH "COREDNS-DYNUPDATE" 7 "September 2026" "CoreDNS" "CoreDNS Plugins" +.\" Generated by Mmark Markdown Processer - mmark.miek.nl +.TH "COREDNS-DYNUPDATE" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIdynupdate\fP \- accepts authenticated RFC 2136 DNS UPDATE messages for an -explicit, opt\-in authoritative zone. +\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. +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. @@ -26,7 +26,7 @@ owner name, and RR type. Use \fB\fC*\fR as the owner name or RR type only when t 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 +fall through to query-only backends. Ordinary queries outside the dynamic zone still pass to the next plugin. .PP @@ -34,12 +34,12 @@ 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 +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 +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 @@ -49,7 +49,7 @@ answers. Other middleware, such as \fIheader\fP, still processes those requests 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 +best-effort NOTIFY; bursts are coalesced to one in-flight notification per zone instance. .SS "PERSISTENCE" @@ -70,8 +70,8 @@ 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 +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. @@ -82,7 +82,7 @@ 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. +deleted; \fB\fCmax_bytes\fR limits live uncompressed DNS data, not on-disk file size. .SH "SYNTAX" .PP @@ -105,9 +105,9 @@ dynupdate [ZONE] { \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 +\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. +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 @@ -135,7 +135,7 @@ 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. +high-volume bulk loading. .PP At least one \fB\fCallow\fR rule is required. The plugin owns the configured zone; @@ -145,7 +145,7 @@ 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. +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 @@ -206,7 +206,7 @@ ns 60 IN A 192.0.2.53 .RE .PP -With a BIND\-format TSIG key file, \fB\fCnsupdate -k update.key\fR can submit: +With a BIND-format TSIG key file, \fB\fCnsupdate -k update.key\fR can submit: .PP .RS @@ -225,7 +225,7 @@ send 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. +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. @@ -240,7 +240,7 @@ 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 +For a DHCP-managed \fB\fChost.example.org.\fR at \fB\fC192.0.2.10\fR, the forward-zone rule can be: .PP @@ -287,10 +287,10 @@ go test ./plugin/dynupdate \-run '^$' \-bench '^BenchmarkUpdate$' \-benchmem \-c .RE .PP -The Kea test supplies synthetic lease\-change notifications to a real D2 +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 +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 @@ -299,16 +299,16 @@ 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, +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 +\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. +updated zones, not a high-throughput DHCP service. .SH "SEE ALSO" .PP @@ -317,10 +317,10 @@ AXFR/NOTIFY, and TSIG authentication configuration. .IP \(bu 4 RFC 2136 -\[la]https://www.rfc-editor.org/rfc/rfc2136\[ra] defines DNS UPDATE. +\[la]https://www.rfc-editor.org/info/rfc2136/\[ra] defines DNS UPDATE. .IP \(bu 4 RFC 1982 -\[la]https://www.rfc-editor.org/rfc/rfc1982\[ra] defines DNS serial +\[la]https://www.rfc-editor.org/info/rfc1982/\[ra] defines DNS serial number arithmetic. diff --git a/man/coredns-erratic.7 b/man/coredns-erratic.7 index 71d88c4d5..54b24499d 100644 --- a/man/coredns-erratic.7 +++ b/man/coredns-erratic.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-ERRATIC" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ERRATIC" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -11,9 +11,9 @@ dropped or truncated. The \fIerratic\fP plugin will respond to every A or AAAA query. For any other type it will return a SERVFAIL response (except AXFR). The reply for A will return 192.0.2.53 (RFC 5737 -\[la]https://tools.ietf.org/html/rfc5737\[ra]), for AAAA it returns 2001:DB8::53 (RFC +\[la]https://www.rfc-editor.org/info/rfc5737/\[ra]), for AAAA it returns 2001:DB8::53 (RFC 3849 -\[la]https://tools.ietf.org/html/rfc3849\[ra]). For an AXFR request it will respond with a small +\[la]https://www.rfc-editor.org/info/rfc3849/\[ra]). For an AXFR request it will respond with a small zone transfer. .SH "SYNTAX" @@ -127,6 +127,6 @@ example.org { .SH "SEE ALSO" .PP RFC 3849 -\[la]https://tools.ietf.org/html/rfc3849\[ra] and RFC 5737 -\[la]https://tools.ietf.org/html/rfc5737\[ra]. +\[la]https://www.rfc-editor.org/info/rfc3849/\[ra] and RFC 5737 +\[la]https://www.rfc-editor.org/info/rfc5737/\[ra]. diff --git a/man/coredns-etcd.7 b/man/coredns-etcd.7 index 0a384f727..29009f4d3 100644 --- a/man/coredns-etcd.7 +++ b/man/coredns-etcd.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-ETCD" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ETCD" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -52,6 +52,7 @@ etcd [ZONES...] { endpoint ENDPOINT... credentials USERNAME PASSWORD tls CERT KEY CACERT + no\_apex\_fallback } .fi @@ -85,6 +86,17 @@ file - if the server certificate is not signed by a system-installed CA and clie is needed. .RE +.IP \(bu 4 +\fB\fCno_apex_fallback\fR disables the legacy zone-root lookup used by address queries and apex-existence +checks at a configured zone apex. When \fB\fCapex.dns.ZONE\fR does not exist, the lookup returns a name +error instead of issuing a prefix range over the complete zone subtree. Migrate zone-apex address +records to the \fB\fCdns/apex\fR layout before enabling this option. + + +.PP +CoreDNS sets the minimum TLS version to TLS 1.2. The maximum TLS version, TLS 1.2 cipher suites, and +key exchange mechanisms use the Go \fB\fCcrypto/tls\fR defaults. + .IP \(bu 4 \fB\fCmin-lease-ttl\fR the minimum TTL for DNS records based on etcd lease duration. Accepts flexible time formats like '30', '30s', '5m', '1h', '2h30m'. Default: 30 seconds. .IP \(bu 4 @@ -112,6 +124,27 @@ find entries like \fB\fC/skydns/test/skydns/mx1\fR. .PP This causes two lookups from CoreDNS to etcd in certain cases. +.SS "BACKEND LOAD" +.PP +The \fIetcd\fP plugin does not watch or poll etcd when data changes. Record lookups are driven by +incoming DNS queries. An uncached lookup may issue multiple etcd requests when an exact-key fallback +or an internal CNAME lookup is needed. + +.PP +Non-exact lookups use an etcd prefix range and return the complete subtree by design. Querying a name +high in the hierarchy can therefore read many keys. In particular, an A or AAAA query for a configured +zone name first looks below \fB\fCapex.dns.ZONE\fR. If that entry does not exist, CoreDNS falls back to the +zone's root prefix for compatibility with older SkyDNS layouts. On a large zone, that fallback scans +the entire zone subtree. + +.PP +Store zone-apex address records below the \fB\fCdns/apex\fR path, as shown in the examples below, to avoid +the zone-wide fallback. Once all apex records use that layout, enable \fB\fCno_apex_fallback\fR to prevent a +missing or deleted apex entry from triggering a zone-root scan. The \fIcache\fP plugin reduces repeated +backend reads for the same DNS question, but does not reduce the size of the first prefix response. +Use the \fIlog\fP plugin to identify the client and question name that trigger a lookup, and +\fB\fCcoredns_dns_requests_total\fR from the \fIprometheus\fP plugin to measure query volume by zone and type. + .SH "EXAMPLES" .PP This is the default SkyDNS setup, with everything specified in full: @@ -189,7 +222,7 @@ endpoint URL depends on the version of \fB\fCetcd\fR. For instance, \fB\fCetcd v [CLIENT-URL]/v3alpha/* while \fB\fCetcd v3.5\fR or later uses [CLIENT-URL]/v3/* . Also, Key and Value must be base64 encoded in the JSON payload. With \fB\fCetcdctl\fR these details are automatically taken care of. You can check this document -\[la]https://github.com/coreos/etcd/blob/master/Documentation/dev-guide/api_grpc_gateway.md#notes\[ra] +\[la]https://github.com/etcd-io/website/blob/main/content/en/docs/v3.2/dev-guide/api_grpc_gateway.md\[ra] for details. .SS "REVERSE ZONES" @@ -244,7 +277,7 @@ create an \fB\fCA\fR record for this zone as follows: .RS .nf -% etcdctl put /skydns/local/skydns/ '{"host":"1.1.1.1","ttl":60}' +% etcdctl put /skydns/local/skydns/dns/apex/x1 '{"host":"1.1.1.1","ttl":60}' .fi .RE @@ -269,8 +302,8 @@ If you would like to use DNS RR for the zone name, you can set the following: .RS .nf -% etcdctl put /skydns/local/skydns/x1 '{"host":"1.1.1.1","ttl":60}' -% etcdctl put /skydns/local/skydns/x2 '{"host":"1.1.1.2","ttl":60}' +% etcdctl put /skydns/local/skydns/dns/apex/x1 '{"host":"1.1.1.1","ttl":60}' +% etcdctl put /skydns/local/skydns/dns/apex/x2 '{"host":"1.1.1.2","ttl":60}' .fi .RE @@ -297,8 +330,8 @@ If you would like to use \fB\fCAAAA\fR records for the zone name too, you can se .RS .nf -% etcdctl put /skydns/local/skydns/x3 '{"host":"2003::8:1","ttl":60}' -% etcdctl put /skydns/local/skydns/x4 '{"host":"2003::8:2","ttl":60}' +% etcdctl put /skydns/local/skydns/dns/apex/x3 '{"host":"2003::8:1","ttl":60}' +% etcdctl put /skydns/local/skydns/dns/apex/x4 '{"host":"2003::8:2","ttl":60}' .fi .RE diff --git a/man/coredns-file.7 b/man/coredns-file.7 index 14f395825..e0faed638 100644 --- a/man/coredns-file.7 +++ b/man/coredns-file.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-FILE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-FILE" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -30,6 +30,13 @@ plugin will be prepended to it. are used. +.PP +The SOA record's owner name must match the zone being loaded. Names without a final dot are +relative to the current origin; for example, \fB\fCtest\fR in a zone loaded as \fB\fCtest.\fR becomes +\fB\fCtest.test.\fR, not \fB\fCtest.\fR. Use \fB\fC@\fR (when the current origin matches the zone) or the zone's +absolute name for the SOA owner. A mismatched SOA causes loading to fail; an invalid reload +leaves the last successfully loaded zone in service. + .PP If you want to round-robin A and AAAA responses look at the \fIloadbalance\fP plugin. @@ -39,6 +46,7 @@ If you want to round-robin A and AAAA responses look at the \fIloadbalance\fP pl .nf file DBFILE [ZONES... ] { reload DURATION + reload\_by\_mtime fallthrough [ZONES...] } @@ -50,6 +58,9 @@ file DBFILE [ZONES... ] { Value of \fB\fC0\fR means to not scan for changes and reload. For example, \fB\fC30s\fR checks the zonefile every 30 seconds and reloads the zone when serial changes. .IP \(bu 4 +\fB\fCreload_by_mtime\fR if set, decision to reload the zone will be based on the zone file modification time, +instead of change in the SOA serial. +.IP \(bu 4 \fB\fCfallthrough\fR If zone matches and no record can be generated, pass request to the next plugin. If \fB[ZONES...]\fP is omitted, then fallthrough happens for all zones for which the plugin is authoritative. If specific zones are listed (for example \fB\fCin-addr.arpa\fR and \fB\fCip6.arpa\fR), then only @@ -79,8 +90,8 @@ example.org { .RE .PP -Where \fB\fCdb.example.org\fR would contain RRSets (https://tools.ietf.org/html/rfc7719#section-4 -\[la]https://tools.ietf.org/html/rfc7719#section-4\[ra]) in the +Where \fB\fCdb.example.org\fR would contain RRSets (https://www.rfc-editor.org/info/rfc7719/#section-4 +\[la]https://www.rfc-editor.org/info/rfc7719/#section-4\[ra]) in the (text) presentation format from RFC 1035: .PP @@ -99,14 +110,14 @@ www IN A 127.0.0.1 .RE .PP -Or use a single zone file for multiple zones: +Or use a single zone file for multiple zones, with relative owner names and no fixed \fB\fC$ORIGIN\fR: .PP .RS .nf \&. { - file example.org.signed example.org example.net + file db.shared example.org example.net transfer example.org example.net { to * 10.240.1.1 } @@ -115,6 +126,24 @@ Or use a single zone file for multiple zones: .fi .RE +.PP +For example, \fB\fCdb.shared\fR can contain: + +.PP +.RS + +.nf +@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2017042745 7200 3600 1209600 3600 +@ 3600 IN NS a.iana\-servers.net. +www 3600 IN A 127.0.0.1 + +.fi +.RE + +.PP +Each configured zone is used as the initial origin when parsing this file, so \fB\fC@\fR is its apex. +Signed zones require signatures for the actual owner names and must be signed separately. + .PP Note that if you have a configuration like the following you may run into a problem of the origin not being correctly recognized: @@ -132,9 +161,9 @@ not being correctly recognized: .PP We omit the origin for the file \fB\fCdb.example.org\fR, so this references the zone in the server block, -which, in this case, is the root zone. Any contents of \fB\fCdb.example.org\fR will then read with that -origin set; this may or may not do what you want. -It's better to be explicit here and specify the correct origin. This can be done in two ways: +which, in this case, is the root zone. A file with an SOA for \fB\fCexample.org.\fR will be rejected +because it does not match the configured root zone, even if the file sets \fB\fC$ORIGIN example.org.\fR. +Specify the correct zone in one of two ways: .PP .RS @@ -168,6 +197,6 @@ transfers. Lastly the \fIroot\fP plugin can help you specify the location of the .PP See RFC 1035 -\[la]https://www.rfc-editor.org/rfc/rfc1035.txt\[ra] for more info on how to structure zone +\[la]https://www.rfc-editor.org/info/rfc1035/\[ra] for more info on how to structure zone files. diff --git a/man/coredns-forward.7 b/man/coredns-forward.7 index 4d88c558d..214500b21 100644 --- a/man/coredns-forward.7 +++ b/man/coredns-forward.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-FORWARD" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-FORWARD" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -7,8 +7,8 @@ .SH "DESCRIPTION" .PP -The \fIforward\fP plugin re-uses already opened sockets to the upstreams. It supports UDP, TCP and -DNS-over-TLS and uses in band health checking. +The \fIforward\fP plugin re-uses already opened sockets to the upstreams. It supports UDP, TCP, +DNS-over-TLS, DNS-over-HTTPS and uses in band health checking. .PP When it detects an error a health check is performed. This checks runs in a loop, performing each @@ -40,8 +40,11 @@ forward FROM TO... that expand to multiple reverse zones are not fully supported; only the first expanded zone is used. .IP \(bu 4 \fBTO...\fP are the destination endpoints to forward to. The \fBTO\fP syntax allows you to specify -a protocol, \fB\fCtls://9.9.9.9\fR or \fB\fCdns://\fR (or no protocol) for plain DNS. The number of upstreams is -limited to 15. +a protocol, \fB\fCtls://9.9.9.9\fR, \fB\fCquic://94.140.14.14\fR, \fB\fChttps://9.9.9.9\fR (DoH defaults to \fB\fC/dns-query\fR path) or \fB\fCdns://\fR (or no protocol) +for plain DNS. The number of upstreams is limited to 15. In addition to IP addresses and files (like \fB\fC/etc/resolv.conf\fR), \fBTO\fP can also be +a hostname (e.g., \fB\fCmy-dns.svc.cluster.local\fR). Hostnames are resolved to IP addresses at startup and are treated as +absolute DNS names even without a trailing dot; resolver search domains are not applied. +See the \fB\fCresolver\fR option below. .PP @@ -60,9 +63,12 @@ forward FROM TO... { force\_tcp prefer\_udp expire DURATION + max\_age DURATION max\_idle\_conns INTEGER + read\_timeout DURATION max\_fails INTEGER max\_connect\_attempts INTEGER + doh\_method GET|POST tls CERT KEY CA tls\_servername NAME policy random|round\_robin|sequential @@ -71,6 +77,8 @@ forward FROM TO... { next RCODE\_1 [RCODE\_2] [RCODE\_3...] failfast\_all\_unhealthy\_upstreams failover RCODE\_1 [RCODE\_2] [RCODE\_3...] + source\_address IP + resolver IP[:PORT] [IP[:PORT]...] } .fi @@ -86,20 +94,33 @@ Requests that match none of these names will be passed through. .IP \(bu 4 \fB\fCprefer_udp\fR, try first using UDP even when the request comes in over TCP. If response is truncated (TC flag set in response) then do another attempt over TCP. In case if both \fB\fCforce_tcp\fR and -\fB\fCprefer_udp\fR options specified the \fB\fCforce_tcp\fR takes precedence. +\fB\fCprefer_udp\fR options specified the \fB\fCforce_tcp\fR takes precedence. These options do not change an +explicitly configured DoT, DoQ, or DoH upstream transport. .IP \(bu 4 \fB\fCmax_fails\fR is the number of subsequent failed health checks that are needed before considering an upstream to be down. If 0, the upstream will never be marked as down (nor health checked). Default is 2. .IP \(bu 4 \fB\fCmax_connect_attempts\fR caps the total number of upstream connect attempts -performed for a single incoming DNS request. Default value of 0 means no per-request -cap. +performed for a single incoming DNS request. The default cap is twice the number of +configured upstreams, allowing two complete passes when all upstreams are healthy. +Set this to 0 to disable the per-request cap. .IP \(bu 4 \fB\fCexpire\fR \fBDURATION\fP, expire (cached) connections after this time, the default is 10s. .IP \(bu 4 +\fB\fCmax_age\fR \fBDURATION\fP, stop reusing and replace connections after this total lifetime. +The default is 0, which disables maximum connection age. A non-zero value must not be less than \fB\fCexpire\fR. +.IP \(bu 4 +\fB\fCdoh_method\fR \fBGET|POST\fP, whether to use GET or POST http method for DoH requests (defaults to POST). +.IP \(bu 4 \fB\fCmax_idle_conns\fR \fBINTEGER\fP, maximum number of idle connections to cache per upstream for reuse. -Default is 0, which means unlimited. +Default is 0, which means unlimited. DoQ multiplexes streams over one cached connection per upstream. +.IP \(bu 4 +\fB\fCread_timeout\fR \fBDURATION\fP, the per-query read timeout applied to each upstream when waiting for a +response. The default is 2s. Increase this if upstreams legitimately take longer than 2s to answer +(for example slow recursive resolutions that would otherwise surface as \fB\fCSERVFAIL\fR/timeouts). Note +that this timeout applies to each upstream individually, so large values reduce the time available +to retry other upstreams within a single query. .IP \(bu 4 \fB\fCtls\fR \fBCERT\fP \fBKEY\fP \fBCA\fP define the TLS properties for TLS connection. From 0 to 3 arguments can be provided with the meaning as described below @@ -117,17 +138,23 @@ The server certificate is verified with the system CAs The server certificate is verified using the specified CA file .RE -.IP \(bu 4 -\fB\fCtls_servername\fR \fBNAME\fP allows you to set a server name in the TLS configuration; for instance 9.9.9.9 -needs this to be set to \fB\fCdns.quad9.net\fR. Using TLS forwarding but not setting \fB\fCtls_servername\fR results in anyone -being able to man-in-the-middle your connection to the DNS server you are forwarding to. Because of this, -it is strongly recommended to set this value when using TLS forwarding. .PP -Per destination endpoint TLS server name indication is possible in the form of \fB\fCtls://9.9.9.9%dns.quad9.net\fR. +CoreDNS sets the minimum TLS version to TLS 1.2 for DoT and DoH. DoQ uses TLS 1.3 as required by QUIC. +The maximum TLS version, TLS 1.2 cipher suites, and key exchange mechanisms use the Go \fB\fCcrypto/tls\fR defaults. + +.IP \(bu 4 +\fB\fCtls_servername\fR \fBNAME\fP allows you to set a server name in the TLS configuration; for instance 9.9.9.9 +needs this to be set to \fB\fCdns.quad9.net\fR. It is strongly recommended when using DoT, DoQ, or DoH with +an IP address whose certificate identifies a DNS name instead of that IP address. + + +.PP +Per destination endpoint TLS server name indication is possible in the form of \fB\fCtls://9.9.9.9%dns.quad9.net\fR + or \fB\fCquic://9.9.9.9%dns.quad9.net\fR. \fB\fCtls_servername\fR must not be specified when using per destination endpoint TLS server name indication - as it would introduce clash between the server name indication spectifications. If destination endpoint + as it would introduce a clash between server name indication specifications. If destination endpoint is to be reached via a port other than 853 then the port must be appended to the end of the destination endpoint specifier. In case of port 10853, the above string would be: \fB\fCtls://9.9.9.9%dns.quad9.net:10853\fR. @@ -166,20 +193,34 @@ As an upper bound for \fBMAX\fP, consider that each concurrent query will use ab .IP \(bu 4 \fB\fCnext\fR If the \fB\fCRCODE\fR (i.e. \fB\fCNXDOMAIN\fR) is returned by the remote then execute the next plugin. If no next plugin is defined, or the next plugin is not a \fB\fCforward\fR plugin, this setting is ignored .IP \(bu 4 +\fB\fCnext_on_nodata\fR If \fB\fCNOERROR\fR is returned by the remote, but an empty answer section (\fB\fCNODATA\fR) was provided, execute the next \fB\fCforward\fR plugin, if configured. +.IP \(bu 4 \fB\fCfailfast_all_unhealthy_upstreams\fR - determines the handling of requests when all upstream servers are unhealthy and unresponsive to health checks. Enabling this option will immediately return SERVFAIL responses for all requests. By default, requests are sent to a random upstream. .IP \(bu 4 \fB\fCfailover\fR - By default when a DNS lookup fails to return a DNS response (e.g. timeout), \fIforward\fP will attempt a lookup on the next upstream server. The \fB\fCfailover\fR option will make \fIforward\fP do the same for any response with a response code matching an \fB\fCRCODE\fR ( e.g. \fB\fCSERVFAIL\fR、\fB\fCREFUSED\fR). \fB\fCNOERROR\fR cannot be used. If all upstreams have been tried, the response from the last attempt is returned. +.IP \(bu 4 +\fB\fCsource_address\fR \fBIP\fP - set the address to use for all outgoing requests as source address (also health check query). This works reliably when upstream servers are reachable from that address. However, if upstream servers belong to different networks, care must be taken. The selected source address may not be valid for all upstreams, and responses may fail if return routing is not properly configured. In such cases, make sure that upstream servers have a route back to the configured source address. +.IP \(bu 4 +\fB\fCresolver\fR \fBIP[:PORT] [IP[:PORT]...]\fP specifies one or more DNS resolver addresses used to resolve hostname-based \fBTO\fP endpoints at startup. If not specified, the system resolver (\fB\fC/etc/resolv.conf\fR) is used. Each address is either a bare IP (IPv4 or IPv6, port 53 assumed) or \fB\fCIP:port\fR. Multiple addresses can be specified for redundancy. .PP -Also note the TLS config is "global" for the whole forwarding proxy if you need a different -\fB\fCtls_servername\fR for different upstreams you're out of luck. +The client certificate, key, and CA configuration is global for one \fB\fCforward\fR stanza. For DoT and DoQ, +use the \fB\fC%servername\fR endpoint form when upstreams in the same stanza require different TLS server names. .PP On each endpoint, the timeouts for communication are set as follows: .IP \(bu 4 -The dial timeout by default is 30s, and can decrease automatically down to 1s based on early results. +The DNS and DoT dial timeout defaults to 30s and can decrease automatically down to 1s based on early results. +The DoQ handshake timeout is 5s. +.IP \(bu 4 +DoT connection setup (TCP dial plus TLS handshake) is additionally bounded by the remaining +5s forwarding retry window, or an earlier request deadline. When retries are enabled, each +setup attempt is limited to half of the window available at the start of forwarding (at most +2.5s), so a stalled handshake leaves time to try a fresh connection. With \fB\fCmax_connect_attempts 1\fR, +setup may use the full remaining window. Failed handshakes close the connection; successful +connections remain reusable. These setup limits do not change the DNS exchange read timeout. .IP \(bu 4 The read timeout is static at 2s. @@ -215,7 +256,7 @@ number of concurrent queries were at maximum. .PP Where \fB\fCto\fR is one of the upstream servers (\fBTO\fP from the config), \fB\fCrcode\fR is the returned RCODE -from the upstream, \fB\fCproto\fR is the transport protocol like \fB\fCudp\fR, \fB\fCtcp\fR, \fB\fCtcp-tls\fR. +from the upstream, \fB\fCproto\fR is the transport protocol like \fB\fCudp\fR, \fB\fCtcp\fR, \fB\fCtcp-tls\fR, \fB\fCquic\fR, \fB\fChttps\fR. .PP The following metrics have recently been deprecated: @@ -356,6 +397,45 @@ service with health checks. .fi .RE +.PP +The following example uses DNS-over-QUIC (DoQ). DoQ uses UDP port 853 by default and multiplexes +concurrent queries over separate streams on one QUIC connection. The \fB\fCforward\fR plugin's single-message +exchange path does not support AXFR or IXFR over DoQ; those requests return \fB\fCNOTIMP\fR. + +.PP +.RS + +.nf +\&. { + forward . quic://94.140.14.14 { + tls\_servername dns.adguard\-dns.com + health\_check 5s + } + cache 30 +} + +.fi +.RE + +.PP +The same configuration but using DNS-over-HTTPS (DoH) protocol. Note that the implementation uses the default \fB\fC/dns-query\fR +path (custom paths are not supported). + +.PP +.RS + +.nf +\&. { + forward . https://9.9.9.9 { + tls\_servername dns.quad9.net + health\_check 5s + } + cache 30 +} + +.fi +.RE + .PP Or configure other domain name for health check requests @@ -456,8 +536,32 @@ In the following example, if the response from \fB\fC1.2.3.4\fR is \fB\fCSERVFAI .fi .RE +.PP +Forward to an upstream identified by hostname, using a specific resolver to look it up: + +.PP +.RS + +.nf +\&. { + forward . dns.example.local { + resolver 10.0.0.1 + } +} + +.fi +.RE + .SH "SEE ALSO" .PP RFC 7858 -\[la]https://tools.ietf.org/html/rfc7858\[ra] for DNS over TLS. +\[la]https://www.rfc-editor.org/info/rfc7858/\[ra] for DNS over TLS. + +.PP +RFC 8484 +\[la]https://www.rfc-editor.org/info/rfc8484/\[ra] for DNS over HTTPS. + +.PP +RFC 9250 +\[la]https://www.rfc-editor.org/info/rfc9250/\[ra] for DNS over QUIC. diff --git a/man/coredns-geoip.7 b/man/coredns-geoip.7 index 7d2b54db1..96ccc0cc1 100644 --- a/man/coredns-geoip.7 +++ b/man/coredns-geoip.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-GEOIP" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-GEOIP" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -132,7 +132,7 @@ geoip [DBFILE] { .PP There is no defined mask size in the standards, but there are examples: RFC 7871's example -\[la]https://datatracker.ietf.org/doc/html/rfc7871#section-13\[ra] conceals the last 72 bits of an IPv6 source address, and NS1 Help Center mentions +\[la]https://www.rfc-editor.org/info/rfc7871/#section-13\[ra] conceals the last 72 bits of an IPv6 source address, and NS1 Help Center mentions \[la]https://help.ns1.com/hc/en-us/articles/360020256573-About-the-EDNS-Client-Subnet-ECS-DNS-extension\[ra] that ECS-enabled DNS resolvers send only the first three octets (eg. /24) of the source IPv4 address. .SH "EXAMPLES" @@ -196,7 +196,7 @@ l l l l . \fB\fCgeoip/country/name\fR \fB\fCstring\fR \fB\fCUnited Kingdom\fR The country name in English language. \fB\fCgeoip/country/is_in_european_union\fR \fB\fCbool\fR \fB\fCfalse\fR Either \fB\fCtrue\fR or \fB\fCfalse\fR. \fB\fCgeoip/continent/code\fR \fB\fCstring\fR \fB\fCEU\fR See Continent codes -\[la]#ContinentCodes\[ra]. +\[la]#continent-codes\[ra]. \fB\fCgeoip/continent/name\fR \fB\fCstring\fR \fB\fCEurope\fR The continent name in English language. \fB\fCgeoip/latitude\fR \fB\fCfloat64\fR \fB\fC52.2242\fR Base 10, max available precision. \fB\fCgeoip/longitude\fR \fB\fCfloat64\fR \fB\fC0.1315\fR Base 10, max available precision. diff --git a/man/coredns-grpc.7 b/man/coredns-grpc.7 index f2aefd908..44f2cf5a5 100644 --- a/man/coredns-grpc.7 +++ b/man/coredns-grpc.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-GRPC" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-GRPC" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -76,6 +76,12 @@ The server certificate is verified with the system CAs The server certificate is verified using the specified CA file .RE + + +.PP +CoreDNS sets the minimum TLS version to TLS 1.2. The maximum TLS version, TLS 1.2 cipher suites, and +key exchange mechanisms use the Go \fB\fCcrypto/tls\fR defaults. + .IP \(bu 4 \fB\fCtls_servername\fR \fBNAME\fP allows you to set a server name in the TLS configuration; for instance 9.9.9.9 needs this to be set to \fB\fCdns.quad9.net\fR. Multiple upstreams are still allowed in this scenario, diff --git a/man/coredns-hosts.7 b/man/coredns-hosts.7 index 826dd0e68..a12cbd65a 100644 --- a/man/coredns-hosts.7 +++ b/man/coredns-hosts.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-HOSTS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-HOSTS" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -45,6 +45,41 @@ fdfc:a744:27b5:3b0e::1 example.com example .fi .RE +.SS "WILDCARD RECORDS" +.PP +Owner names may use a \fB\fC*\fR as the leftmost label to match one additional label below +that name. This follows the same wildcard semantics as the \fIfile\fP plugin. + +.PP +Examples: + +.PP +.RS + +.nf +192.168.1.10 *.example.com +192.168.1.11 a.example.com +192.168.1.12 b.example.com + +.fi +.RE + +.PP +With the entries above: + +.IP \(bu 4 +\fB\fCa.example.com\fR and \fB\fCb.example.com\fR resolve to their explicit addresses. +.IP \(bu 4 +\fB\fCapps.example.com\fR resolves to \fB\fC192.168.1.10\fR. +.IP \(bu 4 +\fB\fCexample.com\fR does not match the wildcard (the zone apex is excluded). +.IP \(bu 4 +\fB\fCdeep.apps.example.com\fR does not match \fB\fC*.example.com\fR (only one label is matched). + + +.PP +Wildcard entries do not generate PTR records. + .SS "PTR RECORDS" .PP PTR records for reverse lookups are generated automatically by CoreDNS (based on the hosts file @@ -61,6 +96,7 @@ hosts [FILE [ZONES...]] { no\_reverse reload DURATION fallthrough [ZONES...] + fallthrough\_unsupported } .fi @@ -91,6 +127,13 @@ time If \fB[ZONES...]\fP is omitted, then fallthrough happens for all zones for which the plugin is authoritative. If specific zones are listed (for example \fB\fCin-addr.arpa\fR and \fB\fCip6.arpa\fR), then only queries for those zones will be subject to fallthrough. +By default, queries for unsupported record types return an authoritative NODATA response when +the queried name has an A or AAAA entry in the hosts data. +.IP \(bu 4 +\fB\fCfallthrough_unsupported\fR extends \fB\fCfallthrough\fR to unsupported query types when the queried name +exists in the hosts data. For example, TXT, HTTPS, and SVCB queries for a name with an A or AAAA +entry are passed to the next plugin. If that plugin is \fIforward\fP, these queries are sent upstream. +This option requires \fB\fCfallthrough\fR and uses the same zone scope. .SH "METRICS" @@ -167,9 +210,29 @@ example.hosts example.org { .fi .RE +.PP +Resolve all single-label subdomains of \fB\fCexample.com\fR to one address, with explicit +exceptions, and fall through for everything else under \fB\fCexample.com\fR. + +.PP +.RS + +.nf +\&. { + hosts example.hosts example.com { + 192.168.1.10 *.example.com + 192.168.1.11 www.example.com + fallthrough example.com + } + forward . 8.8.8.8 +} + +.fi +.RE + .SH "SEE ALSO" .PP The form of the entries in the \fB\fC/etc/hosts\fR file are based on IETF RFC 952 -\[la]https://tools.ietf.org/html/rfc952\[ra] which was updated by IETF RFC 1123 -\[la]https://tools.ietf.org/html/rfc1123\[ra]. +\[la]https://www.rfc-editor.org/info/rfc952/\[ra] which was updated by IETF RFC 1123 +\[la]https://www.rfc-editor.org/info/rfc1123/\[ra]. diff --git a/man/coredns-https.7 b/man/coredns-https.7 index d164e3071..f22c3b651 100644 --- a/man/coredns-https.7 +++ b/man/coredns-https.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-HTTPS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-HTTPS" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -18,7 +18,8 @@ This plugin can only be used once per HTTPS listener block. .nf https { - max\_connections POSITIVE\_INTEGER + max\_connections NON\_NEGATIVE\_INTEGER + max\_streams NON\_NEGATIVE\_INTEGER } .fi @@ -26,11 +27,13 @@ https { .IP \(bu 4 \fB\fCmax_connections\fR limits the number of concurrent TCP connections to the HTTPS server. The default value is 200 if not specified. Set to 0 for unbounded. +.IP \(bu 4 +\fB\fCmax_streams\fR limits the number of concurrent HTTP/2 streams per HTTPS connection. This helps prevent unbounded streams on a single connection, exhausting server resources. The default value is 250 if not specified. Set to 0 to use the underlying HTTP/2 transport default. .SH "EXAMPLES" .PP -Set custom limits for maximum connections: +Set custom limits for maximum connections and streams: .PP .RS @@ -40,6 +43,7 @@ https://.:443 { tls cert.pem key.pem https { max\_connections 100 + max\_streams 100 } whoami } @@ -48,7 +52,7 @@ https://.:443 { .RE .PP -Set values to 0 for unbounded, matching CoreDNS behaviour before v1.14.0: +Set both values to 0 to disable the CoreDNS limits (unbounded connections and the underlying HTTP/2 transport stream default), matching CoreDNS behaviour before v1.14.0: .PP .RS @@ -58,6 +62,7 @@ https://.:443 { tls cert.pem key.pem https { max\_connections 0 + max\_streams 0 } whoami } diff --git a/man/coredns-https3.7 b/man/coredns-https3.7 index fbcc2c3f2..81b3819b5 100644 --- a/man/coredns-https3.7 +++ b/man/coredns-https3.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-HTTPS3" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-HTTPS3" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -19,6 +19,7 @@ This plugin can only be used once per HTTPS3 listener block. .nf https3 { max\_streams POSITIVE\_INTEGER + max\_connections POSITIVE\_INTEGER } .fi @@ -26,6 +27,8 @@ https3 { .IP \(bu 4 \fB\fCmax_streams\fR limits the number of concurrent QUIC streams per connection. This helps prevent unbounded streams on a single connection, exhausting server resources. The default value is 256 if not specified. Set to 0 to use underlying QUIC transport default. +.IP \(bu 4 +\fB\fCmax_connections\fR limits the number of concurrent HTTPS/3 connections accepted by the server. The default value is 200 if not specified. Connections above the configured limit are rejected. Set to 0 to disable the CoreDNS connection limit. .SH "EXAMPLES" diff --git a/man/coredns-kubernetes.7 b/man/coredns-kubernetes.7 index 06ce806a1..b8ff41474 100644 --- a/man/coredns-kubernetes.7 +++ b/man/coredns-kubernetes.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-KUBERNETES" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-KUBERNETES" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-local.7 b/man/coredns-local.7 index bd0651cec..cbc2b3e31 100644 --- a/man/coredns-local.7 +++ b/man/coredns-local.7 @@ -1,16 +1,16 @@ -.\" Generated by Mmark Markdown Processor - mmark.miek.nl -.TH "COREDNS-LOCAL" 7 "June 2026" "CoreDNS" "CoreDNS Plugins" +.\" Generated by Mmark Markdown Processer - mmark.miek.nl +.TH "COREDNS-LOCAL" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIlocal\fP \- respond to local names. +\fIlocal\fP - respond to local names. .SH "DESCRIPTION" .PP \fIlocal\fP will respond with a basic reply to a "local request". Local requests are defined to be -names in the following zones: localhost, 0.in\-addr.arpa, 127.in\-addr.arpa and 255.in\-addr.arpa, +names in the following zones: localhost, 0.in-addr.arpa, 127.in-addr.arpa and 255.in-addr.arpa, any query under \fB\fC.localhost.\fR, and, by default for backward compatibility, any query prefixed by -\fB\fClocalhost.\fR. When seeing one of the non\-apex localhost forms a metric counter is increased and if +\fB\fClocalhost.\fR. When seeing one of the non-apex localhost forms a metric counter is increased and if \fIdebug\fP is enabled a debug log is emitted. .PP @@ -54,8 +54,8 @@ future release. If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metric is exported: .IP \(bu 4 -\fB\fCcoredns_local_localhost_requests_total{}\fR \- a counter of the number of non\-apex localhost -special\-case queries CoreDNS has seen. This includes \fB\fC.localhost.\fR names and, when +\fB\fCcoredns_local_localhost_requests_total{}\fR - a counter of the number of non-apex localhost +special-case queries CoreDNS has seen. This includes \fB\fC.localhost.\fR names and, when \fB\fClocalhost_prefix\fR is \fB\fCon\fR, legacy \fB\fClocalhost.\fR names. It does \fInot\fP count \fB\fClocalhost.\fR queries. diff --git a/man/coredns-log.7 b/man/coredns-log.7 index 3d1c2ab89..175aed474 100644 --- a/man/coredns-log.7 +++ b/man/coredns-log.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-LOG" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-LOG" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -146,7 +146,7 @@ The default Common Log Format is: .RE .PP -Each of these logs will be outputted with \fB\fClog.Infof\fR, so a typical example looks like this: +In the default text mode, each of these logs is output with \fB\fClog.Info\fR, so a typical example looks like this: .PP .RS @@ -157,6 +157,60 @@ Each of these logs will be outputted with \fB\fClog.Infof\fR, so a typical examp .fi .RE +.SH "JSON OUTPUT" +.PP +Start CoreDNS with \fB\fC-log-format=json\fR to select JSON output for the entire process. +This is a command-line flag, not a Corefile directive. \fB\fC-log-format=text\fR is the default. +The \fB\fClog\fR plugin's name and response-class filters work identically in both modes. + +.PP +Each query produces one JSON record with common fields \fB\fCtime\fR, \fB\fClevel\fR, \fB\fCmsg\fR, and +\fB\fCplugin\fR (always \fB\fClog\fR for query records), plus these typed fields: + +.RS +.TS +allbox; +l l l +l l l . +\fBField\fP\fB Type\fP\fB Meaning\fP +\fB\fCclient_ip\fR string Client address, without brackets around IPv6 addresses +\fB\fCclient_port\fR number Client port +\fB\fCqname\fR string Lowercase, fully qualified query name, in DNS presentation format +\fB\fCqtype\fR, \fB\fCqclass\fR string Query type and class, including numeric forms for unknown values +\fB\fCprotocol\fR string \fB\fCudp\fR or \fB\fCtcp\fR, as for \fB\fC{proto}\fR +\fB\fCid\fR, \fB\fCopcode\fR number Query ID and opcode +\fB\fCrequest_size\fR number Request size in bytes, as for \fB\fC{size}\fR +\fB\fCdnssec_ok\fR boolean Query's DNSSEC OK bit +\fB\fCbufsize\fR number Effective response buffer size, as for \fB\fC{>bufsize}\fR +\fB\fCrcode\fR string or null Response RCODE, or null if no DNS response was recorded +\fB\fCresponse_size\fR number Recorded response size in bytes, as for \fB\fC{rsize}\fR +\fB\fCduration_seconds\fR number Elapsed handling time in seconds +.TE +.RE + + +.PP +As in text mode, response sizes describe recorded, uncompressed messages, not +necessarily the bytes delivered to the client. Deferred errors (such as SERVFAIL) +use the response CoreDNS will generate after the plugin chain returns. A dropped +request has \fB\fCrcode: null\fR; it is not logged as a successful response. Raw \fB\fCWrite\fR +calls contribute to the size but do not provide a decoded response RCODE. + +.PP +\fB\fCFORMAT\fR still controls \fB\fCmsg\fR, including custom formats and metadata placeholders. +It does not replace the JSON schema or define new top-level fields. The DNS fields +come directly from the request and response, not from parsing \fB\fCmsg\fR. For example, +with \fB\fClog . "{name} {rcode}"\fR: + +.PP +.RS + +.nf +{"time":"2026\-09\-15T08:00:00Z","level":"INFO","msg":"example.org. NOERROR","plugin":"log","client\_ip":"127.0.0.1","client\_port":40212,"qname":"example.org.","qtype":"A","qclass":"IN","protocol":"udp","id":42,"opcode":0,"request\_size":29,"dnssec\_ok":false,"bufsize":512,"rcode":"NOERROR","response\_size":29,"duration\_seconds":0.001} + +.fi +.RE + .SH "ADDITIONAL METADATA" .PP The log plugin adds the following metadata to allow for granular differentiation of NOERROR denial vs success messages. These are mapped from \fB\fCplugin/pkg/response/classify.go\fR and \fB\fCplugin/pkg/response/typify.go\fR. diff --git a/man/coredns-metrics.7 b/man/coredns-metrics.7 index 616be427b..8267a7d8b 100644 --- a/man/coredns-metrics.7 +++ b/man/coredns-metrics.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-METRICS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-METRICS" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -93,7 +93,9 @@ This plugin can only be used once per Server Block. .RS .nf -prometheus [ADDRESS] +prometheus [ADDRESS] { + runtime\_metrics +} .fi .RE @@ -105,6 +107,15 @@ For each zone that you want to see metrics for. It optionally takes a bind address to which the metrics are exported; the default listens on \fB\fClocalhost:9153\fR. The metrics path is fixed to \fB\fC/metrics\fR. +.IP \(bu 4 +\fB\fCruntime_metrics\fR exports the full Go runtime/metrics +\[la]https://pkg.go.dev/runtime/metrics\[ra] +set — notably \fB\fCgo_cpu_classes_*\fR for CPU attribution (GC mark/assist/pause vs user code) +and \fB\fCgo_sched_latencies_seconds\fR for goroutine scheduling delay. Adds roughly 100 scalars +and 8 histograms. This is a process-wide latch: enabling it in any server block enables it +for all, and it stays enabled across reloads until restart. + + .SH "EXAMPLES" .PP Use an alternative listening address: diff --git a/man/coredns-nsid.7 b/man/coredns-nsid.7 index 1539229c8..c4a60b074 100644 --- a/man/coredns-nsid.7 +++ b/man/coredns-nsid.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-NSID" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-NSID" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -8,7 +8,7 @@ .SH "DESCRIPTION" .PP This plugin implements RFC 5001 -\[la]https://tools.ietf.org/html/rfc5001\[ra] and adds an EDNS0 OPT +\[la]https://www.rfc-editor.org/info/rfc5001/\[ra] and adds an EDNS0 OPT resource record to replies that uniquely identify the server. This is useful in anycast setups to see which server was responsible for generating the reply and for debugging. @@ -74,5 +74,5 @@ And now a client with NSID support will see an OPT record with the NSID option: .SH "SEE ALSO" .PP RFC 5001 -\[la]https://tools.ietf.org/html/rfc5001\[ra] +\[la]https://www.rfc-editor.org/info/rfc5001/\[ra] diff --git a/man/coredns-proxyproto.7 b/man/coredns-proxyproto.7 index 22afa920c..bbf0ca95e 100644 --- a/man/coredns-proxyproto.7 +++ b/man/coredns-proxyproto.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-PROXYPROTO" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-PROXYPROTO" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -20,6 +20,7 @@ client's IP address and port information. proxyproto { allow default + udp\_session\_tracking [max\_sessions] } .fi @@ -30,10 +31,27 @@ If \fB\fCallow\fR is unspecified, PROXY protocol headers are accepted from all I The \fB\fCdefault\fR option controls how connections from sources not listed in \fB\fCallow\fR are handled. If \fB\fCdefault\fR is unspecified, it defaults to \fB\fCignore\fR. The possible values are: -- \fB\fCuse\fR: accept and use PROXY protocol headers from these sources -- \fB\fCignore\fR: accept and ignore PROXY protocol headers from other sources -- \fB\fCreject\fR: reject connections with PROXY protocol headers from other sources -- \fB\fCskip\fR: skip PROXY protocol processing for connections from other sources, treating them as normal connections preserving the PROXY protocol headers. + +.IP \(bu 4 +\fB\fCuse\fR: accept and use PROXY protocol headers from these sources +.IP \(bu 4 +\fB\fCignore\fR: accept and ignore PROXY protocol headers from other sources +.IP \(bu 4 +\fB\fCreject\fR: reject connections with PROXY protocol headers from other sources +.IP \(bu 4 +\fB\fCskip\fR: skip PROXY protocol processing for connections from other sources, treating them as normal connections preserving the PROXY protocol headers. + + +.PP +The \fB\fCudp_session_tracking [max_sessions]\fR option enables UDP session state tracking +for Cloudflare Spectrum's PROXY Protocol v2 over UDP. Spectrum sends the PPv2 header as a +standalone first datagram (with no DNS payload). Subsequent datagrams from the same client arrive +without any header. When this option is set to a positive duration, the real client address from +the header-only datagram is cached (keyed by the Spectrum-side remote address) for that duration +and automatically applied to all subsequent headerless datagrams within that window. The TTL is +refreshed on each matching packet. The optional \fB\fCmax_sessions\fR argument caps the number of +concurrent sessions in the LRU cache (default: 10240). This option has no effect for TCP +connections. .SH "EXAMPLES" .PP @@ -88,3 +106,41 @@ connections without valid PROXY protocol headers from those sources: .fi .RE +.PP +In this configuration, we enable UDP session tracking for Cloudflare Spectrum's PPv2-over-UDP +with a 28-second TTL (slightly shorter than Spectrum's 30-second UDP idle timeout) and the +default session cap of 10240: + +.PP +.RS + +.nf +\&. { + proxyproto { + allow 192.168.1.1/32 + udp\_session\_tracking 28s + } + forward . /etc/resolv.conf +} + +.fi +.RE + +.PP +In this configuration, the session cap is raised to 20480: + +.PP +.RS + +.nf +\&. { + proxyproto { + allow 192.168.1.1/32 + udp\_session\_tracking 28s 20000 + } + forward . /etc/resolv.conf +} + +.fi +.RE + diff --git a/man/coredns-secondary.7 b/man/coredns-secondary.7 index e47820be2..89d00e37f 100644 --- a/man/coredns-secondary.7 +++ b/man/coredns-secondary.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-SECONDARY" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-SECONDARY" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -39,6 +39,8 @@ A working syntax would be: .nf secondary [zones...] { transfer from ADDRESS [ADDRESS...] + catalog [MEMBER\-ZONES...] + fallthrough [ZONES...] } .fi @@ -48,6 +50,21 @@ secondary [zones...] { \fB\fCtransfer from\fR specifies from which \fBADDRESS\fP to fetch the zone. It can be specified multiple times; if one does not work, another will be tried. Transferring this zone outwards again can be done by enabling the \fItransfer\fP plugin. +.IP \(bu 4 +\fB\fCcatalog\fR treats the transferred zone as an RFC 9432 catalog zone. After each successful catalog +transfer, CoreDNS adds and removes the catalog member zones and transfers those member zones from +the same primary servers. Optional \fBMEMBER-ZONES\fP restrict which member zone names are accepted; +each name also matches its subdomains. With no \fBMEMBER-ZONES\fP, all member zones are accepted for +backward compatibility. RFC 9432 Section 7 recommends configuring this restriction because a +catalog producer otherwise controls which zones the consumer serves. A member in another catalog +remains a name clash unless the current catalog's \fB\fCcoo\fR property points to the newly updated +catalog. During that ownership migration, CoreDNS preserves the current zone data only when both +catalogs use the same member node label. +.IP \(bu 4 +\fB\fCfallthrough\fR If a query for a record in the zone results in NXDOMAIN, the query will be passed +to the next plugin in the chain. If \fB[ZONES...]\fP are listed, then only queries for those zones +will be subject to fallthrough. This can be useful in split DNS setups where the secondary zone +contains only partial records. .PP @@ -91,6 +108,23 @@ example.net { .fi .RE +.PP +Restrict a catalog consumer to member zones at or below \fB\fCexample.org\fR and \fB\fCinternal.example\fR. + +.PP +.RS + +.nf +catalog.example { + secondary { + transfer from 10.1.2.1 + catalog example.org internal.example + } +} + +.fi +.RE + .SH "BUGS" .PP Only AXFR is supported and the retrieved zone is not committed to disk. @@ -98,5 +132,5 @@ Only AXFR is supported and the retrieved zone is not committed to disk. .SH "SEE ALSO" .PP See the \fItransfer\fP plugin to enable zone transfers \fIto\fP other servers. -And RFC 5936 detailing the AXFR protocol. +RFC 5936 details the AXFR protocol, and RFC 9432 defines DNS catalog zones. diff --git a/man/coredns-shed.7 b/man/coredns-shed.7 index 471ca551e..5493fa16c 100644 --- a/man/coredns-shed.7 +++ b/man/coredns-shed.7 @@ -1,14 +1,14 @@ -.\" Generated by Mmark Markdown Processor - mmark.miek.nl -.TH "COREDNS-SHED" 7 "August 2026" "CoreDNS" "CoreDNS Plugins" +.\" Generated by Mmark Markdown Processer - mmark.miek.nl +.TH "COREDNS-SHED" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIshed\fP \- serializes UDP response writes per listener socket and sheds load when the socket cannot keep up. +\fIshed\fP - serializes UDP response writes per listener socket and sheds load when the socket cannot keep up. .SH "DESCRIPTION" .PP UDP responses written back through one listener socket serialize on the Go runtime's internal -fdMutex, which allows at most 2^20\-1 concurrent operations (holders plus waiters) per file +fdMutex, which allows at most 2^20-1 concurrent operations (holders plus waiters) per file descriptor and terminates the process with .PP @@ -23,40 +23,40 @@ panic: too many concurrent operations on a single file or socket (max 1048575) .PP when that is exceeded. CoreDNS serves UDP with one goroutine per query, all writing back through the shared packet connection, so when queries arrive faster than the socket's serialized writes -drain, every excess in\-flight query parks its goroutine in that wait queue and nothing bounds the +drain, every excess in-flight query parks its goroutine in that wait queue and nothing bounds the pile. Observed in production: ~2.8M goroutines and 60GiB RSS before the panic. .PP The \fIshed\fP plugin makes that panic structurally unreachable, per UDP listener socket: .IP \(bu 4 -\fBSingle writer\fP \- responses are not written by the handler goroutine. The packed response is -pushed onto a bounded per\-socket stack (fixed depth 1024) and one writer goroutine per socket +\fBSingle writer\fP - responses are not written by the handler goroutine. The packed response is +pushed onto a bounded per-socket stack (fixed depth 1024) and one writer goroutine per socket performs the wire writes, so the file descriptor never sees more than one writer. The stack evicts the oldest entry when full and the writer pops the newest first, so under overload the socket's residual capacity always goes to the freshest response. The depth is a fixed burst -budget (roughly 12\-16ms of a typical socket's drain rate), not a tunable. +budget (roughly 12-16ms of a typical socket's drain rate), not a tunable. .IP \(bu 4 -\fBCoupled shedding\fP \- while a socket's stack is full, arriving queries on that socket are +\fBCoupled shedding\fP - while a socket's stack is full, arriving queries on that socket are dropped before any plugin runs; work admitted then would only produce a response destined for eviction. There is no configuration: the stack's fullness is the signal. .PP -Drops are silent \- no response is written, so the client's resolver retries against another -server, the standard load\-shedding contract for UDP DNS. Every drop is counted. +Drops are silent - no response is written, so the client's resolver retries against another +server, the standard load-shedding contract for UDP DNS. Every drop is counted. .PP The plugin only acts on UDP; TCP queries pass through untouched. It can only be used in plain DNS server blocks (not \fItls\fP, \fIgrpc\fP, \fIhttps\fP or \fIquic\fP), which is enforced at startup. It should be listed before (above) the \fIprometheus\fP plugin in the plugin chain, so that shed drops are never -counted as handled requests by the \fIprometheus\fP plugin \- which is where this plugin sits by +counted as handled requests by the \fIprometheus\fP plugin - which is where this plugin sits by default. .PP When several server blocks share a listener, any block with \fIshed\fP installs the write discipline -for every write on that socket, while the pre\-chain shedding only runs in blocks that carry the -directive \- keep it uniform across blocks sharing a listener. The discipline covers every response +for every write on that socket, while the pre-chain shedding only runs in blocks that carry the +directive - keep it uniform across blocks sharing a listener. The discipline covers every response written through \fB\fCWriteMsg\fR, which is how every plugin responds; a plugin writing raw bytes with \fB\fCResponseWriter.Write\fR would bypass it. @@ -78,7 +78,7 @@ The plugin takes no arguments. If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metric is exported: .IP \(bu 4 -\fB\fCcoredns_shed_dropped_total{server, reason}\fR \- counter of dropped queries and responses. The +\fB\fCcoredns_shed_dropped_total{server, reason}\fR - counter of dropped queries and responses. The \fB\fCreason\fR label is \fB\fCquery\fR for queries dropped before the plugin chain because the socket's stack was full, and \fB\fCresponse\fR for responses dropped at the write boundary (evicted by a newer response, failed to reach the wire, or arriving during shutdown). diff --git a/man/coredns-siit.7 b/man/coredns-siit.7 index b405e3d72..078dee53d 100644 --- a/man/coredns-siit.7 +++ b/man/coredns-siit.7 @@ -1,9 +1,9 @@ -.\" Generated by Mmark Markdown Processor - mmark.miek.nl -.TH "COREDNS-SIIT" 7 "August 2026" "CoreDNS" "CoreDNS Plugins" +.\" Generated by Mmark Markdown Processer - mmark.miek.nl +.TH "COREDNS-SIIT" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIsiit\fP \- enables AAAA\->A translation support for DNS records based on SIIT (IPv6\->IPv4 translation). +\fIsiit\fP - enables AAAA->A translation support for DNS records based on SIIT (IPv6->IPv4 translation). .SH "DESCRIPTION" .PP @@ -11,10 +11,10 @@ The \fIsiit\fP plugin will when asked for a domain's A record, synthesizes it from a corresponding AAAA record if it belongs to a certain IP range. .PP -It also supports arbitrary mapping IPv6\->IPv4. +It also supports arbitrary mapping IPv6->IPv4. .PP -It is useful when published services are IPv6\-only and emit their AAAA record accordingly +It is useful when published services are IPv6-only and emit their AAAA record accordingly but IPv4 clients reach them through a siit routing. This plugin generates the associated A records for these clients automatically. @@ -56,7 +56,7 @@ siit { If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported: .IP \(bu 4 -\fB\fCcoredns_siit_requests_translated_total{server}\fR \- counter of DNS requests translated +\fB\fCcoredns_siit_requests_translated_total{server}\fR - counter of DNS requests translated .PP @@ -67,15 +67,15 @@ The \fB\fCserver\fR label is explained in the \fIprometheus\fP plugin documentat Prefix matching in eam is not implemented yet. .IP \(bu 4 DNSSEC support is not implemented yet. The problem is the same as DNS64. See: RFC 6147 Section 3 -\[la]https://tools.ietf.org/html/rfc6147#section-3\[ra] +\[la]https://www.rfc-editor.org/info/rfc6147/#section-3\[ra] .SH "SEE ALSO" .PP See RFC 6052 -\[la]https://tools.ietf.org/html/rfc6052\[ra] for more information on the SIIT mechanism +\[la]https://www.rfc-editor.org/info/rfc6052/\[ra] for more information on the SIIT mechanism and RFC 7757 -\[la]https://tools.ietf.org/html/rfc7757\[ra] about the explicit address mappings (eam) mechanism +\[la]https://www.rfc-editor.org/info/rfc7757/\[ra] about the explicit address mappings (eam) mechanism .SH "NOTES" .PP diff --git a/man/coredns-template.7 b/man/coredns-template.7 index 24bafba67..7f6d2cd0e 100644 --- a/man/coredns-template.7 +++ b/man/coredns-template.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-TEMPLATE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-TEMPLATE" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -16,6 +16,8 @@ The \fItemplate\fP plugin allows you to dynamically respond to queries by just w .nf template CLASS TYPE [ZONE...] { match REGEX... + var NAME EXPRESSION + expr EXPRESSION answer RR additional RR authority RR @@ -40,11 +42,19 @@ Specifying no regex matches everything (default: \fB\fC.*\fR). First matching re must not exceed 10000 characters. .IP \(bu 4 \fB\fCanswer|additional|authority\fR \fBRR\fP A RFC 1035 -\[la]https://tools.ietf.org/html/rfc1035#section-5\[ra] style resource record fragment +\[la]https://www.rfc-editor.org/info/rfc1035/#section-5\[ra] style resource record fragment built by a Go template \[la]https://golang.org/pkg/text/template/\[ra] that contains the reply. Specifying no answer will result in a response with an empty answer section. .IP \(bu 4 +\fB\fCvar\fR \fBNAME\fP \fBEXPRESSION\fP sets the variable \fBNAME\fP to the result of \fBEXPRESSION\fP, evaluated for each matching query +and available to the templates as \fB\fC.Var.NAME\fR. Multiple variables may be set; each one may use the variables declared before it. +See the \fBExpressions\fP section. +.IP \(bu 4 +\fB\fCexpr\fR \fBEXPRESSION\fP a condition that must evaluate to \fB\fCtrue\fR for the query to match. All conditions must be true for a +complete match; otherwise the query is subject to \fB\fCfallthrough\fR, as if no regex had matched. Conditions may use the +variables declared with \fB\fCvar\fR. See the \fBExpressions\fP section. +.IP \(bu 4 \fB\fCrcode\fR \fBCODE\fP A response code (\fB\fCNXDOMAIN, SERVFAIL, ...\fR). The default is \fB\fCNOERROR\fR. Valid response code values are per the \fB\fCRcodeToString\fR map defined by the \fB\fCmiekg/dns\fR package in \fB\fCmsg.go\fR. .IP \(bu 4 @@ -85,6 +95,8 @@ Each resource record is a full-featured Go template .IP \(bu 4 \fB\fC.Remote\fR client’s IP address .IP \(bu 4 +\fB\fC.Var\fR the variables defined with \fB\fCvar\fR (e.g. \fB\fC.Var.myvariable\fR). +.IP \(bu 4 \fB\fC.Meta\fR a function that takes a metadata name and returns the value, if the metadata plugin is enabled. For example, \fB\fC.Meta "kubernetes/client-namespace"\fR @@ -100,7 +112,7 @@ and the following predefined template functions .PP The output of the template must be a RFC 1035 -\[la]https://tools.ietf.org/html/rfc1035\[ra] style resource record (commonly referred to as a "zone file"). +\[la]https://www.rfc-editor.org/info/rfc1035/\[ra] style resource record (commonly referred to as a "zone file"). .PP \fBWARNING\fP there is a syntactical problem with Go templates and CoreDNS config files. Expressions @@ -108,6 +120,27 @@ The output of the template must be a RFC 1035 Caddy) while \fB\fC{{ $var }}\fR will work. See Bugs \[la]#bugs\[ra] and corefile(5). +.SH "EXPRESSIONS" +.PP +The \fBEXPRESSION\fP of a \fB\fCvar\fR or \fB\fCexpr\fR is written in the expr language, the same as used by the \fIview\fP plugin. See +https://expr-lang.org/docs/language-definition +\[la]https://expr-lang.org/docs/language-definition\[ra] as a detailed reference for valid syntax. + +.PP +Expressions can reference the DNS query functions and utility functions listed in the \fIview\fP plugin's documentation, the +variables declared by preceding \fB\fCvar\fR options, and + +.IP \(bu 4 +\fB\fCgroup(name string) string\fR: the capture group named \fIname\fP of the matching regex, or \fB\fC""\fR if there is no such group. +.IP \(bu 4 +\fB\fCgroup(index int) string\fR: the \fIindex\fP-th capture group of the matching regex, \fB\fCgroup(0)\fR being the entire match, or \fB\fC""\fR +if there is no such group. + + +.PP +A variable name must be a valid identifier and must not be the name of an existing function, or of a keyword or literal of +the expr language, such as \fB\fClen\fR or \fB\fCtrue\fR. + .SH "METRICS" .PP If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported: @@ -153,7 +186,7 @@ The answer is always NXDOMAIN .SS "RESOLVE .INVALID AS NXDOMAIN" .PP The \fB\fC.invalid\fR domain is a reserved TLD (see RFC 2606 Reserved Top Level DNS Names -\[la]https://tools.ietf.org/html/rfc2606#section-2\[ra]) to indicate invalid domains. +\[la]https://www.rfc-editor.org/info/rfc2606/#section-2\[ra]) to indicate invalid domains. .PP .RS @@ -270,6 +303,44 @@ Having templates to map certain PTR/A pairs is a common pattern. .PP Fallthrough is needed for mixed domains where only some responses are templated. +.SS "RESOLVE DEVICE ADDRESSES FOR HTTPS ON LAN" +.PP +For an embedded device on a local network to be trusted, it needs to have a certificate signed by a +CA and the CA needs to verify that the device controls the name for which it is issued. As the local +address may change, a certificate is issued for the wildcard subdomain \fB\fC*..example.com\fR instead, +where \fB\fC\fR is a unique id for the given device. The same trick as in the example above can be used +to find out the actual IP address. + +.PP +Resolving to public IP addresses would allow for this to be used in phishing attacks, so an +additional expression must be satisfied to limit the allowed IP range. + +.PP +.RS + +.nf +\&. { + forward . 8.8.8.8 + + template IN A example.com { + match ^(?P[0\-9]{1,3}(\-[0\-9]{1,3}){3})[.](?P[a\-z2\-7]{26})[.]example[.]com[.]$ + var ip replace(group('ip'), '\-', '.') + expr "any(['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '169.254.0.0/16'], incidr(ip, #))" + answer "{{ .Name }} 60 IN A {{ .Var.ip }}" + fallthrough + } +} + +.fi +.RE + +.PP +The regular expression for the unique device id matches a base32 encoded string of a 128-bit device +id, with the padding removed. + +.PP +Note that an expression using \fB\fC#\fR must be quoted, or it will be interpreted as a comment. + .SS "RESOLVE HEXADECIMAL IP PATTERN USING PARSEINT" .PP .RS @@ -400,8 +471,8 @@ RE2 syntax reference \[la]https://github.com/google/re2/wiki/Syntax\[ra] for details about the regex syntax .IP \(bu 4 RFC 1034 -\[la]https://tools.ietf.org/html/rfc1034#section-3.6.1\[ra] and RFC 1035 -\[la]https://tools.ietf.org/html/rfc1035#section-5\[ra] for the resource record format +\[la]https://www.rfc-editor.org/info/rfc1034/#section-3.6.1\[ra] and RFC 1035 +\[la]https://www.rfc-editor.org/info/rfc1035/#section-5\[ra] for the resource record format .IP \(bu 4 Go template \[la]https://golang.org/pkg/text/template/\[ra] for the template language reference diff --git a/man/coredns-timeouts.7 b/man/coredns-timeouts.7 index aea2cca9d..f5e9ecdc4 100644 --- a/man/coredns-timeouts.7 +++ b/man/coredns-timeouts.7 @@ -1,9 +1,9 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-TIMEOUTS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-TIMEOUTS" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fItimeouts\fP - allows you to configure the server read, write and idle timeouts for the TCP, TLS, DoH and DoQ (idle only) servers. +\fItimeouts\fP - allows you to configure the supported server read, write and idle timeouts for the TCP, TLS, DoH and DoQ servers, and the maximum number of queries served on a single TCP or TLS connection. .SH "DESCRIPTION" .PP @@ -18,7 +18,8 @@ with such routers. .PP The \fItimeouts\fP "plugin" allows you to configure CoreDNS server read, write and -idle timeouts. +idle timeouts, and the maximum number of queries CoreDNS will serve on a single +TCP or TLS connection before closing it. .SH "SYNTAX" .PP @@ -29,6 +30,7 @@ timeouts { read DURATION write DURATION idle DURATION + maxtcpqueries MAXIMUM } .fi @@ -36,9 +38,27 @@ timeouts { .PP For any timeouts that are not provided, default values are used which may vary -depending on the server type. At least one timeout must be specified otherwise +depending on the server type. At least one option must be specified otherwise the entire timeouts block should be omitted. +.IP \(bu 4 +\fB\fCmaxtcpqueries\fR sets the maximum number of queries served on a single TCP or +TLS connection before CoreDNS closes it. \fBMAXIMUM\fP must be a positive +integer, or \fB\fC-1\fR to allow an unlimited number of queries per connection +(the default). Long-lived connections that serve an unlimited number of +queries can cause uneven load distribution across CoreDNS replicas that sit +behind a connection-based load balancer, since new queries keep reusing the +same connection instead of establishing a new one. Setting a bound, e.g. +\fB\fCmaxtcpqueries 128\fR, forces clients to periodically reconnect, which allows +the load balancer to redistribute load. + + +.PP +The configured timeouts apply where the selected server transport supports +them. TCP, TLS and DoH servers use the read, write and idle timeouts. DoQ +servers use the read timeout to bound receiving a query on an opened QUIC +stream, and the idle timeout to bound idle QUIC connections. + .SH "EXAMPLES" .PP Start a DNS-over-TLS server that picks up incoming DNS-over-TLS queries on port @@ -83,7 +103,8 @@ https://. { .RE .PP -Start a DNS-over-QUIC server that has the idle timeout set to two minutes. +Start a DNS-over-QUIC server that has a 10 second read timeout for receiving a +query on an opened stream and the idle timeout set to two minutes. .PP .RS @@ -92,6 +113,7 @@ Start a DNS-over-QUIC server that has the idle timeout set to two minutes. quic://.:853 { tls cert.pem key.pem ca.pem timeouts { + read 10s idle 2m } forward . /etc/resolv.conf @@ -119,3 +141,22 @@ configured. The timeouts are only applied to the TCP side of the server. .fi .RE +.PP +Start a standard TCP/UDP server that closes a TCP connection after it has +served 128 queries, to help spread load evenly across replicas sitting behind +a connection-based load balancer. + +.PP +.RS + +.nf +\&. { + timeouts { + maxtcpqueries 128 + } + forward . /etc/resolv.conf +} + +.fi +.RE + diff --git a/man/coredns-tls.7 b/man/coredns-tls.7 index ed85d4376..db4d77f22 100644 --- a/man/coredns-tls.7 +++ b/man/coredns-tls.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-TLS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-TLS" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -39,6 +39,7 @@ Parameter CA is optional. If not set, system CAs can be used to verify the clien .nf tls CERT KEY [CA] { client\_auth nocert|request|require|verify\_if\_given|require\_and\_verify + keylog FILE } .fi @@ -51,6 +52,64 @@ The option value corresponds to the ClientAuthType values of the Go tls package The default is "nocert". Note that it makes no sense to specify parameter CA unless this option is set to verify_if_given or require_and_verify. +.PP +The keylog can be specified to export TLS master secrets in key log format to allow external programs +to decrypt TLS connections. It compromises security and should only be used for debugging! + +.PP +CoreDNS sets the minimum TLS version to TLS 1.2. The maximum TLS version, TLS 1.2 cipher suites, and +key exchange mechanisms use the Go \fB\fCcrypto/tls\fR defaults. + +.PP +Certificates can instead be obtained and renewed automatically with ACME: + +.PP +.RS + +.nf +tls { + acme DOMAIN... + email EMAIL + ca URL + storage DIRECTORY + ca\_root FILE + resolver ADDRESS +} + +.fi +.RE + +.PP +The \fB\fCacme\fR property enables automatic certificate management for one or more domain names. CoreDNS +uses the DNS-01 challenge and answers the temporary \fB\fC_acme-challenge\fR TXT queries on every DNS +listener in the same CoreDNS instance. The domains' authoritative DNS must therefore reach this +CoreDNS instance over port 53. HTTP-01 and TLS-ALPN-01 challenges are not used. + +.PP +The remaining properties are optional: + +.IP \(bu 4 +\fB\fCemail\fR sets the ACME account contact address. +.IP \(bu 4 +\fB\fCca\fR sets the ACME directory URL. It defaults to the Let's Encrypt production directory. +.IP \(bu 4 +\fB\fCstorage\fR sets the directory for ACME accounts, certificates, and private keys. It defaults to +\fB\fC.coredns/acme\fR below the Corefile root. +.IP \(bu 4 +\fB\fCca_root\fR adds a PEM certificate bundle for connecting to a private ACME server. +.IP \(bu 4 +\fB\fCresolver\fR sets the DNS resolver used to reach the ACME server and must use \fB\fCHOST:PORT\fR syntax. + + +.PP +Certificate management starts in the background after all listeners are active. A new encrypted +listener can reject TLS handshakes until its first certificate has been obtained. Renewed certificates +are used without restarting CoreDNS. + +.PP +The DNS-01 challenge state is local to one CoreDNS process. When authoritative DNS is served by +multiple replicas, validation queries must be routed to the replica performing the ACME operation. + .SH "EXAMPLES" .PP Start a DNS-over-TLS server that picks up incoming DNS-over-TLS queries on port 5553 and uses the @@ -100,11 +159,35 @@ https://. { .RE .PP -Only Knot DNS' \fB\fCkdig\fR supports DNS-over-TLS queries, no command line client supports gRPC making +Obtain and renew a certificate for a DoT server. The plain DNS server answers the DNS-01 challenge; +both server blocks must be in the same CoreDNS process. + +.PP +.RS + +.nf +\&.:53 { + file example.org +} + +tls://.:853 { + tls { + acme dns.example.org + email hostmaster@example.org + } + forward . /etc/resolv.conf +} + +.fi +.RE + +.PP +Knot DNS' \fB\fCkdig\fR as well as Bind9' \fB\fCdig\fR (since 9.17.7, via \fB\fC+tls\fR) can be used to make DNS-over-TLS queries. No command line client supports gRPC making debugging these transports harder than it should be. .SH "SEE ALSO" .PP -RFC 7858 and https://grpc.io +RFC 7858 +\[la]https://www.rfc-editor.org/info/rfc7858/\[ra] and https://grpc.io \[la]https://grpc.io\[ra]. diff --git a/man/coredns-trace.7 b/man/coredns-trace.7 index 5778df4ec..4a404aa30 100644 --- a/man/coredns-trace.7 +++ b/man/coredns-trace.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-TRACE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-TRACE" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -173,3 +173,4 @@ plugin is also enabled: .SH "SEE ALSO" .PP See the \fIdebug\fP plugin for more information about debug logging. + diff --git a/man/coredns-transfer.7 b/man/coredns-transfer.7 index 97305b4f8..330f5afc1 100644 --- a/man/coredns-transfer.7 +++ b/man/coredns-transfer.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-TRANSFER" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-TRANSFER" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -28,6 +28,7 @@ use this plugin. .nf transfer [ZONE...] { to ADDRESS... + source ADDRESS } .fi @@ -43,6 +44,10 @@ there must be another plugin in the same server block that serves the same zone, addresses. Zone change notifications are sent to all \fBADDRESS\fP that are an IP address or an IP address and port e.g. \fB\fC1.2.3.4\fR, \fB\fC12:34::56\fR, \fB\fC1.2.3.4:5300\fR, \fB\fC[12:34::56]:5300\fR. \fB\fCto\fR may be specified multiple times. +.IP \(bu 4 +\fB\fCsource\fR \fBADDRESS\fP is the local IP address to use when sending zone change +notifications to the configured \fB\fCto\fR addresses. It does not change which +clients are allowed to request AXFR or IXFR transfers. .PP @@ -72,6 +77,23 @@ Use in conjunction with the \fIacl\fP plugin to restrict access to subnet 10.1.0 .fi .RE +.PP +Send NOTIFY messages from a specific local address. + +.PP +.RS + +.nf +\&... + transfer { + to 2001:db8::1 + source 2001:db8::53 + } +\&... + +.fi +.RE + .PP Each plugin that can use \fItransfer\fP includes an example of use in their respective documentation. diff --git a/man/coredns-tsig.7 b/man/coredns-tsig.7 index 9121bb06d..4c9de80cc 100644 --- a/man/coredns-tsig.7 +++ b/man/coredns-tsig.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-TSIG" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-TSIG" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -14,6 +14,11 @@ respective plugins sending those requests to sign them using the keys defined by .PP The \fItsig\fP plugin can also require that incoming requests be signed for certain query types, refusing requests that do not comply. +.PP +After successfully validating a TSIG record, the plugin adds the normalized key name to the request context. Downstream Go +plugins can call \fB\fCtsig.ValidatedKeyName(ctx)\fR to retrieve the key name and distinguish validated requests from unsigned +requests. The value is not set for requests outside the configured zones because the \fItsig\fP plugin does not validate them. + .SH "SYNTAX" .PP .RS @@ -23,6 +28,7 @@ tsig [ZONE...] { secret NAME KEY secrets FILE require [QTYPE...] + require\_opcode [OPCODE...] } .fi @@ -50,14 +56,15 @@ to define multiple secrets. Secrets are global to the server instance, not just Each key may also specify an \fB\fCalgorithm\fR e.g. \fB\fCalgorithm hmac-sha256;\fR, but this is currently ignored by the plugin. - -.RS -.IP \(en 4 +.IP \(bu 4 \fB\fCrequire\fR \fBQTYPE...\fP - the query types that must be TSIG'd. Requests of the specified types -will be \fB\fCREFUSED\fR if they are not signed.\fB\fCrequire all\fR will require requests of all types to be +will be \fB\fCREFUSED\fR if they are not signed. \fB\fCrequire all\fR will require requests of all types to be signed. \fB\fCrequire none\fR will not require requests any types to be signed. Default behavior is to not require. - -.RE +.IP \(bu 4 +\fB\fCrequire_opcode\fR \fBOPCODE...\fP - the opcodes that must be TSIG'd. Requests with the specified opcodes +will be \fB\fCREFUSED\fR if they are not signed. Valid opcodes are: \fB\fCQUERY\fR, \fB\fCIQUERY\fR, \fB\fCSTATUS\fR, \fB\fCNOTIFY\fR, \fB\fCUPDATE\fR. +\fB\fCrequire_opcode all\fR will require requests with all opcodes to be signed. \fB\fCrequire_opcode none\fR will not +require requests with any opcode to be signed. Default behavior is to not require. .SH "EXAMPLES" @@ -99,6 +106,23 @@ auth.zone { .fi .RE +.PP +Require TSIG signed transactions for UPDATE and NOTIFY operations to \fB\fCdynamic.zone\fR. + +.PP +.RS + +.nf +dynamic.zone { + tsig { + secret dynamic.zone.key. NoTCJU+DMqFWywaPyxSijrDEA/eC3nK0xi3AMEZuPVk= + require\_opcode UPDATE NOTIFY + } +} + +.fi +.RE + .SH "BUGS" .SS "SECONDARY" .PP @@ -110,8 +134,8 @@ With the \fItransfer\fP plugin, zone transfer notifications from CoreDNS are not .SS "SPECIAL CONSIDERATIONS FOR FORWARDING SERVERS (RFC 8945 5.5)" .PP -https://datatracker.ietf.org/doc/html/rfc8945#section-5.5 -\[la]https://datatracker.ietf.org/doc/html/rfc8945#section-5.5\[ra] +https://www.rfc-editor.org/info/rfc8945/#section-5.5 +\[la]https://www.rfc-editor.org/info/rfc8945/#section-5.5\[ra] .PP CoreDNS does not implement this section as follows ... diff --git a/man/coredns-view.7 b/man/coredns-view.7 index 9d087b52e..928a97de3 100644 --- a/man/coredns-view.7 +++ b/man/coredns-view.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-VIEW" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-VIEW" 7 "October 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -35,6 +35,16 @@ incoming queries to the enclosing server block. .PP For expression syntax and examples, see the Expressions and Examples sections. +.SH "SERVER BLOCK ORDERING" +.PP +Server blocks sharing the same zone and port are evaluated \fBtop to bottom\fP. The first block whose +view expression matches (or that has no view) handles the query. An unfiltered catch-all block +declared \fIbefore\fP a filtered block will shadow it, because the catch-all matches every query. + +.PP +To get the expected split-DNS behavior, declare all filtered (view) blocks first and the unfiltered +catch-all block last. + .SH "EXAMPLES" .PP Implement CIDR based split DNS routing. This will return a different diff --git a/man/corefile.5 b/man/corefile.5 index d24a35ee4..86d75787e 100644 --- a/man/corefile.5 +++ b/man/corefile.5 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREFILE" 5 "March 2021" "CoreDNS" "CoreDNS" +.TH "COREFILE" 5 "October 2026" "CoreDNS" "CoreDNS" .SH "NAME" .PP @@ -47,6 +47,21 @@ match on the query name will receive the query. server with no plugins will just return SERVFAIL for all queries. Each plugin can have a number of properties than can have arguments, see the documentation for each plugin. +.PP +The Corefile is line oriented: the arguments of a plugin, or of one of its properties, run until the +end of the line. Put each plugin, each property and each closing \fB\fC}\fR on a line of its own. A \fB\fC}\fR that +shares a line with a plugin or a property can be read as part of that line. For example, this fails +with "Unexpected '}' because no matching opening brace": + +.PP +.RS + +.nf +\&. { whoami } + +.fi +.RE + .PP Comments are allowed and begin with an unquoted hash \fB\fC#\fR and continue to the end of the line. Comments may be started anywhere on a line. diff --git a/notes/coredns-008.md b/notes/coredns-008.md index e0c7ab375..39baab9ca 100644 --- a/notes/coredns-008.md +++ b/notes/coredns-008.md @@ -36,7 +36,7 @@ only allows `stdout` as the file name (which of course may be omitted). * Now supports federation records * Has had some other bug fixes. * *file* - * Now supports DNAME [RFC 6672](https://tools.ietf.org/html/rfc6672) + * Now supports DNAME [RFC 6672](https://www.rfc-editor.org/info/rfc6672/) * Refuse to load a zone without a SOA record. * *file, auto* don't reload a zone when the SOA's serial hasn't changed. * *secondary* now behaves properly if queried before the zone has been transferred diff --git a/notes/coredns-1.0.1.md b/notes/coredns-1.0.1.md index e3cb55898..c1e859851 100644 --- a/notes/coredns-1.0.1.md +++ b/notes/coredns-1.0.1.md @@ -11,7 +11,7 @@ author = "coredns" We are pleased to announce the [release](https://github.com/coredns/coredns/releases/tag/v1.0.1) of CoreDNS-1.0.1! This release fixes a crash in the *file* plugin and has some minor bug fixes for other plugins. -One new plugin was added: *nsid*, that implements [RFC 5001](https://tools.ietf.org/html/rfc5001). +One new plugin was added: *nsid*, that implements [RFC 5001](https://www.rfc-editor.org/info/rfc5001/). ## Plugins * *file* fixes a crash when an request with a DO bit (pretty much the default) hits an unsigned zone. The default configuration should recover the go-routine, but this is nonetheless serious. *file* received some other fixes when returning (secure) delegations. diff --git a/notes/coredns-1.5.1.md b/notes/coredns-1.5.1.md index 124f17962..e0f840ef7 100644 --- a/notes/coredns-1.5.1.md +++ b/notes/coredns-1.5.1.md @@ -18,7 +18,7 @@ PR](https://github.com/coredns/coredns/pull/2793) otherwise we'll remove it in t # Plugins -* A new plugin [*any*](/plugins/any) that block ANY queries according to [RFC 8482](https://tools.ietf.org/html/rfc8482) was added. +* A new plugin [*any*](/plugins/any) that block ANY queries according to [RFC 8482](https://www.rfc-editor.org/info/rfc8482/) was added. * Failed reload fixes for: [*ready*](/plugins/ready), [*health*](/plugins/health) and [*prometheus*](/plugins/metrics) - when CoreDNS reloads and the Corefile is invalid these plugins now keep on working. The [*reload*](/plugin/reload) also gained a metric that export failed diff --git a/notes/coredns-1.6.2.md b/notes/coredns-1.6.2.md index f942de7b3..d3b647120 100644 --- a/notes/coredns-1.6.2.md +++ b/notes/coredns-1.6.2.md @@ -13,7 +13,7 @@ The CoreDNS team has released This is a bug fix release, but it also features a new plugin called [*azure*](/plugins/azure). It's compiled with Go 1.12.8 that incorporates fixes for HTTP/2 that may impact you if you use -[DoH](https://tools.ietf.org/html/rfc8484). +[DoH](https://www.rfc-editor.org/info/rfc8484/). # Plugins diff --git a/plugin/any/README.md b/plugin/any/README.md index 25e4ecf4a..d96a72b0f 100644 --- a/plugin/any/README.md +++ b/plugin/any/README.md @@ -8,7 +8,7 @@ ## Description *any* basically blocks ANY queries by responding to them with a short HINFO reply. See [RFC -8482](https://tools.ietf.org/html/rfc8482) for details. +8482](https://www.rfc-editor.org/info/rfc8482/) for details. ## Syntax @@ -33,4 +33,4 @@ example.org. 8482 IN HINFO "ANY obsoleted" "See RFC 8482" ## See Also -[RFC 8482](https://tools.ietf.org/html/rfc8482). +[RFC 8482](https://www.rfc-editor.org/info/rfc8482/). diff --git a/plugin/bufsize/README.md b/plugin/bufsize/README.md index 0dc96235c..173d5a102 100644 --- a/plugin/bufsize/README.md +++ b/plugin/bufsize/README.md @@ -9,7 +9,7 @@ of the request will be reduced. Otherwise the request is unaffected. It prevents IP fragmentation, mitigating certain DNS vulnerabilities. It cannot increase UDP size requested by the client, it can be reduced only. This will only affect queries that have -an OPT RR ([EDNS(0)](https://www.rfc-editor.org/rfc/rfc6891)). +an OPT RR ([EDNS(0)](https://www.rfc-editor.org/info/rfc6891/)). ## Syntax ```txt diff --git a/plugin/dns64/README.md b/plugin/dns64/README.md index 797557485..39c9cf757 100644 --- a/plugin/dns64/README.md +++ b/plugin/dns64/README.md @@ -99,8 +99,8 @@ Not all features required by DNS64 are implemented, only basic AAAA synthesis. * Support "mapping of separate IPv4 ranges to separate IPv6 prefixes" * Resolve PTR records -* Make resolver DNSSEC aware. See: [RFC 6147 Section 3](https://tools.ietf.org/html/rfc6147#section-3) +* Make resolver DNSSEC aware. See: [RFC 6147 Section 3](https://www.rfc-editor.org/info/rfc6147/#section-3) ## See Also -See [RFC 6147](https://tools.ietf.org/html/rfc6147) for more information on the DNS64 mechanism. +See [RFC 6147](https://www.rfc-editor.org/info/rfc6147/) for more information on the DNS64 mechanism. diff --git a/plugin/dns64/dns64.go b/plugin/dns64/dns64.go index f8efdfd9f..ef646f9b1 100644 --- a/plugin/dns64/dns64.go +++ b/plugin/dns64/dns64.go @@ -1,6 +1,6 @@ // Package dns64 implements a plugin that performs DNS64. // -// See: RFC 6147 (https://tools.ietf.org/html/rfc6147) +// See: RFC 6147 (https://www.rfc-editor.org/info/rfc6147/) package dns64 import ( diff --git a/plugin/dnssec/black_lies.go b/plugin/dnssec/black_lies.go index d01fa7c84..2957f356a 100644 --- a/plugin/dnssec/black_lies.go +++ b/plugin/dnssec/black_lies.go @@ -10,7 +10,7 @@ import ( ) // nsec returns an NSEC useful for NXDOMAIN responses. -// See https://tools.ietf.org/html/draft-valsorda-dnsop-black-lies-00 +// See https://datatracker.ietf.org/doc/html/draft-valsorda-dnsop-black-lies-00 // For example, a request for the non-existing name a.example.com would // cause the following NSEC record to be generated: // diff --git a/plugin/dynupdate/README.md b/plugin/dynupdate/README.md index cd718c499..c65467e20 100644 --- a/plugin/dynupdate/README.md +++ b/plugin/dynupdate/README.md @@ -248,6 +248,6 @@ updated zones, not a high-throughput DHCP service. See the *file*, *transfer*, and *tsig* plugins for authoritative data, AXFR/NOTIFY, and TSIG authentication configuration. -* [RFC 2136](https://www.rfc-editor.org/rfc/rfc2136) defines DNS UPDATE. -* [RFC 1982](https://www.rfc-editor.org/rfc/rfc1982) defines DNS serial +* [RFC 2136](https://www.rfc-editor.org/info/rfc2136/) defines DNS UPDATE. +* [RFC 1982](https://www.rfc-editor.org/info/rfc1982/) defines DNS serial number arithmetic. diff --git a/plugin/erratic/README.md b/plugin/erratic/README.md index 5e2b06bc7..3030e3e16 100644 --- a/plugin/erratic/README.md +++ b/plugin/erratic/README.md @@ -9,8 +9,8 @@ *erratic* returns a static response to all queries, but the responses can be delayed, dropped or truncated. The *erratic* plugin will respond to every A or AAAA query. For any other type it will return a SERVFAIL response (except AXFR). The reply for A will return -192.0.2.53 ([RFC 5737](https://tools.ietf.org/html/rfc5737)), for AAAA it returns 2001:DB8::53 ([RFC -3849](https://tools.ietf.org/html/rfc3849)). For an AXFR request it will respond with a small +192.0.2.53 ([RFC 5737](https://www.rfc-editor.org/info/rfc5737/)), for AAAA it returns 2001:DB8::53 ([RFC +3849](https://www.rfc-editor.org/info/rfc3849/)). For an AXFR request it will respond with a small zone transfer. ## Syntax @@ -86,4 +86,4 @@ example.org { ## See Also -[RFC 3849](https://tools.ietf.org/html/rfc3849) and [RFC 5737](https://tools.ietf.org/html/rfc5737). +[RFC 3849](https://www.rfc-editor.org/info/rfc3849/) and [RFC 5737](https://www.rfc-editor.org/info/rfc5737/). diff --git a/plugin/file/README.md b/plugin/file/README.md index 6ebfdf1f0..6e69ec8c7 100644 --- a/plugin/file/README.md +++ b/plugin/file/README.md @@ -64,7 +64,7 @@ example.org { } ~~~ -Where `db.example.org` would contain RRSets () in the +Where `db.example.org` would contain RRSets () in the (text) presentation format from RFC 1035: ~~~ @@ -133,5 +133,5 @@ example.org { See the *loadbalance* plugin if you need simple record shuffling. And the *transfer* plugin for zone transfers. Lastly the *root* plugin can help you specify the location of the zone files. -See [RFC 1035](https://www.rfc-editor.org/rfc/rfc1035.txt) for more info on how to structure zone +See [RFC 1035](https://www.rfc-editor.org/info/rfc1035/) for more info on how to structure zone files. diff --git a/plugin/forward/README.md b/plugin/forward/README.md index 00d8fead1..95f8f8c35 100644 --- a/plugin/forward/README.md +++ b/plugin/forward/README.md @@ -382,8 +382,8 @@ Forward to an upstream identified by hostname, using a specific resolver to look ## See Also -[RFC 7858](https://tools.ietf.org/html/rfc7858) for DNS over TLS. +[RFC 7858](https://www.rfc-editor.org/info/rfc7858/) for DNS over TLS. -[RFC 8484](https://tools.ietf.org/html/rfc8484) for DNS over HTTPS. +[RFC 8484](https://www.rfc-editor.org/info/rfc8484/) for DNS over HTTPS. -[RFC 9250](https://www.rfc-editor.org/rfc/rfc9250.html) for DNS over QUIC. +[RFC 9250](https://www.rfc-editor.org/info/rfc9250/) for DNS over QUIC. diff --git a/plugin/geoip/README.md b/plugin/geoip/README.md index c79e39fac..6f5e3fa43 100644 --- a/plugin/geoip/README.md +++ b/plugin/geoip/README.md @@ -89,7 +89,7 @@ geoip [DBFILE] { **NOTE:** due to security reasons, recursive DNS resolvers may mask a few bits off of the clients' IP address, which can cause inaccuracies in GeoIP resolution. - There is no defined mask size in the standards, but there are examples: [RFC 7871's example](https://datatracker.ietf.org/doc/html/rfc7871#section-13) conceals the last 72 bits of an IPv6 source address, and NS1 Help Center [mentions](https://help.ns1.com/hc/en-us/articles/360020256573-About-the-EDNS-Client-Subnet-ECS-DNS-extension) that ECS-enabled DNS resolvers send only the first three octets (eg. /24) of the source IPv4 address. + There is no defined mask size in the standards, but there are examples: [RFC 7871's example](https://www.rfc-editor.org/info/rfc7871/#section-13) conceals the last 72 bits of an IPv6 source address, and NS1 Help Center [mentions](https://help.ns1.com/hc/en-us/articles/360020256573-About-the-EDNS-Client-Subnet-ECS-DNS-extension) that ECS-enabled DNS resolvers send only the first three octets (eg. /24) of the source IPv4 address. ## Examples diff --git a/plugin/hosts/README.md b/plugin/hosts/README.md index 59570a216..04c0bdd02 100644 --- a/plugin/hosts/README.md +++ b/plugin/hosts/README.md @@ -165,4 +165,4 @@ exceptions, and fall through for everything else under `example.com`. ## See also -The form of the entries in the `/etc/hosts` file are based on IETF [RFC 952](https://tools.ietf.org/html/rfc952) which was updated by IETF [RFC 1123](https://tools.ietf.org/html/rfc1123). +The form of the entries in the `/etc/hosts` file are based on IETF [RFC 952](https://www.rfc-editor.org/info/rfc952/) which was updated by IETF [RFC 1123](https://www.rfc-editor.org/info/rfc1123/). diff --git a/plugin/hosts/hostsfile_test.go b/plugin/hosts/hostsfile_test.go index 2bae28661..59e40f845 100644 --- a/plugin/hosts/hostsfile_test.go +++ b/plugin/hosts/hostsfile_test.go @@ -49,7 +49,7 @@ var ( 123.123.123 loki 321.321.321.321` singlelinehosts = `127.0.0.2 odin` - ipv4hosts = `# See https://tools.ietf.org/html/rfc1123. + ipv4hosts = `# See https://www.rfc-editor.org/info/rfc1123/. # # internet address and host name @@ -58,7 +58,7 @@ var ( # internet address, host name and aliases 127.0.0.3 localhost localhost.localdomain` - ipv6hosts = `# See https://tools.ietf.org/html/rfc5952, https://tools.ietf.org/html/rfc4007. + ipv6hosts = `# See https://www.rfc-editor.org/info/rfc5952/, https://www.rfc-editor.org/info/rfc4007/. # internet address and host name ::1 localhost # inline comment separated by tab diff --git a/plugin/nsid/README.md b/plugin/nsid/README.md index 7bb15ca92..11ae9038d 100644 --- a/plugin/nsid/README.md +++ b/plugin/nsid/README.md @@ -6,7 +6,7 @@ ## Description -This plugin implements [RFC 5001](https://tools.ietf.org/html/rfc5001) and adds an EDNS0 OPT +This plugin implements [RFC 5001](https://www.rfc-editor.org/info/rfc5001/) and adds an EDNS0 OPT resource record to replies that uniquely identify the server. This is useful in anycast setups to see which server was responsible for generating the reply and for debugging. @@ -54,4 +54,4 @@ And now a client with NSID support will see an OPT record with the NSID option: ## See Also -[RFC 5001](https://tools.ietf.org/html/rfc5001) +[RFC 5001](https://www.rfc-editor.org/info/rfc5001/) diff --git a/plugin/siit/README.md b/plugin/siit/README.md index 85dfdff60..2cf7c4362 100644 --- a/plugin/siit/README.md +++ b/plugin/siit/README.md @@ -48,12 +48,12 @@ The `server` label is explained in the _prometheus_ plugin documentation. ## Bugs * Prefix matching in eam is not implemented yet. -* DNSSEC support is not implemented yet. The problem is the same as DNS64. See: [RFC 6147 Section 3](https://tools.ietf.org/html/rfc6147#section-3) +* DNSSEC support is not implemented yet. The problem is the same as DNS64. See: [RFC 6147 Section 3](https://www.rfc-editor.org/info/rfc6147/#section-3) ## See Also -See [RFC 6052](https://tools.ietf.org/html/rfc6052) for more information on the SIIT mechanism -and [RFC 7757](https://tools.ietf.org/html/rfc7757) about the explicit address mappings (eam) mechanism +See [RFC 6052](https://www.rfc-editor.org/info/rfc6052/) for more information on the SIIT mechanism +and [RFC 7757](https://www.rfc-editor.org/info/rfc7757/) about the explicit address mappings (eam) mechanism ## Notes diff --git a/plugin/siit/siit.go b/plugin/siit/siit.go index f964ab543..79eb03223 100644 --- a/plugin/siit/siit.go +++ b/plugin/siit/siit.go @@ -1,7 +1,7 @@ // Package siit implements a plugin that performs AAAA to A translation. // -// See: RFC 6052 (https://tools.ietf.org/html/rfc6052) -// See: RFC 7757 (https://tools.ietf.org/html/rfc7757) +// See: RFC 6052 (https://www.rfc-editor.org/info/rfc6052/) +// See: RFC 7757 (https://www.rfc-editor.org/info/rfc7757/) package siit import ( diff --git a/plugin/template/README.md b/plugin/template/README.md index d043e63e6..eb12adda5 100644 --- a/plugin/template/README.md +++ b/plugin/template/README.md @@ -30,7 +30,7 @@ template CLASS TYPE [ZONE...] { * `match` **REGEX** [Go regexp](https://golang.org/pkg/regexp/) that are matched against the incoming question name. Specifying no regex matches everything (default: `.*`). First matching regex wins. Regex patterns must not exceed 10000 characters. -* `answer|additional|authority` **RR** A [RFC 1035](https://tools.ietf.org/html/rfc1035#section-5) style resource record fragment +* `answer|additional|authority` **RR** A [RFC 1035](https://www.rfc-editor.org/info/rfc1035/#section-5) style resource record fragment built by a [Go template](https://golang.org/pkg/text/template/) that contains the reply. Specifying no answer will result in a response with an empty answer section. * `var` **NAME** **EXPRESSION** sets the variable **NAME** to the result of **EXPRESSION**, evaluated for each matching query @@ -71,7 +71,7 @@ and the following predefined [template functions](https://golang.org/pkg/text/te * `parseInt` interprets a string in the given base and bit size. Equivalent to [strconv.ParseUint](https://golang.org/pkg/strconv#ParseUint). -The output of the template must be a [RFC 1035](https://tools.ietf.org/html/rfc1035) style resource record (commonly referred to as a "zone file"). +The output of the template must be a [RFC 1035](https://www.rfc-editor.org/info/rfc1035/) style resource record (commonly referred to as a "zone file"). **WARNING** there is a syntactical problem with Go templates and CoreDNS config files. Expressions like `{{$var}}` will be interpreted as a reference to an environment variable by CoreDNS (and @@ -123,7 +123,7 @@ The most simplistic template is ### Resolve .invalid as NXDOMAIN -The `.invalid` domain is a reserved TLD (see [RFC 2606 Reserved Top Level DNS Names](https://tools.ietf.org/html/rfc2606#section-2)) to indicate invalid domains. +The `.invalid` domain is a reserved TLD (see [RFC 2606 Reserved Top Level DNS Names](https://www.rfc-editor.org/info/rfc2606/#section-2)) to indicate invalid domains. ~~~ corefile . { @@ -342,7 +342,7 @@ requested type. * [Go regexp](https://golang.org/pkg/regexp/) for details about the regex implementation * [RE2 syntax reference](https://github.com/google/re2/wiki/Syntax) for details about the regex syntax -* [RFC 1034](https://tools.ietf.org/html/rfc1034#section-3.6.1) and [RFC 1035](https://tools.ietf.org/html/rfc1035#section-5) for the resource record format +* [RFC 1034](https://www.rfc-editor.org/info/rfc1034/#section-3.6.1) and [RFC 1035](https://www.rfc-editor.org/info/rfc1035/#section-5) for the resource record format * [Go template](https://golang.org/pkg/text/template/) for the template language reference ## Bugs diff --git a/plugin/tls/README.md b/plugin/tls/README.md index 9f9f8010d..7aec3be5c 100644 --- a/plugin/tls/README.md +++ b/plugin/tls/README.md @@ -128,4 +128,4 @@ debugging these transports harder than it should be. ## See Also -RFC 7858 and https://grpc.io. +[RFC 7858](https://www.rfc-editor.org/info/rfc7858/) and https://grpc.io. diff --git a/plugin/tsig/README.md b/plugin/tsig/README.md index bf325b29a..b236367ce 100644 --- a/plugin/tsig/README.md +++ b/plugin/tsig/README.md @@ -101,7 +101,7 @@ With the *transfer* plugin, zone transfer notifications from CoreDNS are not TSI ### Special Considerations for Forwarding Servers (RFC 8945 5.5) -https://datatracker.ietf.org/doc/html/rfc8945#section-5.5 +https://www.rfc-editor.org/info/rfc8945/#section-5.5 CoreDNS does not implement this section as follows ...