diff --git a/man/coredns-acl.7 b/man/coredns-acl.7 index f03731cc9..7dcbf30ec 100644 --- a/man/coredns-acl.7 +++ b/man/coredns-acl.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-ACL" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ACL" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -7,7 +7,13 @@ .SH "DESCRIPTION" .PP -With \fB\fCacl\fR enabled, users are able to block or filter suspicious DNS queries by configuring IP filter rule sets, i.e. allowing authorized queries to recurse or blocking unauthorized queries. +With \fB\fCacl\fR enabled, users are able to block or filter suspicious DNS queries by configuring IP filter rule sets, i.e. allowing authorized queries or blocking unauthorized queries. + +.PP +When evaluating the rule sets, \fIacl\fP uses the source IP of the TCP/UDP headers of the DNS query received by CoreDNS. +This source IP will be different than the IP of the client originating the request in cases where the source IP of the request is changed in transit. For example: +* if the request passes though an intermediate forwarding DNS server or recursive DNS server before reaching CoreDNS +* if the request traverses a Source NAT before reaching CoreDNS .PP This plugin can be used multiple times per Server Block. @@ -27,7 +33,7 @@ acl [ZONES...] { .IP \(bu 4 \fBZONES\fP zones it should be authoritative for. If empty, the zones from the configuration block are used. .IP \(bu 4 -\fBACTION\fP (\fIallow\fP, \fIblock\fP, or \fIfilter\fP) defines the way to deal with DNS queries matched by this rule. The default action is \fIallow\fP, which means a DNS query not matched by any rules will be allowed to recurse. The difference between \fIblock\fP and \fIfilter\fP is that block returns status code of \fIREFUSED\fP while filter returns an empty set \fINOERROR\fP +\fBACTION\fP (\fIallow\fP, \fIblock\fP, \fIfilter\fP, or \fIdrop\fP) defines the way to deal with DNS queries matched by this rule. The default action is \fIallow\fP, which means a DNS query not matched by any rules will be allowed to recurse. The difference between \fIblock\fP and \fIfilter\fP is that block returns status code of \fIREFUSED\fP while filter returns an empty set \fINOERROR\fP. \fIdrop\fP however returns no response to the client. .IP \(bu 4 \fBQTYPE\fP is the query type to match for the requests to be allowed or blocked. Common resource record types are supported. \fB\fC*\fR stands for all record types. The default behavior for an omitted \fB\fCtype QTYPE...\fR is to match all kinds of DNS queries (same as \fB\fCtype *\fR). .IP \(bu 4 @@ -120,14 +126,34 @@ example.org { .fi .RE +.PP +Drop all DNS queries from 192.0.2.0/24: + +.PP +.RS + +.nf +\&. { + acl { + drop net 192.0.2.0/24 + } +} + +.fi +.RE + .SH "METRICS" .PP If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported: .IP \(bu 4 -\fB\fCcoredns_acl_blocked_requests_total{server, zone}\fR - counter of DNS requests being blocked. +\fB\fCcoredns_acl_blocked_requests_total{server, zone, view}\fR - counter of DNS requests being blocked. .IP \(bu 4 -\fB\fCcoredns_acl_allowed_requests_total{server}\fR - counter of DNS requests being allowed. +\fB\fCcoredns_acl_filtered_requests_total{server, zone, view}\fR - counter of DNS requests being filtered. +.IP \(bu 4 +\fB\fCcoredns_acl_allowed_requests_total{server, view}\fR - counter of DNS requests being allowed. +.IP \(bu 4 +\fB\fCcoredns_acl_dropped_requests_total{server, zone, view}\fR - counter of DNS requests being dropped. .PP diff --git a/man/coredns-any.7 b/man/coredns-any.7 index c17b34ca5..a578a8bf4 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ANY" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-auto.7 b/man/coredns-auto.7 index 2362129d5..6253b9072 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-AUTO" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -34,7 +34,8 @@ are used. used to extract the origin. \fBORIGIN_TEMPLATE\fP will be used as a template for the origin. Strings 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. +name \fB\fCdb.example.com\fR, the extracted origin will be \fB\fCexample.com\fR. \fBREGEXP\fP must not be longer +than 10000 characters. .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-autopath.7 b/man/coredns-autopath.7 index 4840b8ab8..66bb63d06 100644 --- a/man/coredns-autopath.7 +++ b/man/coredns-autopath.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-AUTOPATH" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-AUTOPATH" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -81,7 +81,7 @@ path) in the following case. To properly build the search path of a client \fIau the namespace of the a Pod making a DNS request. To do this, it relies on the \fIkubernetes\fP plugin's Pod cache to resolve the client's IP address to a Pod. The Pod cache is maintained by an API watch on Pods. When Pod IP assignments change, the Kubernetes API notifies CoreDNS via the API watch. -However, that notification is not instantaneous. In the case that a Pod is deleted, and it's IP is +However, that notification is not instantaneous. In the case that a Pod is deleted, and its IP is immediately provisioned to a Pod in another namespace, and that new Pod make a DNS lookup \fIbefore\fP the API watch can notify CoreDNS of the change, \fIautopath\fP will resolve the IP to the previous Pod's namespace. diff --git a/man/coredns-azure.7 b/man/coredns-azure.7 index dc92154fa..07286280d 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-AZURE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-bind.7 b/man/coredns-bind.7 index 2306bca15..7f19afc9b 100644 --- a/man/coredns-bind.7 +++ b/man/coredns-bind.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-BIND" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-BIND" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -17,23 +17,43 @@ If several addresses are provided, a listener will be open on each of the IP pro Each address has to be an IP or name of one of the interfaces of the host. Bind by interface name, binds to the IPs on that interface at the time of startup or reload (reload will happen with a SIGHUP or if the config file changes). .PP -If the given argument is an interface name, and that interface has serveral IP addresses, CoreDNS will listen on all of the interface IP addresses (including IPv4 and IPv6). +If the given argument is an interface name, and that interface has several IP addresses, CoreDNS will listen on all of the interface IP addresses (including IPv4 and IPv6). .SH "SYNTAX" +.PP +In its basic form, a simple bind uses this syntax: + .PP .RS .nf -bind ADDRESS ... +bind ADDRESS|IFACE ... .fi .RE .PP -\fBADDRESS\fP is an IP address to bind to. -When several addresses are provided a listener will be opened on each of the addresses. +You can also exclude some addresses with their IP address or interface name in expanded syntax: + +.PP +.RS + +.nf +bind ADDRESS|IFACE ... { + except ADDRESS|IFACE ... +} + +.fi +.RE + +.IP \(bu 4 +\fBADDRESS|IFACE\fP is an IP address or interface name to bind to. +When several addresses are provided a listener will be opened on each of the addresses. Please read the \fIDescription\fP for more details. +.IP \(bu 4 +\fB\fCexcept\fR, excludes interfaces or IP addresses to bind to. \fB\fCexcept\fR option only excludes addresses for the current \fB\fCbind\fR directive if multiple \fB\fCbind\fR directives are used in the same server block. .SH "EXAMPLES" + .PP To make your socket accessible only to that machine, bind to IP 127.0.0.1 (localhost): @@ -92,12 +112,35 @@ The following server block, binds on localhost with its interface name (both "12 .fi .RE -.SH "BUGS" .PP -When defining more than one server block, take care not to bind more than one server to the same -address and port. Doing so will result in unpredictable behavior (requests may be randomly -served by either server). Keep in mind that \fIwithout\fP the \fIbind\fP plugin, a server will bind to all -interfaces, and this will collide with another server if it's using \fIbind\fP to listen to an interface +You can exclude some addresses by their IP or interface name (The following will only listen on \fB\fC::1\fR or whatever addresses have been assigned to the \fB\fClo\fR interface): + +.PP +.RS + +.nf +\&. { + bind lo { + except 127.0.0.1 + } +} + +.fi +.RE + +.SH "BUGS" +.SS "AVOIDING LISTENER CONTENTION" +.PP +TL;DR, When adding the \fIbind\fP plugin to a server block, it must also be added to all other server blocks that listen on the same port. + +.PP +When more than one server block is configured to listen to a common port, those server blocks must either +all use the \fIbind\fP plugin, or all use default binding (no \fIbind\fP plugin). Note that "port" here refers the TCP/UDP port that +a server block is configured to serve (default 53) - not a network interface. For two server blocks listening on the same port, +if one uses the bind plugin and the other does not, two separate listeners will be created that will contend for serving +packets destined to the same address. Doing so will result in unpredictable behavior (requests may be randomly +served by either server). This happens because \fIwithout\fP the \fIbind\fP plugin, a server will bind to all +interfaces, and this will collide with another server if it's using \fIbind\fP to listen to an address on the same port. For example, the following creates two servers that both listen on 127.0.0.1:53, which would result in unpredictable behavior for queries in \fB\fCa.bad.example.com\fR: diff --git a/man/coredns-bufsize.7 b/man/coredns-bufsize.7 index e5303e363..e21a92618 100644 --- a/man/coredns-bufsize.7 +++ b/man/coredns-bufsize.7 @@ -1,14 +1,20 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-BUFSIZE" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-BUFSIZE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIbufsize\fP - sizes EDNS0 buffer size to prevent IP fragmentation. +\fIbufsize\fP - limits EDNS0 buffer size to prevent IP fragmentation. .SH "DESCRIPTION" .PP -\fIbufsize\fP limits a requester's UDP payload size. +\fIbufsize\fP limits a requester's UDP payload size to within a maximum value. +If a request with an OPT RR has a bufsize greater than the limit, the bufsize +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) +\[la]https://www.rfc-editor.org/rfc/rfc6891\[ra]). .SH "SYNTAX" .PP @@ -22,7 +28,7 @@ bufsize [SIZE] .PP \fB[SIZE]\fP is an int value for setting the buffer size. -The default value is 512, and the value must be within 512 - 4096. +The default value is 1232, and the value must be within 512 - 4096. Only one argument is acceptable, and it covers both IPv4 and IPv6. .SH "EXAMPLES" @@ -34,7 +40,7 @@ Enable limiting the buffer size of outgoing query to the resolver (172.31.0.10): .nf \&. { - bufsize 512 + bufsize 1100 forward . 172.31.0.10 log } @@ -50,7 +56,7 @@ Enable limiting the buffer size as an authoritative nameserver: .nf \&. { - bufsize 512 + bufsize 1220 file db.example.org log } @@ -61,7 +67,5 @@ Enable limiting the buffer size as an authoritative nameserver: .SH "CONSIDERATIONS" .IP \(bu 4 Setting 1232 bytes to bufsize may avoid fragmentation on the majority of networks in use today, but it depends on the MTU of the physical network links. -.IP \(bu 4 -For now, if a client does not use EDNS, this plugin adds OPT RR. diff --git a/man/coredns-cache.7 b/man/coredns-cache.7 index b05eeae3f..2e1a1e9fe 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-CACHE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -12,8 +12,7 @@ With \fIcache\fP enabled, all records except zone transfers and metadata records database, etc.) is expensive. .PP -\fICache\fP will change the query to enable DNSSEC (DNSSEC OK; DO) if it passes through the plugin. If -the client didn't request any DNSSEC (records), these are filtered out when replying. +\fICache\fP will pass DNSSEC (DNSSEC OK; DO) options through the plugin for upstream queries. .PP This plugin can only be used once per Server Block. @@ -38,6 +37,11 @@ Setting a TTL of 300: \fB\fCcache 300\fR would cache records up to 300 seconds. .PP Each element in the cache is cached according to its TTL (with \fBTTL\fP as the max). +Note that \fBTTL\fP only caps the cache duration and does not extend it. A record with a 30s TTL +will still be cached for 30s even with \fB\fCcache 600\fR. The minimum cache duration defaults to 5 +seconds and can be adjusted per cache type using \fBMINTTL\fP in the \fB\fCsuccess\fR or \fB\fCdenial\fR directives. + +.PP A cache is divided into 256 shards, each holding up to 39 items by default - for a total size of 256 * 39 = 9984 items. @@ -52,7 +56,10 @@ cache [TTL] [ZONES...] { success CAPACITY [TTL] [MINTTL] denial CAPACITY [TTL] [MINTTL] prefetch AMOUNT [[DURATION] [PERCENTAGE%]] - serve\_stale [DURATION] + serve\_stale [DURATION] [REFRESH\_MODE] + servfail DURATION + disable success|denial [ZONES...] + keepttl } .fi @@ -76,10 +83,28 @@ Popular means \fBAMOUNT\fP queries have been seen with no gaps of \fBDURATION\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. .IP \(bu 4 -\fB\fCserve_stale\fR, when serve_stale is set, cache always will serve an expired entry to a client if there is one -available. When this happens, cache will attempt to refresh the cache entry after sending the expired cache -entry to the client. The responses have a TTL of 0. \fBDURATION\fP is how far back to consider -stale responses as fresh. The default duration is 1h. +\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 +attempt to refresh the cache entry after sending the expired cache entry to the client. The +responses have a TTL of 0. \fBREFRESH_MODE\fP controls the timing of the expired cache entry refresh. +\fB\fCverify\fR will first verify that an entry is still unavailable from the source before sending the expired entry to the client. +\fB\fCimmediate\fR will immediately send the expired entry to the client before +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. +.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 +greater than 5 minutes. +.IP \(bu 4 +\fB\fCdisable\fR disable the success or denial cache for the listed \fBZONES\fP. If no \fBZONES\fP are given, the specified +cache will be disabled for all zones. +.IP \(bu 4 +\fB\fCkeepttl\fR do not age TTL when serving responses from cache. The entry will still be removed from cache +when the TTL expires as normal, but until it expires responses will include the original TTL instead +of the remaining TTL. This can be useful if CoreDNS is used as an authoritative server and you want +to serve a consistent TTL to downstream clients. This is \fBNOT\fP recommended when CoreDNS is caching +records it is not authoritative for because it could result in downstream clients using stale answers. .SH "CAPACITY AND EVICTION" @@ -98,17 +123,21 @@ Entries with 0 TTL will remain in the cache until randomly evicted when the shar If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported: .IP \(bu 4 -\fB\fCcoredns_cache_entries{server, type}\fR - Total elements in the cache by cache type. +\fB\fCcoredns_cache_entries{server, type, zones, view}\fR - Total elements in the cache by cache type. .IP \(bu 4 -\fB\fCcoredns_cache_hits_total{server, type}\fR - Counter of cache hits by cache type. +\fB\fCcoredns_cache_hits_total{server, type, zones, view}\fR - Counter of cache hits by cache type. .IP \(bu 4 -\fB\fCcoredns_cache_misses_total{server}\fR - Counter of cache misses. +\fB\fCcoredns_cache_misses_total{server, zones, view}\fR - Counter of cache misses. - Deprecated, derive misses from cache hits/requests counters. .IP \(bu 4 -\fB\fCcoredns_cache_prefetch_total{server}\fR - Counter of times the cache has prefetched a cached item. +\fB\fCcoredns_cache_requests_total{server, zones, view}\fR - Counter of cache requests. .IP \(bu 4 -\fB\fCcoredns_cache_drops_total{server}\fR - Counter of responses excluded from the cache due to request/response question name mismatch. +\fB\fCcoredns_cache_prefetch_total{server, zones, view}\fR - Counter of times the cache has prefetched a cached item. .IP \(bu 4 -\fB\fCcoredns_cache_served_stale_total{server}\fR - Counter of requests served from stale cache entries. +\fB\fCcoredns_cache_drops_total{server, zones, view}\fR - Counter of responses excluded from the cache due to request/response question name mismatch. +.IP \(bu 4 +\fB\fCcoredns_cache_served_stale_total{server, zones, view}\fR - Counter of requests served from stale cache entries. +.IP \(bu 4 +\fB\fCcoredns_cache_evictions_total{server, type, zones, view}\fR - Counter of cache evictions. .PP @@ -163,3 +192,19 @@ example.org { .fi .RE +.PP +Enable caching for \fB\fCexample.org\fR, but do not cache denials in \fB\fCsub.example.org\fR: + +.PP +.RS + +.nf +example.org { + cache { + disable denial sub.example.org + } +} + +.fi +.RE + diff --git a/man/coredns-cancel.7 b/man/coredns-cancel.7 index a0c83865b..a1037b03b 100644 --- a/man/coredns-cancel.7 +++ b/man/coredns-cancel.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-CANCEL" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-CANCEL" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-chaos.7 b/man/coredns-chaos.7 index a873d694b..23e815ac2 100644 --- a/man/coredns-chaos.7 +++ b/man/coredns-chaos.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-CHAOS" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-CHAOS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-clouddns.7 b/man/coredns-clouddns.7 index 3b83a3a59..51ac55dd1 100644 --- a/man/coredns-clouddns.7 +++ b/man/coredns-clouddns.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-CLOUDDNS" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-CLOUDDNS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -41,6 +41,13 @@ Therefore, for a non-existing resource record, SOA response will be from the rig accessed. .IP \(bu 4 \fB\fCcredentials\fR is used for reading the credential file from \fBFILENAME\fP (normally a .json file). +This field is optional. If this field is not provided then authentication will be done automatically, +e.g., through environmental variable \fB\fCGOOGLE_APPLICATION_CREDENTIALS\fR. Note that CoreDNS validates that the given +file has a valid credentials type, but does not validate the credentials file for malicious input. Please see +Google Cloud's authentication method +\[la]https://cloud.google.com/docs/authentication\[ra] and +validating credential configurations from external sources +\[la]https://docs.cloud.google.com/docs/authentication/client-libraries#external-credentials\[ra] for more details. .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 diff --git a/man/coredns-debug.7 b/man/coredns-debug.7 index 90ee34961..ab034baec 100644 --- a/man/coredns-debug.7 +++ b/man/coredns-debug.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-DEBUG" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-DEBUG" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-dns64.7 b/man/coredns-dns64.7 index 7a5274cb2..749146038 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-DNS64" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -41,6 +41,7 @@ Or use this slightly longer form with more options: dns64 [PREFIX] { [translate\_all] prefix PREFIX + [allow\_ipv4] } .fi @@ -50,6 +51,8 @@ dns64 [PREFIX] { \fB\fCprefix\fR specifies any local IPv6 prefix to use, instead of the well known prefix (64:ff9b::/96) .IP \(bu 4 \fB\fCtranslate_all\fR translates all queries, including responses that have AAAA results. +.IP \(bu 4 +\fB\fCallow_ipv4\fR Allow translating queries if they come in over IPv4, default is IPv6 only translation. .SH "EXAMPLES" @@ -113,6 +116,25 @@ Enable translation even if an existing AAAA record is present. .fi .RE +.PP +Apply translation even to the requests which arrived over IPv4 network. Warning, the \fB\fCallow_ipv4\fR feature will apply +translations to requests coming from dual-stack clients. This means that a request for a client that sends an \fB\fCAAAA\fR +that would normal result in an \fB\fCNXDOMAIN\fR would get a translated result. +This may cause unwanted IPv6 dns64 traffic when a dualstack client would normally use the result of an \fB\fCA\fR record request. + +.PP +.RS + +.nf +\&. { + dns64 { + allow\_ipv4 + } +} + +.fi +.RE + .SH "METRICS" .PP If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported: diff --git a/man/coredns-dnssec.7 b/man/coredns-dnssec.7 index 7376e6b03..d4c724973 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-DNSSEC" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -20,7 +20,7 @@ This plugin can only be used once per Server Block. .nf dnssec [ZONES... ] { - key file KEY... + key file|aws\_secretsmanager KEY... cache\_capacity CAPACITY } @@ -39,10 +39,13 @@ ZSK/KSK split. All signing operations are done online. Authenticated denial of existence is implemented with NSEC black lies. Using ECDSA as an algorithm is preferred as this leads to smaller signatures (compared to RSA). NSEC3 is \fInot\fP supported. +.PP +As the \fIdnssec\fP plugin can't see the original TTL of the RRSets it signs, it will always use 3600s +as the value. + .PP If multiple \fIdnssec\fP plugins are specified in the same zone, the last one specified will be -used (See bugs -\[la]#bugs\[ra]). +used. .IP \(bu 4 \fBZONES\fP zones that should be signed. If empty, the zones from the configuration block @@ -62,6 +65,36 @@ generated public key \fB\fCKexample.org+013+45330.key\fR generated private key \fB\fCKexample.org+013+45330.private\fR .RE +.IP \(bu 4 +\fB\fCkey aws_secretsmanager\fR indicates that \fBKEY\fP secret(s) should be read from AWS Secrets Manager. Secret +names or ARNs may be used. After generating the keys as described in the \fB\fCkey file\fR section, you can +store them in AWS Secrets Manager using the following AWS CLI v2 command: + + +.PP +.RS + +.nf + aws secretsmanager create\-secret \-\-name "Kexample.org.+013+45330" \\ + \-\-description "DNSSEC keys for example.org" \\ + \-\-secret\-string "$(jq \-n \-\-arg key "$(cat Kexample.org.+013+45330.key)" \\ + \-\-arg private "$(cat Kexample.org.+013+45330.private)" \\ + '{key: $key, private: $private}')" + +.fi +.RE + +.PP +This command reads the contents of the \fB\fC.key\fR and \fB\fC.private\fR files, constructs a JSON object, and stores it + as a new secret in AWS Secrets Manager with the specified name and description. CoreDNS will then fetch + the key data from AWS Secrets Manager when using the \fB\fCkey aws_secretsmanager\fR directive. + +.PP +AWS SDK for Go V2 +\[la]https://aws.github.io/aws-sdk-go-v2/docs/configuring-sdk/#specifying-credentials\[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. + .IP \(bu 4 \fB\fCcache_capacity\fR indicates the capacity of the cache. The dnssec plugin uses a cache to store RRSIGs. The default for \fBCAPACITY\fP is 10000. @@ -100,6 +133,24 @@ example.org { .fi .RE +.PP +Sign responses for \fB\fCexample.org\fR with the key stored in AWS Secrets Manager under the secret name +"Kexample.org.+013+45330". + +.PP +.RS + +.nf +example.org { + dnssec { + key aws\_secretsmanager Kexample.org.+013+45330 + } + whoami +} + +.fi +.RE + .PP Sign responses for a kubernetes zone with the key "Kcluster.local+013+45129.key". diff --git a/man/coredns-dnstap.7 b/man/coredns-dnstap.7 index 6d3990250..a94c5c421 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-DNSTAP" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -20,7 +20,12 @@ Every message is sent to the socket as soon as it comes in, the \fIdnstap\fP plu .RS .nf -dnstap SOCKET [full] +dnstap SOCKET [full] [writebuffer] [queue] { + [identity IDENTITY] + [version VERSION] + [extra EXTRA] + [skipverify] +} .fi .RE @@ -29,6 +34,19 @@ dnstap SOCKET [full] \fBSOCKET\fP is the socket (path) supplied to the dnstap command line tool. .IP \(bu 4 \fB\fCfull\fR to include the wire-format DNS message. +.IP \(bu 4 +\fBwritebuffer\fP sets the TCP write buffer multiplier in MiB. Valid range: [1, 1024]. +.IP \(bu 4 +\fBqueue\fP sets the queue multiplier, applied to 10,000 messages. Valid range: [1, 4096]. +.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\fCskipverify\fR to skip tls verification during connection. Default to be secure .SH "EXAMPLES" @@ -44,6 +62,18 @@ dnstap /tmp/dnstap.sock .fi .RE +.PP +Log information about client requests and responses with a custom TCP write buffer (1024 MiB) and queue capacity (2048 x 10000). + +.PP +.RS + +.nf +dnstap /tmp/dnstap.sock full 1024 2048 + +.fi +.RE + .PP Log information including the wire-format DNS message about client requests and responses to \fI/tmp/dnstap.sock\fP. @@ -68,6 +98,78 @@ dnstap tcp://127.0.0.1:6000 full .fi .RE +.PP +Log to a remote endpoint by FQDN. + +.PP +.RS + +.nf +dnstap tcp://example.com:6000 full + +.fi +.RE + +.PP +Log to a socket, overriding the default identity and version. + +.PP +.RS + +.nf +dnstap /tmp/dnstap.sock { + identity my\-dns\-server1 + version MyDNSServer\-1.2.3 +} + +.fi +.RE + +.PP +Log to a socket, customize the "extra" field in dnstap payload. You may use metadata provided by other plugins in the extra field. + +.PP +.RS + +.nf +forward . 8.8.8.8 +metadata +dnstap /tmp/dnstap.sock { + extra "upstream: {/forward/upstream}" +} + +.fi +.RE + +.PP +Log to a remote TLS endpoint. + +.PP +.RS + +.nf +dnstap tls://127.0.0.1:6000 full { + 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, +and also sends client requests and responses without wire-format DNS messages to a remote FQDN. + +.PP +.RS + +.nf +dnstap /tmp/dnstap.sock full +dnstap tcp://example.com:6000 + +.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 @@ -112,16 +214,18 @@ $ dnstap \-l 127.0.0.1:6000 .SH "USING DNSTAP IN YOUR PLUGIN" .PP -In your setup function, check to see if the \fIdnstap\fP plugin is loaded: +In your setup function, collect and store a list of all \fIdnstap\fP plugins loaded in the config: .PP .RS .nf +x := \&ExamplePlugin{} + c.OnStartup(func() error { if taph := dnsserver.GetConfig(c).Handler("dnstap"); taph != nil { - if tapPlugin, ok := taph.(dnstap.Dnstap); ok { - f.tapPlugin = \&tapPlugin + for tapPlugin, ok := taph.(*dnstap.Dnstap); ok; tapPlugin, ok = tapPlugin.Next.(*dnstap.Dnstap) { + x.tapPlugins = append(x.tapPlugins, tapPlugin) } } return nil @@ -137,8 +241,15 @@ And then in your plugin: .RS .nf -func (x RandomPlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - if tapPlugin != nil { +import ( + "github.com/coredns/coredns/plugin/dnstap/msg" + "github.com/coredns/coredns/request" + + tap "github.com/dnstap/golang\-dnstap" +) + +func (x ExamplePlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + for \_, tapPlugin := range x.tapPlugins { q := new(msg.Msg) msg.SetQueryTime(q, time.Now()) msg.SetQueryAddress(q, w.RemoteAddr()) @@ -147,7 +258,12 @@ func (x RandomPlugin) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns q.QueryMessage = buf } msg.SetType(q, tap.Message\_CLIENT\_QUERY) + + // if no metadata interpretation is needed, just send the message tapPlugin.TapMessage(q) + + // OR: to interpret the metadata in "extra" field, give more context info + tapPlugin.TapMessageWithMetadata(ctx, q, request.Request{W: w, Req: query}) } // ... } diff --git a/man/coredns-erratic.7 b/man/coredns-erratic.7 index c85153658..71d88c4d5 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ERRATIC" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-errors.7 b/man/coredns-errors.7 index b296fa324..7357a5956 100644 --- a/man/coredns-errors.7 +++ b/man/coredns-errors.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-ERRORS" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ERRORS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -33,14 +33,19 @@ Extra knobs are available with an expanded syntax: .nf errors { - consolidate DURATION REGEXP + stacktrace + consolidate DURATION REGEXP [LEVEL] [show\_first] } .fi .RE .PP -Option \fB\fCconsolidate\fR allows collecting several error messages matching the regular expression \fBREGEXP\fP during \fBDURATION\fP. After the \fBDURATION\fP since receiving the first such message, the consolidated message will be printed to standard output, e.g. +Option \fB\fCstacktrace\fR will log a stacktrace during panic recovery. + +.PP +Option \fB\fCconsolidate\fR allows collecting several error messages matching the regular expression \fBREGEXP\fP during \fBDURATION\fP. \fBREGEXP\fP must not exceed 10000 characters. After the \fBDURATION\fP since receiving the first such message, the consolidated message will be printed to standard output with +log level, which is configurable by optional option \fBLEVEL\fP. Supported options for \fBLEVEL\fP option are \fB\fCwarning\fR,\fB\fCerror\fR,\fB\fCinfo\fR and \fB\fCdebug\fR. .PP .RS @@ -51,6 +56,36 @@ Option \fB\fCconsolidate\fR allows collecting several error messages matching th .fi .RE +.PP +If the optional \fB\fCshow_first\fR flag is specified, the first error will be logged immediately when it occurs, and then subsequent matching errors will be consolidated. When the consolidation period ends: +- If only one error occurred, no summary is printed (since it was already logged) +- If multiple errors occurred, a summary is printed showing the total count + +.PP +Example with 3 errors: + +.PP +.RS + +.nf +[WARNING] 2 example.org. A: read udp 10.0.0.1:53\->8.8.8.8:53: i/o timeout +[WARNING] 3 errors like '^read udp .* i/o timeout$' occurred in last 30s + +.fi +.RE + +.PP +Example with 1 error: + +.PP +.RS + +.nf +[WARNING] 2 example.org. A: read udp 10.0.0.1:53\->8.8.8.8:53: i/o timeout + +.fi +.RE + .PP Multiple \fB\fCconsolidate\fR options with different \fBDURATION\fP and \fBREGEXP\fP are allowed. In case if some error message corresponds to several defined regular expressions the message will be associated with the first appropriate \fBREGEXP\fP. @@ -74,7 +109,9 @@ example.org { .RE .PP -Use the \fIforward\fP to resolve queries via 8.8.8.8 and print consolidated error messages for errors with suffix " i/o timeout" or with prefix "Failed to ". +Use the \fIforward\fP plugin to resolve queries via 8.8.8.8 and print consolidated messages +for errors with suffix " i/o timeout" as warnings, +and errors with prefix "Failed to " as errors. .PP .RS @@ -83,7 +120,7 @@ Use the \fIforward\fP to resolve queries via 8.8.8.8 and print consolidated erro \&. { forward . 8.8.8.8 errors { - consolidate 5m ".* i/o timeout$" + consolidate 5m ".* i/o timeout$" warning consolidate 30s "^Failed to .+" } } @@ -91,3 +128,22 @@ Use the \fIforward\fP to resolve queries via 8.8.8.8 and print consolidated erro .fi .RE +.PP +Use the \fIforward\fP plugin and consolidate timeout errors with \fB\fCshow_first\fR option to see both +the summary and the first occurrence of the error: + +.PP +.RS + +.nf +\&. { + forward . 8.8.8.8 + errors { + consolidate 5m ".* i/o timeout$" warning show\_first + consolidate 30s "^Failed to .+" error show\_first + } +} + +.fi +.RE + diff --git a/man/coredns-etcd.7 b/man/coredns-etcd.7 index f3484adde..0a384f727 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 "August 2025" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-ETCD" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-file.7 b/man/coredns-file.7 index 972ac3d47..14f395825 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 "May 2025" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-FILE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-forward.7 b/man/coredns-forward.7 index c6f608d24..4d88c558d 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-FORWARD" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -22,9 +22,6 @@ is taken as a healthy upstream. The health check uses the same protocol as speci When \fIall\fP upstreams are down it assumes health checking as a mechanism has failed and will try to connect to a random upstream (which may or may not work). -.PP -This plugin can only be used once per Server Block. - .SH "SYNTAX" .PP In its most basic form, a simple forwarder uses this syntax: @@ -39,7 +36,8 @@ forward FROM TO... .RE .IP \(bu 4 -\fBFROM\fP is the base domain to match for the request to be forwarded. +\fBFROM\fP is the base domain to match for the request to be forwarded. Domains using CIDR notation +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 @@ -62,12 +60,17 @@ forward FROM TO... { force\_tcp prefer\_udp expire DURATION + max\_idle\_conns INTEGER max\_fails INTEGER + max\_connect\_attempts INTEGER tls CERT KEY CA tls\_servername NAME policy random|round\_robin|sequential - health\_check DURATION [no\_rec] + health\_check DURATION [no\_rec] [domain FQDN] max\_concurrent MAX + next RCODE\_1 [RCODE\_2] [RCODE\_3...] + failfast\_all\_unhealthy\_upstreams + failover RCODE\_1 [RCODE\_2] [RCODE\_3...] } .fi @@ -89,8 +92,15 @@ Requests that match none of these names will be passed through. 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. +.IP \(bu 4 \fB\fCexpire\fR \fBDURATION\fP, expire (cached) connections after this time, the default is 10s. .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. +.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 @@ -109,9 +119,18 @@ 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. Multiple upstreams are still allowed in this scenario, -but they have to use the same \fB\fCtls_servername\fR. E.g. mixing 9.9.9.9 (QuadDNS) with 1.1.1.1 -(Cloudflare) will not work. +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. + \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 + 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. + .IP \(bu 4 \fB\fCpolicy\fR specifies the policy to use for selecting upstream servers. The default is \fB\fCrandom\fR. @@ -133,6 +152,9 @@ but they have to use the same \fB\fCtls_servername\fR. E.g. mixing 9.9.9.9 (Quad .IP \(en 4 \fB\fCno_rec\fR - optional argument that sets the RecursionDesired-flag of the dns-query used in health checking to \fB\fCfalse\fR. The flag is default \fB\fCtrue\fR. +.IP \(en 4 +\fB\fCdomain FQDN\fR - set the domain name used for health checks to \fBFQDN\fP. +If not configured, the domain name used for health checks is \fB\fC.\fR. .RE .IP \(bu 4 @@ -141,17 +163,23 @@ raise the number of concurrent queries above the \fBMAX\fP will result in a REFU response does not count as a health failure. When choosing a value for \fBMAX\fP, pick a number at least greater than the expected \fIupstream query rate\fP * \fIlatency\fP of the upstream servers. As an upper bound for \fBMAX\fP, consider that each concurrent query will use about 2kb of memory. +.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\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. .PP Also note the TLS config is "global" for the whole forwarding proxy if you need a different -\fB\fCtls-name\fR for different upstreams you're out of luck. +\fB\fCtls_servername\fR for different upstreams you're out of luck. .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 100ms based on early results. +The dial timeout by default is 30s, and can decrease automatically down to 1s based on early results. .IP \(bu 4 The read timeout is static at 2s. @@ -170,28 +198,35 @@ plugin is also enabled: If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metric are exported: .IP \(bu 4 -\fB\fCcoredns_forward_requests_total{to}\fR - query count per upstream. -.IP \(bu 4 -\fB\fCcoredns_forward_responses_total{to}\fR - Counter of responses received per upstream. -.IP \(bu 4 -\fB\fCcoredns_forward_request_duration_seconds{to, rcode, type}\fR - duration per upstream, RCODE, type -.IP \(bu 4 -\fB\fCcoredns_forward_responses_total{to, rcode}\fR - count of RCODEs per upstream. -.IP \(bu 4 -\fB\fCcoredns_forward_healthcheck_failures_total{to}\fR - number of failed health checks per upstream. -.IP \(bu 4 -\fB\fCcoredns_forward_healthcheck_broken_total{}\fR - counter of when all upstreams are unhealthy, +\fB\fCcoredns_forward_healthcheck_broken_total{}\fR - count of when all upstreams are unhealthy, and we are randomly (this always uses the \fB\fCrandom\fR policy) spraying to an upstream. .IP \(bu 4 -\fB\fCcoredns_forward_max_concurrent_rejects_total{}\fR - counter of the number of queries rejected because the +\fB\fCcoredns_forward_max_concurrent_rejects_total{}\fR - count of queries rejected because the number of concurrent queries were at maximum. .IP \(bu 4 -\fB\fCcoredns_forward_conn_cache_hits_total{to, proto}\fR - counter of connection cache hits per upstream and protocol. +\fB\fCcoredns_proxy_request_duration_seconds{proxy_name="forward", to, rcode}\fR - histogram per upstream, RCODE .IP \(bu 4 -\fB\fCcoredns_forward_conn_cache_misses_total{to, proto}\fR - counter of connection cache misses per upstream and protocol. +\fB\fCcoredns_proxy_healthcheck_failures_total{proxy_name="forward", to, rcode}\fR- count of failed health checks per upstream. +.IP \(bu 4 +\fB\fCcoredns_proxy_conn_cache_hits_total{proxy_name="forward", to, proto}\fR- count of connection cache hits per upstream and protocol. +.IP \(bu 4 +\fB\fCcoredns_proxy_conn_cache_misses_total{proxy_name="forward", to, proto}\fR - count of connection cache misses per upstream and protocol. + + +.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. +.PP +The following metrics have recently been deprecated: +* \fB\fCcoredns_forward_healthcheck_failures_total{to, rcode}\fR + * Can be replaced with \fB\fCcoredns_proxy_healthcheck_failures_total{proxy_name="forward", to, rcode}\fR +* \fB\fCcoredns_forward_requests_total{to}\fR + * Can be replaced with \fB\fCsum(coredns_proxy_request_duration_seconds_count{proxy_name="forward", to})\fR +* \fB\fCcoredns_forward_responses_total{to, rcode}\fR + * Can be replaced with \fB\fCcoredns_proxy_request_duration_seconds_count{proxy_name="forward", to, rcode}\fR +* \fB\fCcoredns_forward_request_duration_seconds{to, rcode}\fR + * Can be replaced with \fB\fCcoredns_proxy_request_duration_seconds{proxy_name="forward", to, rcode}\fR .SH "EXAMPLES" .PP @@ -208,6 +243,52 @@ example.org { .fi .RE +.PP +Send all requests within \fB\fClab.example.local.\fR to \fB\fC10.20.0.1\fR, all requests within \fB\fCexample.local.\fR (and not in +\fB\fClab.example.local.\fR) to \fB\fC10.0.0.1\fR, all others requests to the servers defined in \fB\fC/etc/resolv.conf\fR, and +caches results. Note that a CoreDNS server configured with multiple \fIforward\fP plugins in a server block will evaluate those +forward plugins in the order they are listed when serving a request. Therefore, subdomains should be +placed before parent domains otherwise subdomain requests will be forwarded to the parent domain's upstream. +Accordingly, in this example \fB\fClab.example.local\fR is before \fB\fCexample.local\fR, and \fB\fCexample.local\fR is before \fB\fC.\fR. + +.PP +.RS + +.nf +\&. { + cache + forward lab.example.local 10.20.0.1 + forward example.local 10.0.0.1 + forward . /etc/resolv.conf +} + +.fi +.RE + +.PP +The example above is almost equivalent to the following example, except that example below defines three separate plugin +chains (and thus 3 separate instances of \fIcache\fP). + +.PP +.RS + +.nf +lab.example.local { + cache + forward . 10.20.0.1 +} +example.local { + cache + forward . 10.0.0.1 +} +\&. { + cache + forward . /etc/resolv.conf +} + +.fi +.RE + .PP Load balance all requests between three resolvers, one of which has a IPv6 address. @@ -275,6 +356,24 @@ service with health checks. .fi .RE +.PP +Or configure other domain name for health check requests + +.PP +.RS + +.nf +\&. { + forward . tls://9.9.9.9 { + tls\_servername dns.quad9.net + health\_check 5s domain example.org + } + cache 30 +} + +.fi +.RE + .PP Or with multiple upstreams from the same provider @@ -305,13 +404,13 @@ Or when you have multiple DoT upstreams with different \fB\fCtls_servername\fRs, } \&.:5301 { - forward . 8.8.8.8 8.8.4.4 { + forward . tls://8.8.8.8 tls://8.8.4.4 { tls\_servername dns.google } } \&.:5302 { - forward . 1.1.1.1 1.0.0.1 { + forward . tls://1.1.1.1 tls://1.0.0.1 { tls\_servername cloudflare\-dns.com } } @@ -319,6 +418,44 @@ Or when you have multiple DoT upstreams with different \fB\fCtls_servername\fRs, .fi .RE +.PP +The following would try 1.2.3.4 first. If the response is \fB\fCNXDOMAIN\fR, try 5.6.7.8. If the response from 5.6.7.8 is \fB\fCNXDOMAIN\fR, try 9.0.1.2. + +.PP +.RS + +.nf +\&. { + forward . 1.2.3.4 { + next NXDOMAIN + } + forward . 5.6.7.8 { + next NXDOMAIN + } + forward . 9.0.1.2 { + } +} + +.fi +.RE + +.PP +In the following example, if the response from \fB\fC1.2.3.4\fR is \fB\fCSERVFAIL\fR or \fB\fCREFUSED\fR, it will try \fB\fC5.6.7.8\fR. If the response from \fB\fC5.6.7.8\fR is \fB\fCSERVFAIL\fR or \fB\fCREFUSED\fR, it will try \fB\fC9.0.1.2\fR. + +.PP +.RS + +.nf +\&. { + forward . 1.2.3.4 5.6.7.8 9.0.1.2 { + policy sequential + failover SERVFAIL REFUSED + } +} + +.fi +.RE + .SH "SEE ALSO" .PP RFC 7858 diff --git a/man/coredns-geoip.7 b/man/coredns-geoip.7 index 28104259d..7d2b54db1 100644 --- a/man/coredns-geoip.7 +++ b/man/coredns-geoip.7 @@ -1,17 +1,20 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-GEOIP" 7 "July 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-GEOIP" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIgeoip\fP - Lookup maxmind geoip2 databases using the client IP, then add associated geoip data to the context request. +\fIgeoip\fP - Lookup \fB\fC.mmdb\fR (MaxMind db file format +\[la]https://maxmind.github.io/MaxMind-DB/\[ra]) databases using the client IP, then add associated geoip data to the context request. .SH "DESCRIPTION" .PP -The \fIgeoip\fP plugin add geo location data associated with the client IP, it allows you to configure a geoIP2 maxmind database -\[la]https://dev.maxmind.com/geoip/docs/databases\[ra] to add the geo location data associated with the IP address. +The \fIgeoip\fP plugin allows you to enrich the data associated with Client IP addresses, e.g. geoip information like City, Country, and Network ASN. GeoIP data is commonly available in the \fB\fC.mmdb\fR format, a database format that maps IPv4 and IPv6 addresses to data records using a binary search tree. .PP -The data is added leveraging the \fImetadata\fP plugin, values can then be retrieved using it as well, for example: +The data is added leveraging the \fImetadata\fP plugin, values can then be retrieved using it as well. + +.PP +\fBLongitude example:\fP .PP .RS @@ -34,13 +37,64 @@ if getLongitude := metadata.ValueFunc(ctx, "geoip/longitude"); getLongitude != n .fi .RE -.SH "DATABASES" .PP -The supported databases use city schema such as \fB\fCCity\fR and \fB\fCEnterprise\fR. Other databases types with different schemas are not supported yet. +\fBCity example:\fP .PP -You can download a free and public City database -\[la]https://dev.maxmind.com/geoip/geolite2-free-geolocation-data\[ra]. +.RS + +.nf +import ( + "github.com/coredns/coredns/plugin/metadata" +) +// ... +if getCity := metadata.ValueFunc(ctx, "geoip/city/name"); getCity != nil { + city := getCity() + // Do something useful with city. +} else { + // The metadata label geoip/city/name for some reason, was not set. +} +// ... + +.fi +.RE + +.PP +\fBASN example:\fP + +.PP +.RS + +.nf +import ( + "strconv" + "github.com/coredns/coredns/plugin/metadata" +) +// ... +if getASN := metadata.ValueFunc(ctx, "geoip/asn/number"); getASN != nil { + if asn, err := strconv.ParseUint(getASN(), 10, 32); err == nil { + // Do something useful with asn. + } +} +if getASNOrg := metadata.ValueFunc(ctx, "geoip/asn/org"); getASNOrg != nil { + asnOrg := getASNOrg() + // Do something useful with asnOrg. +} +// ... + +.fi +.RE + +.SH "DATABASES" +.PP +The supported databases use city schema such as \fB\fCASN\fR, \fB\fCCity\fR, and \fB\fCEnterprise\fR. \fB\fC.mmdb\fR files are generally supported, as long as their field names correctly map to the Metadata Labels below. Other database types with different schemas are not supported yet. + +.PP +Free and commercial GeoIP \fB\fC.mmdb\fR files are commonly available from vendors like MaxMind +\[la]https://dev.maxmind.com/geoip/docs/databases\[ra], IPinfo +\[la]https://ipinfo.io/developers/database-download\[ra], and IPtoASN +\[la]https://iptoasn.com/\[ra] which is Public Domain-licensed +\[la]https://opendatacommons.org/licenses/pddl/1-0/\[ra]. .SH "SYNTAX" .PP @@ -52,34 +106,88 @@ geoip [DBFILE] .fi .RE -.IP \(bu 4 -\fBDBFILE\fP the mmdb database file path. +.PP +or +.PP +.RS + +.nf +geoip [DBFILE] { + [edns\-subnet] +} + +.fi +.RE + +.IP \(bu 4 +\fBDBFILE\fP the \fB\fCmmdb\fR database file path. We recommend updating your \fB\fCmmdb\fR database periodically for more accurate results. +.IP \(bu 4 +\fB\fCedns-subnet\fR: Optional. Use EDNS0 subnet +\[la]https://en.wikipedia.org/wiki/EDNS_Client_Subnet\[ra] (if present) for Geo IP instead of the source IP of the DNS request. This helps identifying the closest source IP address through intermediary DNS resolvers, and it also makes GeoIP testing easy: \fB\fCdig +subnet=1.2.3.4 @dns-server.example.com www.geo-aware.com\fR. + + +.PP +\fBNOTE:\fP 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. + +.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://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" .PP -The following configuration configures the \fB\fCCity\fR database. +The following configuration configures the \fB\fCCity\fR database, and looks up geolocation based on EDNS0 subnet if present. .PP .RS .nf \&. { - geoip /opt/geoip2/db/GeoLite2\-City.mmdb + geoip /opt/geoip2/db/GeoLite2\-City.mmdb { + edns\-subnet + } metadata # Note that metadata plugin must be enabled as well. } .fi .RE -.SH "METADATADA LABELS" +.PP +The \fIview\fP plugin can use \fIgeoip\fP metadata as selection criteria to provide GSLB functionality. +In this example, clients from the city "Exampleshire" will receive answers for \fB\fCexample.com\fR from the zone defined in +\fB\fCexample.com.exampleshire-db\fR. All other clients will receive answers from the zone defined in \fB\fCexample.com.db\fR. +Note that the order of the two \fB\fCexample.com\fR server blocks below is important; the default viewless server block +must be last. + +.PP +.RS + +.nf +example.com { + view exampleshire { + expr metadata('geoip/city/name') == 'Exampleshire' + } + geoip /opt/geoip2/db/GeoLite2\-City.mmdb + metadata + file example.com.exampleshire\-db +} + +example.com { + file example.com.db +} + +.fi +.RE + +.SH "METADATA LABELS" .PP A limited set of fields will be exported as labels, all values are stored using strings \fBregardless of their underlying value type\fP, and therefore you may have to convert it back to its original type, note that numeric values are always represented in base 10. .RS .TS allbox; -l l l l +l l l l l l l l . \fBLabel\fP\fB Type\fP\fB Example\fP\fB Description\fP \fB\fCgeoip/city/name\fR \fB\fCstring\fR \fB\fCCambridge\fR Then city name in English language. @@ -94,6 +202,10 @@ l l l l . \fB\fCgeoip/longitude\fR \fB\fCfloat64\fR \fB\fC0.1315\fR Base 10, max available precision. \fB\fCgeoip/timezone\fR \fB\fCstring\fR \fB\fCEurope/London\fR The timezone. \fB\fCgeoip/postalcode\fR \fB\fCstring\fR \fB\fCCB4\fR The postal code. +\fB\fCgeoip/subdivisions/code\fR \fB\fCstring\fR \fB\fCENG,TWH\fR Comma separated ISO 3166-2 +\[la]https://en.wikipedia.org/wiki/ISO_3166-2\[ra] subdivision(region) codes, e.g. first level (province), second level (state). +\fB\fCgeoip/asn/number\fR \fB\fCuint\fR \fB\fC396982\fR The autonomous system number. +\fB\fCgeoip/asn/org\fR \fB\fCstring\fR \fB\fCGOOGLE-CLOUD-PLATFORM\fR The autonomous system organization. .TE .RE @@ -102,7 +214,7 @@ l l l l . .RS .TS allbox; -l l +l l l l . \fBValue\fP\fB Continent (EN)\fP AF Africa @@ -116,3 +228,11 @@ SA South America .RE +.SH "NOTABLE CHANGES" +.IP \(bu 4 +In CoreDNS v1.13.2, the \fB\fCgeoip\fR plugin was upgraded to use \fB\fCoschwald/geoip2-golang/v2\fR +\[la]https://github.com/oschwald/geoip2-golang/blob/main/MIGRATION.md\[ra], the Go library that reads and parses \fB\fC.mmdb\fR +\[la]https://maxmind.github.io/MaxMind-DB/\[ra] databases. It has a small, but possibly-breaking change, where the \fB\fCLocation.Latitude\fR and \fB\fCLocation.Longitude\fR structs changed from value types to pointers (\fB\fCfloat64\fR → \fB\fC*float64\fR). In \fB\fCoschwald/geoip2-golang\fR v1, missing coordinates returned "0" (which is a valid location +\[la]https://en.wikipedia.org/wiki/Null_Island\[ra]), and in v2 they now return an empty string "". + + diff --git a/man/coredns-grpc.7 b/man/coredns-grpc.7 index d286cda0e..f2aefd908 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-GRPC" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -48,6 +48,7 @@ grpc FROM TO... { tls CERT KEY CA tls\_servername NAME policy random|round\_robin|sequential + fallthrough [ZONES...] } .fi @@ -82,6 +83,13 @@ but they have to use the same \fB\fCtls_servername\fR. E.g. mixing 9.9.9.9 (Quad (Cloudflare) will not work. .IP \(bu 4 \fB\fCpolicy\fR specifies the policy to use for selecting upstream servers. The default is \fB\fCrandom\fR. +.IP \(bu 4 +\fB\fCfallthrough\fR \fB[ZONES...]\fP If a query results in NXDOMAIN from the gRPC backend, pass the request +to the next plugin instead of returning the NXDOMAIN response. This is useful when the gRPC backend +is authoritative for a zone but should not return authoritative NXDOMAIN responses for queries that +don't actually belong to that zone (e.g., search path queries). If \fB[ZONES...]\fP is omitted, then +fallthrough happens for all zones. If specific zones are listed, then only queries for those zones +will be subject to fallthrough. .PP @@ -198,6 +206,37 @@ Or with multiple upstreams from the same provider .fi .RE +.PP +Forward requests to a local upstream listening on a Unix domain socket. + +.PP +.RS + +.nf +\&. { + grpc . unix:///path/to/grpc.sock +} + +.fi +.RE + +.PP +Proxy requests for \fB\fCexample.org.\fR to a gRPC backend, but fallthrough to the next plugin for NXDOMAIN responses to handle search path queries correctly. + +.PP +.RS + +.nf +example.org { + grpc . 127.0.0.1:9005 { + fallthrough + } + forward . 8.8.8.8 +} + +.fi +.RE + .SH "BUGS" .PP The TLS config is global for the whole grpc proxy if you need a different \fB\fCtls_servername\fR for diff --git a/man/coredns-grpc_server.7 b/man/coredns-grpc_server.7 new file mode 100644 index 000000000..3dfa8b25f --- /dev/null +++ b/man/coredns-grpc_server.7 @@ -0,0 +1,72 @@ +.\" Generated by Mmark Markdown Processer - mmark.miek.nl +.TH "COREDNS-GRPC_SERVER" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" + +.SH "NAME" +.PP +\fIgrpc_server\fP - configures DNS-over-gRPC server options. + +.SH "DESCRIPTION" +.PP +The \fIgrpc_server\fP plugin allows you to configure parameters for the DNS-over-gRPC server to fine-tune the security posture and performance of the server. + +.PP +This plugin can only be used once per gRPC listener block. + +.SH "SYNTAX" +.PP +.RS + +.nf +grpc\_server { + max\_streams POSITIVE\_INTEGER + max\_connections POSITIVE\_INTEGER +} + +.fi +.RE + +.IP \(bu 4 +\fB\fCmax_streams\fR limits the number of concurrent gRPC 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 for unbounded. +.IP \(bu 4 +\fB\fCmax_connections\fR limits the number of concurrent TCP connections to the gRPC server. The default value is 200 if not specified. Set to 0 for unbounded. + + +.SH "EXAMPLES" +.PP +Set custom limits for maximum streams and connections: + +.PP +.RS + +.nf +grpc://.:8053 { + tls cert.pem key.pem + grpc\_server { + max\_streams 50 + max\_connections 100 + } + whoami +} + +.fi +.RE + +.PP +Set values to 0 for unbounded, matching CoreDNS behaviour before v1.14.0: + +.PP +.RS + +.nf +grpc://.:8053 { + tls cert.pem key.pem + grpc\_server { + max\_streams 0 + max\_connections 0 + } + whoami +} + +.fi +.RE + diff --git a/man/coredns-header.7 b/man/coredns-header.7 index c0e76e46d..0dbd89718 100644 --- a/man/coredns-header.7 +++ b/man/coredns-header.7 @@ -1,14 +1,14 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-HEADER" 7 "July 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-HEADER" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIheader\fP - modifies the header for responses. +\fIheader\fP - modifies the header for queries and responses. .SH "DESCRIPTION" .PP -\fIheader\fP ensures that the flags are in the desired state for responses. The modifications are made transparently for -the client. +\fIheader\fP ensures that the flags are in the desired state for queries and responses. +The modifications are made transparently for the client and subsequent plugins. .SH "SYNTAX" .PP @@ -16,13 +16,15 @@ the client. .nf header { - ACTION FLAGS... - ACTION FLAGS... + SELECTOR ACTION FLAGS... + SELECTOR ACTION FLAGS... } .fi .RE +.IP \(bu 4 +\fBSELECTOR\fP defines if the action should be applied on \fB\fCquery\fR or \fB\fCresponse\fR. .IP \(bu 4 \fBACTION\fP defines the state for DNS message header flags. Actions are evaluated in the order they are defined so last one has the most precedence. Allowed values are: @@ -58,7 +60,7 @@ Make sure recursive available \fB\fCra\fR flag is set in all the responses: .nf \&. { header { - set ra + response set ra } } @@ -74,8 +76,24 @@ Make sure "recursion available" \fB\fCra\fR and "authoritative answer" \fB\fCaa\ .nf \&. { header { - set ra aa - clear rd + response set ra aa + response clear rd + } +} + +.fi +.RE + +.PP +Make sure "recursion desired" \fB\fCrd\fR is set for all subsequent plugins:: + +.PP +.RS + +.nf +\&. { + header { + query set rd } } diff --git a/man/coredns-health.7 b/man/coredns-health.7 index 388d4e96c..0db899642 100644 --- a/man/coredns-health.7 +++ b/man/coredns-health.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-HEALTH" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-HEALTH" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -40,7 +40,7 @@ health [ADDRESS] { .IP \(bu 4 Where \fB\fClameduck\fR will delay shutdown for \fBDURATION\fP. /health will still answer 200 OK. -Note: The \fIready\fP plugin will not answer OK while CoreDNS is in lameduck mode prior to shutdown. +Note: The \fIready\fP plugin will not answer OK while CoreDNS is in lame duck mode prior to shutdown. .PP @@ -69,16 +69,19 @@ Doing this is supported but both endpoints ":8080" and ":8081" will export the e .SH "METRICS" .PP -If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metric is exported: +If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported: .IP \(bu 4 -\fB\fCcoredns_health_request_duration_seconds{}\fR - duration to process a HTTP query to the local -\fB\fC/health\fR endpoint. As this a local operation it should be fast. A (large) increase in this +\fB\fCcoredns_health_request_duration_seconds{}\fR - The \fIhealth\fP plugin performs a self health check +once per second on the \fB\fC/health\fR endpoint. This metric is the duration to process that request. +As this is a local operation it should be fast. A (large) increase in this duration indicates the CoreDNS process is having trouble keeping up with its query load. +.IP \(bu 4 +\fB\fCcoredns_health_request_failures_total{}\fR - The number of times the self health check failed. .PP -Note that this metric \fIdoes not\fP have a \fB\fCserver\fR label, because being overloaded is a symptom of +Note that these metrics \fIdo not\fP have a \fB\fCserver\fR label, because being overloaded is a symptom of the running process, \fInot\fP a specific server. .SH "EXAMPLES" @@ -98,7 +101,7 @@ Run another health endpoint on http://localhost:8091 .RE .PP -Set a lameduck duration of 1 second: +Set a lame duck duration of 1 second: .PP .RS diff --git a/man/coredns-hosts.7 b/man/coredns-hosts.7 index 72bf9a908..826dd0e68 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-HOSTS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP diff --git a/man/coredns-https.7 b/man/coredns-https.7 new file mode 100644 index 000000000..d164e3071 --- /dev/null +++ b/man/coredns-https.7 @@ -0,0 +1,67 @@ +.\" Generated by Mmark Markdown Processer - mmark.miek.nl +.TH "COREDNS-HTTPS" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" + +.SH "NAME" +.PP +\fIhttps\fP - configures DNS-over-HTTPS (DoH) server options. + +.SH "DESCRIPTION" +.PP +The \fIhttps\fP plugin allows you to configure parameters for the DNS-over-HTTPS (DoH) server to fine-tune the security posture and performance of the server. + +.PP +This plugin can only be used once per HTTPS listener block. + +.SH "SYNTAX" +.PP +.RS + +.nf +https { + max\_connections POSITIVE\_INTEGER +} + +.fi +.RE + +.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. + + +.SH "EXAMPLES" +.PP +Set custom limits for maximum connections: + +.PP +.RS + +.nf +https://.:443 { + tls cert.pem key.pem + https { + max\_connections 100 + } + whoami +} + +.fi +.RE + +.PP +Set values to 0 for unbounded, matching CoreDNS behaviour before v1.14.0: + +.PP +.RS + +.nf +https://.:443 { + tls cert.pem key.pem + https { + max\_connections 0 + } + whoami +} + +.fi +.RE + diff --git a/man/coredns-https3.7 b/man/coredns-https3.7 new file mode 100644 index 000000000..fbcc2c3f2 --- /dev/null +++ b/man/coredns-https3.7 @@ -0,0 +1,67 @@ +.\" Generated by Mmark Markdown Processer - mmark.miek.nl +.TH "COREDNS-HTTPS3" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" + +.SH "NAME" +.PP +\fIhttps3\fP - configures DNS-over-HTTPS/3 (DoH3) server options. + +.SH "DESCRIPTION" +.PP +The \fIhttps3\fP plugin allows you to configure parameters for the DNS-over-HTTPS/3 (DoH3) server to fine-tune the security posture and performance of the server. HTTPS/3 uses QUIC as the underlying transport. + +.PP +This plugin can only be used once per HTTPS3 listener block. + +.SH "SYNTAX" +.PP +.RS + +.nf +https3 { + max\_streams POSITIVE\_INTEGER +} + +.fi +.RE + +.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. + + +.SH "EXAMPLES" +.PP +Set custom limits for maximum streams: + +.PP +.RS + +.nf +https3://.:443 { + tls cert.pem key.pem + https3 { + max\_streams 50 + } + whoami +} + +.fi +.RE + +.PP +Set values to 0 for QUIC transport default, matching CoreDNS behaviour before v1.14.0: + +.PP +.RS + +.nf +https3://.:443 { + tls cert.pem key.pem + https3 { + max\_streams 0 + } + whoami +} + +.fi +.RE + diff --git a/man/coredns-import.7 b/man/coredns-import.7 index dda17a022..57dd1e1a3 100644 --- a/man/coredns-import.7 +++ b/man/coredns-import.7 @@ -1,5 +1,5 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-IMPORT" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-IMPORT" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -29,6 +29,9 @@ import PATTERN this line, as if that file's contents appeared here to begin with. +.PP +Corefile may contain at most 10000 import statements. A glob pattern counts as a single import. The limit protects the configuration from recursive imports. + .SH "FILES" .PP You can use \fIimport\fP to include a file or files. This file's location is relative to the diff --git a/man/coredns-k8s_external.7 b/man/coredns-k8s_external.7 index f0b902e49..657620c73 100644 --- a/man/coredns-k8s_external.7 +++ b/man/coredns-k8s_external.7 @@ -1,19 +1,18 @@ .\" Generated by Mmark Markdown Processer - mmark.miek.nl -.TH "COREDNS-K8S_EXTERNAL" 7 "March 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-K8S_EXTERNAL" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP -\fIk8s_external\fP - resolves load balancer and external IPs from outside Kubernetes clusters. +\fIk8s_external\fP - resolves load balancer, external IPs from outside Kubernetes clusters and if enabled headless services. .SH "DESCRIPTION" .PP This plugin allows an additional zone to resolve the external IP address(es) of a Kubernetes -service. This plugin is only useful if the \fIkubernetes\fP plugin is also loaded. +service and headless services. This plugin is only useful if the \fIkubernetes\fP plugin is also loaded. .PP The plugin uses an external zone to resolve in-cluster IP addresses. It only handles queries for A, -AAAA and SRV records; all others result in NODATA responses. To make it a proper DNS zone, it handles -SOA and NS queries for the apex of the zone. +AAAA, SRV, and PTR records; To make it a proper DNS zone, it handles SOA and NS queries for the apex of the zone. .PP By default the apex of the zone will look like the following (assuming the zone used is \fB\fCexample.org\fR): @@ -82,6 +81,38 @@ k8s\_external [ZONE...] { \fB\fCttl\fR allows you to set a custom \fBTTL\fP for responses. The default is 5 (seconds). +.PP +If you want to enable headless service resolution, you can do so by adding \fB\fCheadless\fR option. + +.PP +.RS + +.nf +k8s\_external [ZONE...] { + headless +} + +.fi +.RE + +.IP \(bu 4 +if there is a headless service with external IPs set, external IPs will be resolved + + +.PP +If the queried domain does not exist, you can fall through to next plugin by adding the \fB\fCfallthrough\fR option. + +.PP +.RS + +.nf +k8s\_external [ZONE...] { + fallthrough [ZONE...] +} + +.fi +.RE + .SH "EXAMPLES" .PP Enable names under \fB\fCexample.org\fR to be resolved to in-cluster DNS addresses. @@ -119,12 +150,46 @@ spec: .fi .RE +.PP +The \fIk8s_external\fP plugin can be used in conjunction with the \fItransfer\fP plugin to enable +zone transfers. Notifies are not supported. + +.PP +.RS + +.nf + . { + transfer example.org { + to * + } + kubernetes cluster.local + k8s\_external example.org + } + +.fi +.RE + +.PP +With the \fB\fCfallthrough\fR option, if the queried domain does not exist, it will be passed to the next plugin that matches the zone. + +.PP +.RS + +.nf +\&. { + kubernetes cluster.local + k8s\_external example.org { + fallthrough + } + forward . 8.8.8.8 +} + +.fi +.RE + .PP For some background see resolve external IP address \[la]https://github.com/kubernetes/dns/issues/242\[ra]. And A records for services with Load Balancer IP \[la]https://github.com/coredns/coredns/issues/1851\[ra]. -.PP -PTR queries for the reverse zone is not supported. - diff --git a/man/coredns-kubernetes.7 b/man/coredns-kubernetes.7 index 078c73d60..06ce806a1 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 2021" "CoreDNS" "CoreDNS Plugins" +.TH "COREDNS-KUBERNETES" 7 "March 2026" "CoreDNS" "CoreDNS Plugins" .SH "NAME" .PP @@ -50,6 +50,9 @@ kubernetes [ZONES...] { endpoint URL tls CERT KEY CACERT kubeconfig KUBECONFIG [CONTEXT] + apiserver\_qps QPS + apiserver\_burst BURST + apiserver\_max\_inflight MAX namespaces NAMESPACE... labels EXPRESSION pods POD\-MODE @@ -58,6 +61,8 @@ kubernetes [ZONES...] { noendpoints fallthrough [ZONES...] ignore empty\_service + multicluster [ZONES...] + startup\_timeout DURATION } .fi @@ -65,7 +70,8 @@ kubernetes [ZONES...] { .IP \(bu 4 \fB\fCendpoint\fR specifies the \fBURL\fP for a remote k8s API endpoint. -If omitted, it will connect to k8s in-cluster using the cluster service account. +If omitted, it will connect to k8s in-cluster using the cluster service account. Needs \fB\fCtls\fR for clusters with authentication. +This option is ignored if \fB\fCkubeconfig\fR is set. .IP \(bu 4 \fB\fCtls\fR \fBCERT\fP \fBKEY\fP \fBCACERT\fP are the TLS cert, key and the CA cert file names for remote k8s connection. This option is ignored if connecting in-cluster (i.e. endpoint is not specified). @@ -73,7 +79,16 @@ This option is ignored if connecting in-cluster (i.e. endpoint is not specified) \fB\fCkubeconfig\fR \fBKUBECONFIG [CONTEXT]\fP authenticates the connection to a remote k8s cluster using a kubeconfig file. \fB[CONTEXT]\fP is optional, if not set, then the current context specified in kubeconfig will be used. It supports TLS, username and password, or token-based authentication. -This option is ignored if connecting in-cluster (i.e., the endpoint is not specified). +This option is ignored if omitted. The cluster address in the \fB\fCkubeconfig\fR is given preference. +.IP \(bu 4 +\fB\fCapiserver_qps\fR \fBQPS\fP sets the maximum queries per second (QPS) rate limit for requests. +This allows you to control the rate at which the plugin sends requests to the API server to prevent overwhelming it. +.IP \(bu 4 +\fB\fCapiserver_burst\fR \fBBURST\fP sets the maximum burst size for requests. +This allows temporary spikes in request rate up to this value, even if it exceeds the QPS limit. +.IP \(bu 4 +\fB\fCapiserver_max_inflight\fR \fBMAX\fP sets the maximum number of concurrent in-flight requests. +This caps the total number of simultaneous requests the plugin can make to the API server. .IP \(bu 4 \fB\fCnamespaces\fR \fBNAMESPACE [NAMESPACE...]\fP only exposes the k8s namespaces listed. If this option is omitted all namespaces are exposed @@ -120,7 +135,7 @@ IP address (e.g., \fB\fC1-2-3-4.my-service.namespace.svc.cluster.local.\fR) If this directive is included, then name selection for endpoints changes as follows: Use the hostname of the endpoint, or if hostname is not set, use the pod name of the pod targeted by the endpoint. If there is no pod targeted by -the endpoint, use the dashed IP address form. +the endpoint or pod name is longer than 63, use the dashed IP address form. .IP \(bu 4 \fB\fCttl\fR allows you to set a custom TTL for responses. The default is 5 seconds. The minimum TTL allowed is 0 seconds, and the maximum is capped at 3600 seconds. Setting TTL to 0 will prevent records from being cached. @@ -138,16 +153,41 @@ queries for those zones will be subject to fallthrough. \fB\fCignore empty_service\fR returns NXDOMAIN for services without any ready endpoint addresses (e.g., ready pods). This allows the querying pod to continue searching for the service in the search path. The search path could, for example, include another Kubernetes cluster. +.IP \(bu 4 +\fB\fCmulticluster\fR defines the multicluster zones as defined by Multi-Cluster +Services API (MCS-API). Specifying this option is generally paired with the +installation of an MCS-API implementation and the ServiceImport and ServiceExport +CRDs. The plugin MUST be authoritative for the zones listed here. +.IP \(bu 4 +\fB\fCstartup_timeout\fR specifies the \fBDURATION\fP value that limits the time to wait for informer cache synced +when the kubernetes plugin starts. If not specified, the default timeout will be 5s. .PP Enabling zone transfer is done by using the \fItransfer\fP plugin. +.SH "STARTUP" +.PP +When CoreDNS starts with the \fIkubernetes\fP plugin enabled, it will delay serving DNS for up to 5 seconds +until it can connect to the Kubernetes API and synchronize all object watches. If this cannot happen within +5 seconds, then CoreDNS will start serving DNS while the \fIkubernetes\fP plugin continues to try to connect +and synchronize all object watches. CoreDNS will answer SERVFAIL to any request made for a Kubernetes record +that has not yet been synchronized. You can also determine how long to wait by specifying \fB\fCstartup_timeout\fR. + +.SH "MONITORING KUBERNETES ENDPOINTS" +.PP +The \fIkubernetes\fP plugin watches Endpoints via the \fB\fCdiscovery.EndpointSlices\fR API. + .SH "READY" .PP This plugin reports readiness to the ready plugin. This will happen after it has synced to the Kubernetes API. +.SH "PTR RECORDS" +.PP +This plugin creates PTR records for every Pod selected by a Service. If a given Pod is selected by more than +one Service a separate PTR record will exist for each Service selecting it. + .SH "EXAMPLES" .PP Handle all queries in the \fB\fCcluster.local\fR zone. Connect to Kubernetes in-cluster. Also handle all @@ -196,6 +236,20 @@ kubernetes cluster.local { .fi .RE +.PP +Configure multicluster + +.PP +.RS + +.nf +kubernetes cluster.local clusterset.local { + multicluster clusterset.local +} + +.fi +.RE + .SH "STUBDOMAINS AND UPSTREAMNAMESERVERS" .PP Here we use the \fIforward\fP plugin to implement a stubDomain that forwards \fB\fCexample.local\fR to the nameserver \fB\fC10.100.0.10:53\fR. @@ -256,37 +310,6 @@ cluster.local { .fi .RE -.SH "WILDCARDS" -.PP -Some query labels accept a wildcard value to match any value. If a label is a valid wildcard (*, -or the word "any"), then that label will match all values. The labels that accept wildcards are: - -.IP \(bu 4 -\fIendpoint\fP in an \fB\fCA\fR record request: \fIendpoint\fP.service.namespace.svc.zone, e.g., \fB\fC*.nginx.ns.svc.cluster.local\fR -.IP \(bu 4 -\fIservice\fP in an \fB\fCA\fR record request: \fIservice\fP.namespace.svc.zone, e.g., \fB\fC*.ns.svc.cluster.local\fR -.IP \(bu 4 -\fInamespace\fP in an \fB\fCA\fR record request: service.\fInamespace\fP.svc.zone, e.g., \fB\fCnginx.*.svc.cluster.local\fR -.IP \(bu 4 -\fIport and/or protocol\fP in an \fB\fCSRV\fR request: \fBport_.\fPprotocol_.service.namespace.svc.zone., -e.g., \fB\fC_http.*.service.ns.svc.cluster.local\fR -.IP \(bu 4 -multiple wildcards are allowed in a single query, e.g., \fB\fCA\fR Request \fB\fC*.*.svc.zone.\fR or \fB\fCSRV\fR request \fB\fC*.*.*.*.svc.zone.\fR - - -.PP -For example, wildcards can be used to resolve all Endpoints for a Service as \fB\fCA\fR records. e.g.: \fB\fC*.service.ns.svc.myzone.local\fR will return the Endpoint IPs in the Service \fB\fCservice\fR in namespace \fB\fCdefault\fR: - -.PP -.RS - -.nf -*.service.default.svc.cluster.local. 5 IN A 192.168.10.10 -*.service.default.svc.cluster.local. 5 IN A 192.168.25.15 - -.fi -.RE - .SH "METADATA" .PP The kubernetes plugin will publish the following metadata, if the \fImetadata\fP @@ -308,11 +331,14 @@ plugin is also enabled: \fB\fCkubernetes/client-namespace\fR: the client pod's namespace (see requirements below) .IP \(bu 4 \fB\fCkubernetes/client-pod-name\fR: the client pod's name (see requirements below) +.IP \(bu 4 +\fB\fCkubernetes/client-label/