diff --git a/content/plugins/rewrite.md b/content/plugins/rewrite.md index 66d64ba..32439ce 100644 --- a/content/plugins/rewrite.md +++ b/content/plugins/rewrite.md @@ -1,10 +1,10 @@ +++ title = "rewrite" description = "*rewrite* performs internal message rewriting." -weight = 37 +weight = 38 tags = ["plugin", "rewrite"] categories = ["plugin"] -date = "2021-02-23T09:25:39.8773982" +date = "2021-05-04T08:30:20.8772085" +++ ## Description @@ -16,23 +16,36 @@ Rewrites are invisible to the client. There are simple rewrites (fast) and compl A simplified/easy-to-digest syntax for *rewrite* is... ~~~ -rewrite [continue|stop] FIELD [FROM TO|FROM TTL] +rewrite [continue|stop] FIELD [TYPE] [(FROM TO)|TTL] [OPTIONS] ~~~ * **FIELD** indicates what part of the request/response is being re-written. * `type` - the type field of the request will be rewritten. FROM/TO must be a DNS record type (`A`, `MX`, etc.); e.g., to rewrite ANY queries to HINFO, use `rewrite type ANY HINFO`. - * `class` - the class of the message will be rewritten. FROM/TO must be a DNS class type (`IN`, `CH`, or `HS`); e.g., to rewrite CH queries to IN use `rewrite class CH IN`. * `name` - the query name in the _request_ is rewritten; by default this is a full match of the name, e.g., `rewrite name example.net example.org`. Other match types are supported, see the **Name Field Rewrites** section below. - * `answer name` - the query name in the _response_ is rewritten. This option has special restrictions and requirements, in particular it must always combined with a `name` rewrite. See below in the **Response Rewrites** section. - * `edns0` - an EDNS0 option can be appended to the request as described below in the **EDNS0 Options** section. + * `class` - the class of the message will be rewritten. FROM/TO must be a DNS class type (`IN`, `CH`, or `HS`); e.g., to rewrite CH queries to IN use `rewrite class CH IN`. + * `edns0` - an EDNS0 option can be appended to the request as described below in the **EDNS0 Options** section. * `ttl` - the TTL value in the _response_ is rewritten. +* **TYPE** this optional element can be specified for a `name` or `ttl` field. + If not given type `exact` will be assumed. If options should be specified the + type must be given. * **FROM** is the name (exact, suffix, prefix, substring, or regex) or type to match * **TO** is the destination name or type to rewrite to -* **TTL** is the number of seconds to set the TTL value to +* **TTL** is the number of seconds to set the TTL value to (only for field `ttl`) + +* **OPTIONS** + + for field `name` further options are possible controlling the response rewrites. + All name matching types support the following options + + * `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. + + See below in the **Response Rewrites** section for further details. If you specify multiple rules and an incoming query matches multiple rules, the rewrite will behave as follows: @@ -52,7 +65,7 @@ client. The syntax for name rewriting is as follows: ``` -rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] STRING STRING +rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] STRING STRING [OPTIONS] ``` The match type, e.g., `exact`, `substring`, etc., triggers rewrite: @@ -63,7 +76,8 @@ The match type, e.g., `exact`, `substring`, etc., triggers rewrite: * **suffix**: when the name ends with the matching string * **regex**: when the name in the question section of a request matches a regular expression -If the match type is omitted, the `exact` match type is assumed. +If the match type is omitted, the `exact` match type is assumed. If OPTIONS are +given, the type must be specified. The following instruction allows rewriting names in the query that contain the substring `service.us-west-1.example.org`: @@ -98,7 +112,8 @@ rewrite name suffix .schmoogle.com. .google.com. ### Response Rewrites -When rewriting incoming DNS requests' names, CoreDNS re-writes the `QUESTION SECTION` +When rewriting incoming DNS requests' names (field `name`), CoreDNS re-writes +the `QUESTION SECTION` section of the requests. It may be necessary to rewrite the `ANSWER SECTION` of the requests, because some DNS resolvers treat mismatches between the `QUESTION SECTION` and `ANSWER SECTION` as a man-in-the-middle attack (MITM). @@ -130,6 +145,35 @@ ftp.service.us-west-1.consul. 0 IN A 10.30.30.30 The above is a mismatch between the question asked and the answer provided. +There are three possibilities to specify an answer rewrite: +- A rewrite can request a best effort answer rewrite by adding the option `answer auto`. +- A rewrite may specify a dedicated regex based response name rewrite with the + `answer name FROM TO` option. +- A regex based rewrite of record values like `CNAME`, `SRV`, etc, can be requested by + an `answer value FROM TO` option. + +Hereby FROM/TO follow the rules for the `regex` name rewrite syntax. + +#### Auto Response Name Rewrite + +The following configuration snippet allows for rewriting of the +`ANSWER SECTION` according to the rewrite of the `QUESTION SECTION`: + +``` + rewrite stop { + name suffix .coredns.rocks .service.consul answer auto + } +``` + +Any occurrence of the rewritten question in the answer is mapped +back to the original value before the rewrite. + +Please note that answers for rewrites of type `exact` are always rewritten. +For a `suffix` name rule `auto` leads to a reverse suffix response rewrite, +exchanging FROM and TO from the rewrite request. + +#### Explicit Response Name Rewrite + The following configuration snippet allows for rewriting of the `ANSWER SECTION`, provided that the `QUESTION SECTION` was rewritten: @@ -154,9 +198,11 @@ 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 ``` +#### Rewriting other Response Values + It is also possible to rewrite other values returned in the DNS response records (e.g. the server names returned in `SRV` and `MX` records). This can be enabled by adding -the `answer value` to a name regex rule as specified below. `answer value` takes a +the `answer value FROM TO` option to a name rule as specified below. `answer value` takes a regular expression and a rewrite name as parameters and works in the same way as the `answer name` rule. @@ -176,20 +222,29 @@ rewrite [continue|stop] { ``` Note that the above syntax is strict. For response rewrites, only `name` -rules are allowed to match the question section, and only by match type -`regex`. The answer rewrite must be after the name, as in the -syntax example. +rules are allowed to match the question section. The answer rewrite must be +after the name, as in the syntax example. -An alternate syntax for rewriting a DNS request and response is as -follows: +#### Multiple Response Rewrites +`name` and `value` rewrites can be chained by appending multiple answer rewrite +options. For all occurrences but the first one the keyword `answer` might be +omitted. + +```options +answer (auto | (name|value FROM TO)) { [answer] (auto | (name|value FROM TO)) } ``` -rewrite [continue|stop] name regex STRING STRING answer name STRING STRING [answer value STRING STRING] + +For example: +``` +rewrite [continue|stop] name regex FROM TO answer name FROM TO [answer] value FROM TO ``` When using `exact` name rewrite rules, the answer gets rewritten automatically, -and there is no need to define `answer name`. The rule below -rewrites the name in a request from `RED` to `BLUE`, and subsequently +and there is no need to define `answer name auto`. But it is still possible to define +additional `answer value` and `answer value` options. + +The rule below rewrites the name in a request from `RED` to `BLUE`, and subsequently rewrites the name in a corresponding response from `BLUE` to `RED`. The client in the request would see only `RED` and no `BLUE`. @@ -218,6 +273,7 @@ setting the TTL value really low. The syntax for the TTL rewrite rule is as follows. The meaning of `exact|prefix|suffix|substring|regex` is the same as with the name rewrite rules. +An omitted type is defaulted to `exact`. ``` rewrite [continue|stop] ttl [exact|prefix|suffix|substring|regex] STRING SECONDS @@ -293,12 +349,3 @@ rewrite edns0 subnet set 24 56 * If the query's source IP address is an IPv4 address, the first 24 bits in the IP will be the network subnet. * If the query's source IP address is an IPv6 address, the first 56 bits in the IP will be the network subnet. - -## Full Syntax - -The full plugin usage syntax is harder to digest... -~~~ -rewrite [continue|stop] {type|class|edns0|name [exact|prefix|suffix|substring|regex [FROM TO answer name]]} FROM TO -~~~ - -The syntax above doesn't cover the multi-line block option for specifying a name request+response rewrite rule described in the **Response Rewrite** section.