Files
dns/man/coredns-template.7
41febf8d0a chore: sync upstream 2026-03-27 (#1)
* Bump version to 1.14.2 (#7895)

This PR bumps version to 1.14.2, as part of the release.

Related to 7883

Signed-off-by: Yong Tang <[email protected]>

* plugin/reload: Allow disabling jitter with 0s (#7896)

This PR fixes #7894 by allowing reload 2s 0s as documented.

Signed-off-by: Yong Tang <[email protected]>

* Bump golang to 1.26.1 (#7902)

* Update release note for upcoming 1.14.2 (#7897)

* fix: release date for v1.14.2 notes (#7906)

Updated release date for CoreDNS 1.14.2 to match the actual release
date. This causes issues when rendering the coredns.io website.

Signed-off-by: Ville Vesilehto <[email protected]>

* chore(lint): bump golangci-lint to v2.11.1 (#7905)

- Added nolint to plugin/auto/walk.go to avoid a symlink/TOCTOU
  warning, as it needs to follow symlink.
- Replaced a few flagged integer conversions with safe equivalents in
  cache hashing, reuseport socket setup, and TLS arg handling
- Preallocated response rule slices in plugin/rewrite/name.go
- Replaced WriteString(fmt.Sprintf/Sprintln(...)) with direct
  fmt.Fprint* calls
- Removed stale nolint directives from code and tests that are no
  longer needed

Signed-off-by: Ville Vesilehto <[email protected]>

* feat(secondary): Send NOTIFY messages after zone transfer (#7901)

* feat(secondary): Send NOTIFY messages after zone transfer

- Modified TransferIn() method to accept a transfer.Transfer parameter
- Added NOTIFY message sending after successful zone transfer in secondary plugin
- Updated Update() method to pass the transfer handler through the zone update cycle
- Added comprehensive tests for the secondary notify functionality

Closes #5669

Signed-off-by: liucongran <[email protected]>

* fix(secondary): Fix TransferIn method call in test

Update test to pass nil parameter to TransferIn method after signature change

Signed-off-by: liucongran <[email protected]>

* refactor(secondary): Clean up imports and add helper methods

- Reorder imports for consistency
- Add hasSOA() and getSOA() helper methods to Zone
- Remove unnecessary blank lines in tests

Signed-off-by: liucongran <[email protected]>

* fix(test): Fix variable declaration in secondary test

Change corefile variable assignment to use short declaration syntax (:=)
to fix compilation error.

Signed-off-by: liucongran <[email protected]>

* refactor(secondary): Use getSOA helper method in shouldTransfer

Replace direct SOA access with getSOA() helper method for consistency.

Signed-off-by: liucongran <[email protected]>

---------

Signed-off-by: liucongran <[email protected]>
Co-authored-by: liucongran <[email protected]>

* build(deps): bump github/codeql-action from 4.32.5 to 4.32.6 (#7911)

* build(deps): bump docker/login-action from 3.7.0 to 4.0.0 (#7908)

* build(deps): bump actions/dependency-review-action from 4.8.3 to 4.9.0 (#7909)

* build(deps): bump github.com/aws/aws-sdk-go-v2/service/secretsmanager (#7920)

* build(deps): bump google.golang.org/grpc from 1.79.1 to 1.79.2 (#7916)

* build(deps): bump aquasecurity/trivy-action from 0.34.1 to 0.35.0 (#7910)

* build(deps): bump k8s.io/klog/v2 in the k8s-io group (#7912)

* build(deps): bump golang.org/x/sys from 0.41.0 to 0.42.0 (#7913)

Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.41.0 to 0.42.0.
- [Commits](https://github.com/golang/sys/compare/v0.41.0...v0.42.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* build(deps): bump sigs.k8s.io/mcs-api from 0.3.0 to 0.4.0 (#7919)

Bumps [sigs.k8s.io/mcs-api](https://github.com/kubernetes-sigs/mcs-api) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/kubernetes-sigs/mcs-api/releases)
- [Changelog](https://github.com/kubernetes-sigs/mcs-api/blob/master/RELEASE.md)
- [Commits](https://github.com/kubernetes-sigs/mcs-api/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: sigs.k8s.io/mcs-api
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* build(deps): bump github.com/aws/aws-sdk-go-v2/service/route53 (#7917)

Bumps [github.com/aws/aws-sdk-go-v2/service/route53](https://github.com/aws/aws-sdk-go-v2) from 1.62.2 to 1.62.3.
- [Release notes](https://github.com/aws/aws-sdk-go-v2/releases)
- [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/fsx/v1.62.2...service/fsx/v1.62.3)

---
updated-dependencies:
- dependency-name: github.com/aws/aws-sdk-go-v2/service/route53
  dependency-version: 1.62.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>

* plugin/forward: add max_age option to enforce an absolute connection lifetime (#7903)

* plugin/pkg/proxy: add max_age for per-connection lifetime cap

Introduce a max_age setting on Transport that closes connections based
on creation time, independent of idle-timeout (expire).

Background: PR #7790 changed the connection pool from LIFO to FIFO for
source-port diversity. Under FIFO, every connection is cycled through
the pool and its used timestamp is refreshed continuously. When request
rate is high enough that pool_size / request_rate < expire, no
connection ever becomes idle and expire never fires. This prevents
CoreDNS from opening new connections to upstreams that scale out (e.g.
new Kubernetes pods behind a ClusterIP service with conntrack pinning).

max_age addresses this by enforcing an absolute upper bound on
connection lifetime regardless of activity:
- persistConn gains a created field set at dial time.
- Transport gains maxAge (default 0 = unlimited, preserving existing
  behaviour).
- Dial(): rejects cached connections whose creation age exceeds max_age.
- cleanup(): when maxAge > 0, uses a linear scan over both idle-timeout
  and max-age predicates; when maxAge == 0, preserves the original
  binary-search path on used time (sorted by FIFO insertion order).
- Both hot paths pre-compute the deadline outside any inner loop to
  avoid repeated time.Now() calls.

Tests added:
- TestMaxAgeExpireByCreation: connection with old created but fresh used
  must be rejected even though idle-timeout would pass.
- TestMaxAgeFIFORotation: three FIFO-rotated connections (old created,
  fresh used) must all be rejected, confirming that continuous rotation
  cannot prevent max-age expiry.

Signed-off-by: cangming <[email protected]>

* plugin/forward: add max_age option

Expose Transport.SetMaxAge through the forward plugin so operators can
set an absolute upper bound on connection lifetime via the Corefile.

Usage:
  forward . 1.2.3.4 {
      max_age 30s
  }

Default is 0 (unlimited), which preserves existing behaviour.
A positive value causes connections older than max_age to be closed and
re-dialled on the next request, ensuring CoreDNS reconnects to newly
scaled-out upstream pods even under sustained load where the idle
timeout (expire) would never fire.

If max_age is set, it must not be less than expire; the parser rejects
this combination at startup with a clear error message.

Signed-off-by: cangming <[email protected]>

---------

Signed-off-by: cangming <[email protected]>

* build(deps): bump github.com/aws/aws-sdk-go-v2/feature/ec2/imds (#7914)

* build(deps): bump github.com/aws/aws-sdk-go-v2/config (#7915)

* Add optional TLS support to /metrics endpoint (#7255)

* Use exporter-toolkit to enable optional TLS encryption on /metrics endpoint

Signed-off-by: peppi-lotta <[email protected]>

* Implement startup listener to signal server readiness

Signed-off-by: peppi-lotta <[email protected]>

---------

Signed-off-by: peppi-lotta <[email protected]>

* refactor(test): replace deprecated pbutil dep (#7924)

Replace github.com/matttproud/golang_protobuf_extensions/pbutil
with google.golang.org/protobuf/encoding/protodelim for reading
varint size-delimited protobuf messages in the metrics scraper.

The new protodelim package is already available via the existing
google.golang.org/protobuf dependency, so this removes pbutil as
a direct dependency entirely.

Signed-off-by: Ville Vesilehto <[email protected]>

* Fix case-sensitive zone handling in the transfer plugin for AXFR/IXFR. (#7899)

This PR fixes Fix case-sensitive zone handling in the transfer plugin for AXFR/IXFR, raised in 7898

Signed-off-by: Yong Tang <[email protected]>

* core: Propagate TSIG secrets to DoT server (#7928)

* build(deps): bump github/codeql-action from 4.32.6 to 4.33.0 (#7929)

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.32.6 to 4.33.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/0d579ffd059c29b07949a3cce3983f0780820c98...b1bff81932f5cdfc8695c7752dcee935dcd061c8)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.33.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* build(deps): bump softprops/action-gh-release from 2.5.0 to 2.6.1 (#7930)

Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.5.0 to 2.6.1.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/a06a81a03ee405af7f2048a818ed3f03bbf83c7b...153bb8e04406b158c6c84fc1615b65b24149a1fe)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-version: 2.6.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* core: Avoid spawning waiter goroutines when QUIC worker pool is full (#7927)

* build(deps): bump golang.org/x/crypto from 0.48.0 to 0.49.0 (#7939)

* build(deps): bump github.com/aws/aws-sdk-go-v2 from 1.41.3 to 1.41.4 (#7938)

* build(deps): bump golang.org/x/net from 0.51.0 to 0.52.0 (#7936)

* build(deps): bump google.golang.org/api from 0.269.0 to 0.271.0 (#7933)

* build(deps): bump github.com/aws/aws-sdk-go-v2/config (#7932)

* build(deps): bump github.com/aws/aws-sdk-go-v2/service/route53 (#7937)

* fix(file): protect Zone.Expired with mutex (#7940)

* build(deps): bump github.com/aws/aws-sdk-go-v2/service/secretsmanager (#7935)

* docs(cache): clarify TTL directive (#7941)

* core: Reject oversized GET dns query parameter of DoH (#7926)

* core: Reject oversized GET dns query parameter of DoH

The DoH POST path limits request size using http.MaxBytesReader(..., 65536), but the GET path passes the dns query value directly to base64ToMsg() with no equivalent bound.

This PR adds length check.

Signed-off-by: Yong Tang <[email protected]>

* Fix

Signed-off-by: Yong Tang <[email protected]>

---------

Signed-off-by: Yong Tang <[email protected]>

* build(deps): bump google.golang.org/grpc from 1.79.2 to 1.79.3 (#7945)

* Core: Propagate TSIG status in DoQ transport (#7947)

This PR nsure DoQ writer preserves and returns TSIG verification status, preventing authentication bypass on DNS-over-QUIC.

Signed-off-by: Yong Tang <[email protected]>

* Update github workflow to release windows builds in zip format. (#7946)

* feat: Add GitHub Actions workflow for drafting releases and update Makefile to build Windows releases as zip archives.

Signed-off-by: John-Michael Mulesa <[email protected]>

* Generate both tgz and zip for Windows to support any existing workflows.

Signed-off-by: John-Michael Mulesa <[email protected]>

---------

Signed-off-by: John-Michael Mulesa <[email protected]>

* build(deps): bump github/codeql-action from 4.33.0 to 4.34.1 (#7952)

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 4.33.0 to 4.34.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/b1bff81932f5cdfc8695c7752dcee935dcd061c8...38697555549f1db7851b81482ff19f1fa5c4fedc)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-version: 4.34.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* build(deps): bump github.com/DataDog/dd-trace-go/v2 from 2.6.0 to 2.7.0 (#7955)

Bumps [github.com/DataDog/dd-trace-go/v2](https://github.com/DataDog/dd-trace-go) from 2.6.0 to 2.7.0.
- [Release notes](https://github.com/DataDog/dd-trace-go/releases)
- [Commits](https://github.com/DataDog/dd-trace-go/compare/v2.6.0...v2.7.0)

---
updated-dependencies:
- dependency-name: github.com/DataDog/dd-trace-go/v2
  dependency-version: 2.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>

* ci: use go-version-file instead of GITHUB_ENV (#7958)

* ci(docker): scope secrets to publish step only (#7959)

* ci(yamllint): replace third-party action with uvx (#7957)

* build(deps): bump the k8s-io group with 3 updates (#7953)

* build(deps): bump the go-etcd-io group with 2 updates (#7954)

* ci(dependabot): add 7-day cooldown for updates (#7960)

* fix(kubernetes): record cluster_ip services in dns_programming_duration metric (#7951)

Signed-off-by: Azeez Syed <[email protected]>

* plugin/cache: prefetch without holding a client connection (#7944)

* ci: add persist-credentials: false to checkouts (#7964)

* ci(release): use env vars for expressions in shell (#7965)

* ci(depsreview): add version comment to pin (#7966)

* plugin/transfter: Fix longestMatch to select the most specific zone correctly. (#7949)

* plugin/transfter: Fix longestMatch to select the most specific zone correctly.

This PR Fix longestMatch to select the most specific zone correctly.The previous implementation used lexicographic string comparison, which could choose the wrong zone; this change selects the longest matching zone instead.

Signed-off-by: Yong Tang <[email protected]>

* Tie breaker

Signed-off-by: Yong Tang <[email protected]>

* Fix

Signed-off-by: Yong Tang <[email protected]>

---------

Signed-off-by: Yong Tang <[email protected]>

* core: Preserve TSIG status in gRPC transport (#7943)

* ci: remove trivy-action (#7961)

* feat: add support for running CoreDNS as a Windows service (#7962)

* feat: add support for running CoreDNS as a Windows service

Signed-off-by: John-Michael Mulesa <[email protected]>

* Use non-deprecated service check function.

Signed-off-by: John-Michael Mulesa <[email protected]>

* refactor: remove deprecated build tags and clean up imports in service files

Signed-off-by: John-Michael Mulesa <[email protected]>

* ci: add Windows test workflow and fix log field access in service_windows.go

Signed-off-by: John-Michael Mulesa <[email protected]>

* test: implement cross-platform file permission restriction for Windows compatibility in run_test.go

Signed-off-by: John-Michael Mulesa <[email protected]>

* refactor: remove Windows-specific icacls test logic and restrict unreadable file test to non-Windows platforms

Signed-off-by: John-Michael Mulesa <[email protected]>

* docs: add documentation for -windows-service flag in man page

Signed-off-by: John-Michael Mulesa <[email protected]>

---------

Signed-off-by: John-Michael Mulesa <[email protected]>

* test(dnssec): fix err in TestZoneSigningDouble (#7969)

* chore(docs): regenerate man pages (#7971)

* chore(docs): update Docker build command in README (#7972)

* plugin/tsig: add require_opcode directive for opcode-based TSIG (#7828)

Extend the tsig plugin to require TSIG signatures based on DNS opcodes,
similar to the existing qtype-based requirement.

The new require_opcode directive accepts opcode names (QUERY, IQUERY,
STATUS, NOTIFY, UPDATE) or the special values "all" and "none".

This is useful for requiring TSIG on dynamic update (UPDATE) or zone
transfer notification (NOTIFY) requests while allowing unsigned queries.

Example:
```
  tsig {
    secret key. NoTCJU+DMqFWywaPyxSijrDEA/eC3nK0xi3AMEZuPVk=
    require_opcode UPDATE NOTIFY
  }
```

Signed-off-by: Seena Fallah <[email protected]>

* plugin/tls: Add the keylog option to configure TLSConfig.KeyLogWriter (#7537)

* tls: Add the keylog option to configure TLSConfig.KeyLogWriter

Signed-off-by: Ilya Kulakov <[email protected]>

* tls: Close keylog file on instance shutdown.

Signed-off-by: Ilya Kulakov <[email protected]>

---------

Signed-off-by: Ilya Kulakov <[email protected]>

---------

Signed-off-by: Yong Tang <[email protected]>
Signed-off-by: Ville Vesilehto <[email protected]>
Signed-off-by: liucongran <[email protected]>
Signed-off-by: dependabot[bot] <[email protected]>
Signed-off-by: cangming <[email protected]>
Signed-off-by: peppi-lotta <[email protected]>
Signed-off-by: John-Michael Mulesa <[email protected]>
Signed-off-by: Azeez Syed <[email protected]>
Signed-off-by: Seena Fallah <[email protected]>
Signed-off-by: Ilya Kulakov <[email protected]>
Co-authored-by: Yong Tang <[email protected]>
Co-authored-by: Ville Vesilehto <[email protected]>
Co-authored-by: liucongran <[email protected]>
Co-authored-by: liucongran <[email protected]>

Co-authored-by: cangming <[email protected]>
Co-authored-by: Peppi-Lotta <[email protected]>
Co-authored-by: John-Michael Mulesa <[email protected]>
Co-authored-by: Syed Azeez <[email protected]>

Co-authored-by: John-Michael Mulesa <[email protected]>
Co-authored-by: Seena Fallah <[email protected]>
Co-authored-by: Ilya Kulakov <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-05-29 21:07:33 -07:00

419 lines
12 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
.\" Generated by Mmark Markdown Processer - mmark.miek.nl
.TH "COREDNS-TEMPLATE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins"
.SH "NAME"
.PP
\fItemplate\fP - allows for dynamic responses based on the incoming query.
.SH "DESCRIPTION"
.PP
The \fItemplate\fP plugin allows you to dynamically respond to queries by just writing a (Go) template.
.SH "SYNTAX"
.PP
.RS
.nf
template CLASS TYPE [ZONE...] {
match REGEX...
answer RR
additional RR
authority RR
rcode CODE
ederror EXTENDED\_ERROR\_CODE [EXTRA\_REASON]
fallthrough [FALLTHROUGH\-ZONE...]
}
.fi
.RE
.IP \(bu 4
\fBCLASS\fP the query class (usually IN or ANY).
.IP \(bu 4
\fBTYPE\fP the query type (A, PTR, ... can be ANY to match all types).
.IP \(bu 4
\fBZONE\fP the zone scope(s) for this template. Defaults to the server zones.
.IP \(bu 4
\fB\fCmatch\fR \fBREGEX\fP Go regexp
\[la]https://golang.org/pkg/regexp/\[ra] that are matched against the incoming question name.
Specifying no regex matches everything (default: \fB\fC.*\fR). First matching regex wins. Regex patterns
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
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\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
\fB\fCederror\fR \fBEXTENDED\fIERROR\fPCODE\fP is an extended DNS error code as a number defined in \fB\fCRFC8914\fR (0, 1, 2,..., 24).
\fBEXTRA_REASON\fP is an additional string explaining the reason for returning the error.
.IP \(bu 4
\fB\fCfallthrough\fR Continue with the next \fItemplate\fP instance if the \fItemplate\fP's \fBZONE\fP matches a query name but no regex match.
If there is no next \fItemplate\fP, continue resolution with the next plugin. If \fB[FALLTHROUGH-ZONE...]\fP 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. Without
\fB\fCfallthrough\fR, when the \fItemplate\fP's \fBZONE\fP matches a query but no regex match then a \fB\fCSERVFAIL\fR response is returned.
.PP
Also see
\[la]#also-see\[ra] contains an additional reading list.
.SH "TEMPLATES"
.PP
Each resource record is a full-featured Go template
\[la]https://golang.org/pkg/text/template/\[ra] with the following predefined data
.IP \(bu 4
\fB\fC.Zone\fR the matched zone string (e.g. \fB\fCexample.\fR).
.IP \(bu 4
\fB\fC.Name\fR the query name, as a string (lowercased).
.IP \(bu 4
\fB\fC.Class\fR the query class (usually \fB\fCIN\fR).
.IP \(bu 4
\fB\fC.Type\fR the RR type requested (e.g. \fB\fCPTR\fR).
.IP \(bu 4
\fB\fC.Match\fR an array of all matches. \fB\fCindex .Match 0\fR refers to the whole match.
.IP \(bu 4
\fB\fC.Group\fR a map of the named capture groups.
.IP \(bu 4
\fB\fC.Message\fR the complete incoming DNS message.
.IP \(bu 4
\fB\fC.Question\fR the matched question section.
.IP \(bu 4
\fB\fC.Remote\fR client’s IP address
.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
.PP
and the following predefined template functions
\[la]https://golang.org/pkg/text/template#hdr-Functions\[ra]
.IP \(bu 4
\fB\fCparseInt\fR interprets a string in the given base and bit size. Equivalent to strconv.ParseUint
\[la]https://golang.org/pkg/strconv#ParseUint\[ra].
.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").
.PP
\fBWARNING\fP there is a syntactical problem with Go templates and CoreDNS config files. Expressions
like \fB\fC{{$var}}\fR will be interpreted as a reference to an environment variable by CoreDNS (and
Caddy) while \fB\fC{{ $var }}\fR will work. See Bugs
\[la]#bugs\[ra] and corefile(5).
.SH "METRICS"
.PP
If monitoring is enabled (via the \fIprometheus\fP plugin) then the following metrics are exported:
.IP \(bu 4
\fB\fCcoredns_template_matches_total{server, zone, view, class, type}\fR the total number of matched requests by regex.
.IP \(bu 4
\fB\fCcoredns_template_template_failures_total{server, zone, view, class, type, section, template}\fR the number of times the Go templating failed. Regex, section and template label values can be used to map the error back to the config file.
.IP \(bu 4
\fB\fCcoredns_template_rr_failures_total{server, zone, view, class, type, section, template}\fR the number of times the templated resource record was invalid and could not be parsed. Regex, section and template label values can be used to map the error back to the config file.
.PP
Both failure cases indicate a problem with the template configuration. The \fB\fCserver\fR label indicates
the server incrementing the metric, see the \fImetrics\fP plugin for details.
.SH "EXAMPLES"
.SS "RESOLVE EVERYTHING TO NXDOMAIN"
.PP
The most simplistic template is
.PP
.RS
.nf
\&. {
template ANY ANY {
rcode NXDOMAIN
}
}
.fi
.RE
.IP 1\. 4
This template uses the default zone (\fB\fC.\fR or all queries)
.IP 2\. 4
All queries will be answered (no \fB\fCfallthrough\fR)
.IP 3\. 4
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.
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
template ANY ANY invalid {
rcode NXDOMAIN
authority "invalid. 60 {{ .Class }} SOA ns.invalid. hostmaster.invalid. (1 60 60 60 60)"
ederror 21 "Blocked according to RFC2606"
}
}
.fi
.RE
.IP 1\. 4
A query to .invalid will result in NXDOMAIN (rcode)
.IP 2\. 4
A dummy SOA record is sent to hand out a TTL of 60s for caching purposes
.IP 3\. 4
Querying \fB\fC.invalid\fR in the \fB\fCCH\fR class will also cause a NXDOMAIN/SOA response
.IP 4\. 4
The default regex is \fB\fC.*\fR
.SS "BLOCK INVALID SEARCH DOMAIN COMPLETIONS"
.PP
Imagine you run \fB\fCexample.com\fR with a datacenter \fB\fCdc1.example.com\fR. The datacenter domain
is part of the DNS search domain.
However \fB\fCsomething.example.com.dc1.example.com\fR would indicate a fully qualified
domain name (\fB\fCsomething.example.com\fR) that inadvertently has the default domain or search
path (\fB\fCdc1.example.com\fR) added.
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
template IN ANY example.com.dc1.example.com {
rcode NXDOMAIN
authority "{{ .Zone }} 60 IN SOA ns.example.com hostmaster.example.com (1 60 60 60 60)"
}
}
.fi
.RE
.PP
A more verbose regex based equivalent would be
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
template IN ANY example.com {
match "example\\.com\\.(dc1\\.example\\.com\\.)$"
rcode NXDOMAIN
authority "{{ index .Match 1 }} 60 IN SOA ns.{{ index .Match 1 }} hostmaster.{{ index .Match 1 }} (1 60 60 60 60)"
fallthrough
}
}
.fi
.RE
.PP
The regex-based version can do more complex matching/templating while zone-based templating is easier to read and use.
.SS "RESOLVE A/PTR FOR .EXAMPLE"
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
# ip\-a\-b\-c\-d.example A a.b.c.d
template IN A example {
match (^|[.])ip\-(?P<a>[0\-9]*)\-(?P<b>[0\-9]*)\-(?P<c>[0\-9]*)\-(?P<d>[0\-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN A {{ .Group.a }}.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
# d.c.b.a.in\-addr.arpa PTR ip\-a\-b\-c\-d.example
template IN PTR in\-addr.arpa {
match ^(?P<d>[0\-9]*)[.](?P<c>[0\-9]*)[.](?P<b>[0\-9]*)[.](?P<a>[0\-9]*)[.]in\-addr[.]arpa[.]$
answer "{{ .Name }} 60 IN PTR ip\-{{ .Group.a }}\-{{ .Group.b }}\-{{ .Group.c }}\-{{ .Group.d }}.example."
}
}
.fi
.RE
.PP
An IPv4 address consists of 4 bytes, \fB\fCa.b.c.d\fR. Named groups make it less error-prone to reverse the
IP address in the PTR case. Try to use named groups to explain what your regex and template are doing.
.PP
Note that the A record is actually a wildcard: any subdomain of the IP address will resolve to the IP address.
.PP
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 HEXADECIMAL IP PATTERN USING PARSEINT"
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
template IN A example {
match "^ip0a(?P<b>[a\-f0\-9]{2})(?P<c>[a\-f0\-9]{2})(?P<d>[a\-f0\-9]{2})[.]example[.]$"
answer "{{ .Name }} 60 IN A 10.{{ parseInt .Group.b 16 8 }}.{{ parseInt .Group.c 16 8 }}.{{ parseInt .Group.d 16 8 }}"
fallthrough
}
}
.fi
.RE
.PP
An IPv4 address can be expressed in a more compact form using its hexadecimal encoding.
For example \fB\fCip-10-123-123.example.\fR can instead be expressed as \fB\fCip0a7b7b7b.example.\fR
.SS "RESOLVE MULTIPLE IP PATTERNS"
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
template IN A example {
match "^ip\-(?P<a>10)\-(?P<b>[0\-9]*)\-(?P<c>[0\-9]*)\-(?P<d>[0\-9]*)[.]dc[.]example[.]$"
match "^(?P<a>[0\-9]*)[.](?P<b>[0\-9]*)[.](?P<c>[0\-9]*)[.](?P<d>[0\-9]*)[.]ext[.]example[.]$"
answer "{{ .Name }} 60 IN A {{ .Group.a}}.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
}
.fi
.RE
.PP
Named capture groups can be used to template one response for multiple patterns.
.SS "RESOLVE A AND MX RECORDS FOR IP TEMPLATES IN .EXAMPLE"
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
template IN A example {
match ^ip\-10\-(?P<b>[0\-9]*)\-(?P<c>[0\-9]*)\-(?P<d>[0\-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
template IN MX example {
match ^ip\-10\-(?P<b>[0\-9]*)\-(?P<c>[0\-9]*)\-(?P<d>[0\-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN MX 10 {{ .Name }}"
additional "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
fallthrough
}
}
.fi
.RE
.SS "ADDING AUTHORITATIVE NAMESERVERS TO THE RESPONSE"
.PP
.RS
.nf
\&. {
forward . 8.8.8.8
template IN A example {
match ^ip\-10\-(?P<b>[0\-9]*)\-(?P<c>[0\-9]*)\-(?P<d>[0\-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
authority "example. 60 IN NS ns0.example."
authority "example. 60 IN NS ns1.example."
additional "ns0.example. 60 IN A 203.0.113.8"
additional "ns1.example. 60 IN A 198.51.100.8"
fallthrough
}
template IN MX example {
match ^ip\-10\-(?P<b>[0\-9]*)\-(?P<c>[0\-9]*)\-(?P<d>[0\-9]*)[.]example[.]$
answer "{{ .Name }} 60 IN MX 10 {{ .Name }}"
additional "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
authority "example. 60 IN NS ns0.example."
authority "example. 60 IN NS ns1.example."
additional "ns0.example. 60 IN A 203.0.113.8"
additional "ns1.example. 60 IN A 198.51.100.8"
fallthrough
}
}
.fi
.RE
.SS "FABRICATE A CNAME"
.PP
This example responds with a CNAME to \fB\fCgoogle.com\fR for any DNS query made exactly for \fB\fCfoogle.com\fR.
The answer will also contain a record for \fB\fCgoogle.com\fR if the upstream nameserver can return a record for it of the
requested type.
.PP
.RS
.nf
\&. {
template IN ANY foogle.com {
match "^foogle\\.com\\.$"
answer "foogle.com 60 IN CNAME google.com"
}
forward . 8.8.8.8
}
.fi
.RE
.SH "ALSO SEE"
.IP \(bu 4
Go regexp
\[la]https://golang.org/pkg/regexp/\[ra] for details about the regex implementation
.IP \(bu 4
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
.IP \(bu 4
Go template
\[la]https://golang.org/pkg/text/template/\[ra] for the template language reference
.SH "BUGS"
.PP
CoreDNS supports caddyfile environment variables
\[la]https://caddyserver.com/docs/caddyfile#env\[ra]
with notion of \fB\fC{$ENV_VAR}\fR. This parser feature will break Go template variables
\[la]https://golang.org/pkg/text/template/#hdr-Variables\[ra] notations like\fB\fC{{$variable}}\fR.
The equivalent notation \fB\fC{{ $variable }}\fR will work.
Try to avoid Go template variables in the context of this plugin.