Files
dns/man/coredns-rewrite.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

838 lines
20 KiB
Plaintext

.\" Generated by Mmark Markdown Processer - mmark.miek.nl
.TH "COREDNS-REWRITE" 7 "March 2026" "CoreDNS" "CoreDNS Plugins"
.SH "NAME"
.PP
\fIrewrite\fP - performs internal message rewriting.
.SH "DESCRIPTION"
.PP
Rewrites are invisible to the client. There are simple rewrites (fast) and complex rewrites
(slower), but they're powerful enough to accommodate most dynamic back-end applications.
.SH "SYNTAX"
.PP
A simplified/easy-to-digest syntax for \fIrewrite\fP is...
.PP
.RS
.nf
rewrite [continue|stop] FIELD [TYPE] [(FROM TO)|TTL] [OPTIONS]
.fi
.RE
.IP \(bu 4
\fBFIELD\fP indicates what part of the request/response is being re-written.
.RS
.IP \(en 4
\fB\fCtype\fR - the type field of the request will be rewritten. FROM/TO must be a DNS record type (\fB\fCA\fR, \fB\fCMX\fR, etc.);
e.g., to rewrite ANY queries to HINFO, use \fB\fCrewrite type ANY HINFO\fR.
.IP \(en 4
\fB\fCname\fR - the query name in the \fIrequest\fP is rewritten; by default this is a full match of the
name, e.g., \fB\fCrewrite name example.net example.org\fR. Other match types are supported, see the \fBName Field Rewrites\fP section below.
.IP \(en 4
\fB\fCclass\fR - the class of the message will be rewritten. FROM/TO must be a DNS class type (\fB\fCIN\fR, \fB\fCCH\fR, or \fB\fCHS\fR); e.g., to rewrite CH queries to IN use \fB\fCrewrite class CH IN\fR.
.IP \(en 4
\fB\fCedns0\fR - an EDNS0 option can be appended to the request as described below in the \fBEDNS0 Options\fP section.
.IP \(en 4
\fB\fCttl\fR - the TTL value in the \fIresponse\fP is rewritten.
.IP \(en 4
\fB\fCcname\fR - the CNAME target if the response has a CNAME record
.IP \(en 4
\fB\fCrcode\fR - the response code (RCODE) value in the \fIresponse\fP is rewritten.
.RE
.IP \(bu 4
\fBTYPE\fP this optional element can be specified for a \fB\fCname\fR or \fB\fCttl\fR field.
If not given type \fB\fCexact\fR will be assumed. If options should be specified the
type must be given.
.IP \(bu 4
\fBFROM\fP is the name (exact, suffix, prefix, substring, or regex) or type to match
.IP \(bu 4
\fBTO\fP is the destination name or type to rewrite to
.IP \(bu 4
\fBTTL\fP is the number of seconds to set the TTL value to (only for field \fB\fCttl\fR)
.IP \(bu 4
\fBOPTIONS\fP
.PP
for field \fB\fCname\fR further options are possible controlling the response rewrites.
All name matching types support the following options
.PP
.RS
.nf
* `answer auto` \- the names in the \_response\_ is rewritten in a best effort manner.
* `answer name FROM TO` \- the query name in the \_response\_ is rewritten matching the from regex pattern.
* `answer value FROM TO` \- the names in the \_response\_ is rewritten matching the from regex pattern.
.fi
.RE
.PP
See below in the \fBResponse Rewrites\fP section for further details.
.PP
If you specify multiple rules and an incoming query matches multiple rules, the rewrite
will behave as follows:
.IP \(bu 4
\fB\fCcontinue\fR will continue applying the next rule in the rule list.
.IP \(bu 4
\fB\fCstop\fR will consider the current rule the last rule and will not continue. The default behaviour is \fB\fCstop\fR
.IP \(bu 4
When multiple rules are matched, the request rewrite follows the line order in the configuration, while the response rewrite(\fB\fCanswer\fR option) is executed in reverse order.
.SH "EXAMPLES"
.SS "NAME FIELD REWRITES"
.PP
The \fB\fCrewrite\fR plugin offers the ability to match the name in the question section of
a DNS request. The match could be exact, a substring match, or based on a prefix, suffix, or regular
expression. If the newly used name is not a legal domain name, the plugin returns an error to the
client.
.PP
The syntax for name rewriting is as follows:
.PP
.RS
.nf
rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] STRING STRING [OPTIONS]
.fi
.RE
.PP
The match type, e.g., \fB\fCexact\fR, \fB\fCsubstring\fR, etc., triggers rewrite:
.IP \(bu 4
\fBexact\fP (default): on an exact match of the name in the question section of a request
.IP \(bu 4
\fBsubstring\fP: on a partial match of the name in the question section of a request
.IP \(bu 4
\fBprefix\fP: when the name begins with the matching string
.IP \(bu 4
\fBsuffix\fP: when the name ends with the matching string
.IP \(bu 4
\fBregex\fP: when the name in the question section of a request matches a regular expression.
Regex patterns must not exceed 10000 characters.
.PP
If the match type is omitted, the \fB\fCexact\fR match type is assumed. If OPTIONS are
given, the type must be specified.
.PP
The following instruction allows rewriting names in the query that
contain the substring \fB\fCservice.us-west-1.example.org\fR:
.PP
.RS
.nf
rewrite name substring service.us\-west\-1.example.org service.us\-west\-1.consul
.fi
.RE
.PP
Thus:
.IP \(bu 4
Incoming Request Name: \fB\fCftp.service.us-west-1.example.org\fR
.IP \(bu 4
Rewritten Request Name: \fB\fCftp.service.us-west-1.consul\fR
.PP
The following instruction uses regular expressions. Names in requests
matching the regular expression \fB\fC(.*)-(us-west-1)\.example\.org\fR are replaced with
\fB\fC{1}.service.{2}.consul\fR, where \fB\fC{1}\fR and \fB\fC{2}\fR are regular expression match groups.
.PP
.RS
.nf
rewrite name regex (.*)\-(us\-west\-1)\\.example\\.org {1}.service.{2}.consul
.fi
.RE
.PP
Thus:
.IP \(bu 4
Incoming Request Name: \fB\fCftp-us-west-1.example.org\fR
.IP \(bu 4
Rewritten Request Name: \fB\fCftp.service.us-west-1.consul\fR
.PP
The following example rewrites the \fB\fCschmoogle.com\fR suffix to \fB\fCgoogle.com\fR.
.PP
.RS
.nf
rewrite name suffix .schmoogle.com. .google.com.
.fi
.RE
.SS "RESPONSE REWRITES"
.PP
When rewriting incoming DNS requests' names (field \fB\fCname\fR), CoreDNS re-writes
the \fB\fCQUESTION SECTION\fR
section of the requests. It may be necessary to rewrite the \fB\fCANSWER SECTION\fR of the
requests, because some DNS resolvers treat mismatches between the \fB\fCQUESTION SECTION\fR
and \fB\fCANSWER SECTION\fR as a man-in-the-middle attack (MITM).
.PP
For example, a user tries to resolve \fB\fCftp-us-west-1.coredns.rocks\fR. The
CoreDNS configuration file has the following rule:
.PP
.RS
.nf
rewrite name regex (.*)\-(us\-west\-1)\\.coredns\\.rocks {1}.service.{2}.consul
.fi
.RE
.PP
CoreDNS rewrote the request from \fB\fCftp-us-west-1.coredns.rocks\fR to
\fB\fCftp.service.us-west-1.consul\fR and ultimately resolved it to 3 records.
The resolved records, in the \fB\fCANSWER SECTION\fR below, were not from \fB\fCcoredns.rocks\fR, but
rather from \fB\fCservice.us-west-1.consul\fR.
.PP
.RS
.nf
$ dig @10.1.1.1 ftp\-us\-west\-1.coredns.rocks
;; QUESTION SECTION:
;ftp\-us\-west\-1.coredns.rocks. IN A
;; ANSWER SECTION:
ftp.service.us\-west\-1.consul. 0 IN A 10.10.10.10
ftp.service.us\-west\-1.consul. 0 IN A 10.20.20.20
ftp.service.us\-west\-1.consul. 0 IN A 10.30.30.30
.fi
.RE
.PP
The above is a mismatch between the question asked and the answer provided.
.PP
There are three possibilities to specify an answer rewrite:
- A rewrite can request a best effort answer rewrite by adding the option \fB\fCanswer auto\fR.
- A rewrite may specify a dedicated regex based response name rewrite with the
\fB\fCanswer name FROM TO\fR option.
- A regex based rewrite of record values like \fB\fCCNAME\fR, \fB\fCSRV\fR, etc, can be requested by
an \fB\fCanswer value FROM TO\fR option.
.PP
Hereby FROM/TO follow the rules for the \fB\fCregex\fR name rewrite syntax.
.SS "AUTO RESPONSE NAME REWRITE"
.PP
The following configuration snippet allows for rewriting of the
\fB\fCANSWER SECTION\fR according to the rewrite of the \fB\fCQUESTION SECTION\fR:
.PP
.RS
.nf
rewrite stop {
name suffix .coredns.rocks .service.consul answer auto
}
.fi
.RE
.PP
Any occurrence of the rewritten question in the answer is mapped
back to the original value before the rewrite.
.PP
Please note that answers for rewrites of type \fB\fCexact\fR are always rewritten.
For a \fB\fCsuffix\fR name rule \fB\fCauto\fR leads to a reverse suffix response rewrite,
exchanging FROM and TO from the rewrite request.
.SS "EXPLICIT RESPONSE NAME REWRITE"
.PP
The following configuration snippet allows for rewriting of the
\fB\fCANSWER SECTION\fR, provided that the \fB\fCQUESTION SECTION\fR was rewritten:
.PP
.RS
.nf
rewrite stop {
name regex (.*)\-(us\-west\-1)\\.coredns\\.rocks {1}.service.{2}.consul
answer name (.*)\\.service\\.(us\-west\-1)\\.consul {1}\-{2}.coredns.rocks
}
.fi
.RE
.PP
Now, the \fB\fCANSWER SECTION\fR matches the \fB\fCQUESTION SECTION\fR:
.PP
.RS
.nf
$ dig @10.1.1.1 ftp\-us\-west\-1.coredns.rocks
;; QUESTION SECTION:
;ftp\-us\-west\-1.coredns.rocks. IN A
;; ANSWER SECTION:
ftp\-us\-west\-1.coredns.rocks. 0 IN A 10.10.10.10
ftp\-us\-west\-1.coredns.rocks. 0 IN A 10.20.20.20
ftp\-us\-west\-1.coredns.rocks. 0 IN A 10.30.30.30
.fi
.RE
.SS "REWRITING OTHER RESPONSE VALUES"
.PP
It is also possible to rewrite other values returned in the DNS response records
(e.g. the server names returned in \fB\fCSRV\fR and \fB\fCMX\fR records). This can be enabled by adding
the \fB\fCanswer value FROM TO\fR option to a name rule as specified below. \fB\fCanswer value\fR takes a
regular expression and a rewrite name as parameters and works in the same way as the
\fB\fCanswer name\fR rule.
.PP
Note that names in the \fB\fCAUTHORITY SECTION\fR and \fB\fCADDITIONAL SECTION\fR will also be
rewritten following the specified rules. The names returned by the following
record types: \fB\fCCNAME\fR, \fB\fCDNAME\fR, \fB\fCSOA\fR, \fB\fCSRV\fR, \fB\fCMX\fR, \fB\fCNAPTR\fR, \fB\fCNS\fR, \fB\fCPTR\fR will be rewritten
if the \fB\fCanswer value\fR rule is specified.
.PP
The syntax for the rewrite of DNS request and response is as follows:
.PP
.RS
.nf
rewrite [continue|stop] {
name regex STRING STRING
answer name STRING STRING
[answer value STRING STRING]
}
.fi
.RE
.PP
Note that the above syntax is strict. For response rewrites, only \fB\fCname\fR
rules are allowed to match the question section. The answer rewrite must be
after the name, as in the syntax example.
.SS "EXAMPLE: PTR RESPONSE VALUE REWRITE"
.PP
The original response contains the domain \fB\fCservice.consul.\fR in the \fB\fCVALUE\fR part
of the \fB\fCANSWER SECTION\fR
.PP
.RS
.nf
$ dig @10.1.1.1 30.30.30.10.in\-addr.arpa PTR
;; QUESTION SECTION:
;30.30.30.10.in\-addr.arpa. IN PTR
;; ANSWER SECTION:
30.30.30.10.in\-addr.arpa. 60 IN PTR ftp\-us\-west\-1.service.consul.
.fi
.RE
.PP
The following configuration snippet allows for rewriting of the value
in the \fB\fCANSWER SECTION\fR:
.PP
.RS
.nf
rewrite stop {
name suffix .arpa .arpa
answer name auto
answer value (.*)\\.service\\.consul\\. {1}.coredns.rocks.
}
.fi
.RE
.PP
Now, the \fB\fCVALUE\fR in the \fB\fCANSWER SECTION\fR has been overwritten in the domain part:
.PP
.RS
.nf
$ dig @10.1.1.1 30.30.30.10.in\-addr.arpa PTR
;; QUESTION SECTION:
;30.30.30.10.in\-addr.arpa. IN PTR
;; ANSWER SECTION:
30.30.30.10.in\-addr.arpa. 60 IN PTR ftp\-us\-west\-1.coredns.rocks.
.fi
.RE
.SS "MULTIPLE RESPONSE REWRITES"
.PP
\fB\fCname\fR and \fB\fCvalue\fR rewrites can be chained by appending multiple answer rewrite
options. For all occurrences but the first one the keyword \fB\fCanswer\fR might be
omitted.
.PP
.RS
.nf
answer (auto | (name|value FROM TO)) { [answer] (auto | (name|value FROM TO)) }
.fi
.RE
.PP
For example:
.PP
.RS
.nf
rewrite [continue|stop] name regex FROM TO answer name FROM TO [answer] value FROM TO
.fi
.RE
.PP
When using \fB\fCexact\fR name rewrite rules, the answer gets rewritten automatically,
and there is no need to define \fB\fCanswer name auto\fR. But it is still possible to define
additional \fB\fCanswer value\fR and \fB\fCanswer value\fR options.
.PP
The rule below rewrites the name in a request from \fB\fCRED\fR to \fB\fCBLUE\fR, and subsequently
rewrites the name in a corresponding response from \fB\fCBLUE\fR to \fB\fCRED\fR. The
client in the request would see only \fB\fCRED\fR and no \fB\fCBLUE\fR.
.PP
.RS
.nf
rewrite [continue|stop] name exact RED BLUE
.fi
.RE
.SS "TTL FIELD REWRITES"
.PP
At times, the need to rewrite a TTL value could arise. For example, a DNS server
may not cache records with a TTL of zero (\fB\fC0\fR). An administrator
may want to increase the TTL to ensure it is cached, e.g., by increasing it to 15 seconds.
.PP
In the below example, the TTL in the answers for \fB\fCcoredns.rocks\fR domain are
being set to \fB\fC15\fR:
.PP
.RS
.nf
rewrite continue {
ttl regex (.*)\\.coredns\\.rocks 15
}
.fi
.RE
.PP
By the same token, an administrator may use this feature to prevent or limit caching by
setting the TTL value really low.
.PP
The syntax for the TTL rewrite rule is as follows. The meaning of
\fB\fCexact|prefix|suffix|substring|regex\fR is the same as with the name rewrite rules.
An omitted type is defaulted to \fB\fCexact\fR.
.PP
.RS
.nf
rewrite [continue|stop] ttl [exact|prefix|suffix|substring|regex] STRING [SECONDS|MIN\-MAX]
.fi
.RE
.PP
It is possible to supply a range of TTL values in the \fB\fCSECONDS\fR parameters instead of a single value.
If a range is supplied, the TTL value is set to \fB\fCMIN\fR if it is below, or set to \fB\fCMAX\fR if it is above.
The TTL value is left unchanged if it is already inside the provided range.
The ranges can be unbounded on either side.
.PP
TTL examples with ranges:
.PP
.RS
.nf
rewrite ttl example.com. 30\-300
rewrite ttl example.com. \-30 # equivalent to rewrite ttl example.com. 0\-30
rewrite ttl example.com. 30\-
rewrite ttl example.com. 30 # equivalent to rewrite ttl example.com. 30\-30
.fi
.RE
.SS "RCODE FIELD REWRITES"
.PP
At times, the need to rewrite a RCODE value could arise. For example, a DNS server
may respond with a SERVFAIL instead of NOERROR records when AAAA records are requested.
.PP
In the below example, the rcode value the answer for \fB\fCcoredns.rocks\fR the replies with SERVFAIL
is being switched to NOERROR.
.PP
This example rewrites all the *.coredns.rocks domain SERVFAIL errors to NOERROR
.PP
.RS
.nf
rewrite continue {
rcode regex (.*)\\.coredns\\.rocks SERVFAIL NOERROR
}
.fi
.RE
.PP
The same result numeric values:
.PP
.RS
.nf
rewrite continue {
rcode regex (.*)\\.coredns\\.rocks 2 0
}
.fi
.RE
.PP
The syntax for the RCODE rewrite rule is as follows. The meaning of
\fB\fCexact|prefix|suffix|substring|regex\fR is the same as with the name rewrite rules.
An omitted type is defaulted to \fB\fCexact\fR.
.PP
.RS
.nf
rewrite [continue|stop] rcode [exact|prefix|suffix|substring|regex] STRING FROM TO
.fi
.RE
.PP
The values of FROM and TO can be any of the following, text value or numeric:
.PP
.RS
.nf
0 NOERROR
1 FORMERR
2 SERVFAIL
3 NXDOMAIN
4 NOTIMP
5 REFUSED
6 YXDOMAIN
7 YXRRSET
8 NXRRSET
9 NOTAUTH
10 NOTZONE
16 BADSIG
17 BADKEY
18 BADTIME
19 BADMODE
20 BADNAME
21 BADALG
22 BADTRUNC
23 BADCOOKIE
.fi
.RE
.SH "EDNS0 OPTIONS"
.PP
Using the FIELD edns0, you can set, append, replace, or unset specific EDNS0 options in the request.
.IP \(bu 4
\fB\fCreplace\fR will modify any "matching" option with the specified option. The criteria for "matching" varies based on EDNS0 type.
.IP \(bu 4
\fB\fCappend\fR will add the option only if no matching option exists
.IP \(bu 4
\fB\fCset\fR will modify a matching option or add one if none is found
.IP \(bu 4
\fB\fCunset\fR will remove the matching option if one exists
.PP
Currently supported are \fB\fCEDNS0_LOCAL\fR, \fB\fCEDNS0_NSID\fR and \fB\fCEDNS0_SUBNET\fR.
.SS "EDNS0_LOCAL"
.PP
This has two fields, code and data. A match is defined as having the same code. Data may be a string or a variable.
.IP \(bu 4
A string data is treated as hex if it starts with \fB\fC0x\fR. Example:
.PP
.RS
.nf
\&. {
rewrite edns0 local set 0xffee 0x61626364
whoami
}
.fi
.RE
.PP
rewrites the first local option with code 0xffee, setting the data to "abcd". This is equivalent to:
.PP
.RS
.nf
\&. {
rewrite edns0 local set 0xffee abcd
}
.fi
.RE
.IP \(bu 4
A variable data is specified with a pair of curly brackets \fB\fC{}\fR. Following are the supported variables:
{qname}, {qtype}, {client\fIip}, {client\fPport}, {protocol}, {server\fIip}, {server\fPport}.
.IP \(bu 4
If the metadata plugin is enabled, then labels are supported as variables if they are presented within curly brackets.
The variable data will be replaced with the value associated with that label. If that label is not provided,
the variable will be silently substituted with an empty string.
.PP
Examples:
.PP
.RS
.nf
rewrite edns0 local set 0xffee {client\_ip}
.fi
.RE
.PP
The following example uses metadata and an imaginary "some-plugin" that would provide "some-label" as metadata information.
.PP
.RS
.nf
metadata
some\-plugin
rewrite edns0 local set 0xffee {some\-plugin/some\-label}
.fi
.RE
.PP
A local option may be removed by unsetting its code. Example:
.PP
.RS
.nf
rewrite edns0 local unset 0xffee
.fi
.RE
.SS "EDNS0_NSID"
.PP
This has no fields; it will add an NSID option with an empty string for the NSID. If the option already exists
and the action is \fB\fCreplace\fR or \fB\fCset\fR, then the NSID in the option will be set to the empty string.
The option can be removed with the \fB\fCunset\fR action.
.SS "EDNS0_SUBNET"
.PP
This has two fields, IPv4 bitmask length and IPv6 bitmask length. The bitmask
length is used to extract the client subnet from the source IP address in the query.
.PP
Example:
.PP
.RS
.nf
rewrite edns0 subnet set 24 56
.fi
.RE
.IP \(bu 4
If the query's source IP address is an IPv4 address, the first 24 bits in the IP will be the network subnet.
.IP \(bu 4
If the query's source IP address is an IPv6 address, the first 56 bits in the IP will be the network subnet.
.PP
This option can be removed by using \fB\fCunset\fR:
.PP
.RS
.nf
rewrite edns0 subnet unset
.fi
.RE
.SS "EDNS0 REVERT"
.PP
Using the \fB\fCrevert\fR flag, you can revert the changes made by this rewrite call, so the response will not contain this option.
.PP
This example sets option, but response will not contain it
.PP
.RS
.nf
\&. {
rewrite edns0 local set 0xffee abcd revert
}
.fi
.RE
.PP
If only some calls contain the \fB\fCrevert\fR flag, then the value in the response will be changed to the previous one. So, in this example, the response will contain \fB\fCabcd\fR data at \fB\fC0xffee\fR
.PP
.RS
.nf
\&. {
rewrite continue {
edns0 local set 0xffee abcd
}
rewrite edns0 local replace 0xffee bcde revert
}
.fi
.RE
.SH "CNAME FIELD REWRITES"
.PP
There might be a scenario where you want the \fB\fCCNAME\fR target of the response to be rewritten. You can do this by using the \fB\fCCNAME\fR field rewrite. Answer records preceding the \fB\fCCNAME\fR target are kept unchanged, the \fB\fCCNAME\fR target is rewritten, and the subsequent records are replaced with the lookup result of the rewritten \fB\fCCNAME\fR target.
.PP
The syntax for the \fB\fCCNAME\fR rewrite rule is as follows. The meaning of
\fB\fCexact|prefix|suffix|substring|regex\fR is the same as with the name rewrite rules.
An omitted type is defaulted to \fB\fCexact\fR.
.PP
.RS
.nf
rewrite [continue|stop] cname [exact|prefix|suffix|substring|regex] FROM TO
.fi
.RE
.PP
Consider the following \fB\fCCNAME\fR rewrite rule with regex type.
.PP
.RS
.nf
rewrite cname regex (.*).cdn.example.net. {1}.other.cdn.com.
.fi
.RE
.PP
If you were to send the following DNS request without the above rule, an example response would be:
.PP
.RS
.nf
$ dig @10.1.1.1 my\-app.com
;; QUESTION SECTION:
;my\-app.com. IN A
;; ANSWER SECTION:
my\-app.com. 200 IN CNAME my\-app.example.
my\-app.example. 200 IN CNAME my\-app.com.cdn.example.net.
my\-app.com.cdn.example.net. 300 IN A 20.2.0.1
my\-app.com.cdn.example.net. 300 IN A 20.2.0.2
.fi
.RE
.PP
If you were to send the same DNS request with the above rule set up, an example response would be:
.PP
.RS
.nf
$ dig @10.1.1.1 my\-app.com
;; QUESTION SECTION:
;my\-app.com. IN A
;; ANSWER SECTION:
my\-app.com. 200 IN CNAME my\-app.example.
my\-app.example. 200 IN CNAME my\-app.com.other.cdn.com.
my\-app.com.other.cdn.com. 100 IN A 30.3.1.2
.fi
.RE
.PP
Note that the answer will contain a completely different set of answer records after rewriting the \fB\fCCNAME\fR target.