Mmark recently became able to create manual pages. This removed the dependency on 'ronn' and just uses mmark (Go program). Re-hookup Makefile.doc to generate the correct header mmark needs to see and regenate them all. Spot checking a few pages suggest they look good and actually better than rendered with ronn, esp. lists in lists. Fixes #2757 Signed-off-by: Miek Gieben <miek@miek.nl>
468 lines
12 KiB
Groff
468 lines
12 KiB
Groff
.\" Generated by Mmark Markdown Processer - mmark.nl
|
|
.TH "COREDNS-REWRITE" "7" "April 2019" "CoreDNS" "CoreDNS Plugins"
|
|
|
|
.SH REWRITE
|
|
.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 [FROM TO|FROM TTL]
|
|
|
|
.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\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\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\fCanswer name\fR - the query name in the \fIresponse\fP is rewritten. This option has special restrictions and requirements, in particular it must always combined with a \fB\fCname\fR rewrite. See below in the \fBResponse Rewrites\fP section.
|
|
.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.
|
|
|
|
.RE
|
|
.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
|
|
|
|
|
|
.PP
|
|
If you specify multiple rules and an incoming query matches on multiple rules, the rewrite
|
|
will behave as following
|
|
* \fB\fCcontinue\fR will continue apply the next rule in the rule list.
|
|
* \fB\fCstop\fR will consider the current rule is the last rule and will not continue. Default behaviour
|
|
for not specifying this rule processing mode is \fB\fCstop\fR
|
|
|
|
.SS NAME FIELD REWRITES
|
|
.PP
|
|
The \fB\fCrewrite\fR plugin offers the ability to match on the name in the question section of
|
|
a DNS request. The match could be exact, substring, 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 the name re-writing is as follows:
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
rewrite [continue|stop] name [exact|prefix|suffix|substring|regex] STRING STRING
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
The match type, i.e. \fB\fCexact\fR, \fB\fCsubstring\fR, etc., triggers re-write:
|
|
|
|
.IP \(bu 4
|
|
\fBexact\fP (default): on 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
|
|
|
|
|
|
.PP
|
|
If the match type is omitted, the \fB\fCexact\fR match type is being assumed.
|
|
|
|
.PP
|
|
The following instruction allows re-writing the name in the query that
|
|
contains \fB\fCservice.us-west-1.example.org\fR substring.
|
|
|
|
.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
|
|
Re-written Request Name: \fB\fCftp.service.us-west-1.consul\fR
|
|
|
|
|
|
.PP
|
|
The following instruction uses regular expressions. The name in a request
|
|
matching \fB\fC(.*)-(us-west-1)\.example\.org\fR regular expression is being replaces 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
|
|
Re-written 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 re-writing incoming DNS requests' names, CoreDNS re-writes the \fB\fCQUESTION SECTION\fR
|
|
section of the requests. It may be necessary to re-write the \fB\fCANSWER SECTION\fR of the
|
|
requests, because some DNS resolvers would treat the mismatch between \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 instance re-wrote the request to \fB\fCftp-us-west-1.coredns.rocks\fR with
|
|
\fB\fCftp.service.us-west-1.consul\fR and ultimately resolved it to 3 records.
|
|
The resolved records, see \fB\fCANSWER SECTION\fR, 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
|
|
|
|
; <<>> DiG 9.8.3\-P1 <<>> @10.1.1.1 ftp\-us\-west\-1.coredns.rocks
|
|
; (1 server found)
|
|
;; global options: +cmd
|
|
;; Got answer:
|
|
;; \->>HEADER<<\- opcode: QUERY, status: NOERROR, id: 8619
|
|
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
|
|
|
|
;; 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 the mismatch.
|
|
|
|
.PP
|
|
The following configuration snippet allows for the re-writing of the
|
|
\fB\fCANSWER SECTION\fR, provided that the \fB\fCQUESTION SECTION\fR was re-written:
|
|
|
|
.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
|
|
|
|
; <<>> DiG 9.8.3\-P1 <<>> @10.1.1.1 ftp\-us\-west\-1.coredns.rocks
|
|
; (1 server found)
|
|
;; global options: +cmd
|
|
;; Got answer:
|
|
;; \->>HEADER<<\- opcode: QUERY, status: NOERROR, id: 8619
|
|
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
|
|
|
|
;; 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
|
|
|
|
.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
|
|
}
|
|
|
|
.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, and only by match type
|
|
\fB\fCregex\fR. The answer rewrite must be after the name, as ordered in the
|
|
syntax example. There must only be two lines (a \fB\fCname\fR followed by an
|
|
\fB\fCanswer\fR) in the brackets, additional rules are not supported.
|
|
|
|
.PP
|
|
An alternate 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
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
When using \fB\fCexact\fR name rewrite rules, answer gets re-written automatically,
|
|
and there is no need defining \fB\fCanswer name\fR instruction. The below rule
|
|
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 for rewriting TTL value could arise. For example, a DNS server
|
|
may prevent caching by setting TTL as low as zero (\fB\fC0\fR). An administrator
|
|
may want to increase the TTL to prevent caching, e.g. 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 force caching by
|
|
setting 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.
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
rewrite [continue|stop] ttl [exact|prefix|suffix|substring|regex] STRING SECONDS
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.SH EDNS0 OPTIONS
|
|
.PP
|
|
Using FIELD edns0, you can set, append, or replace specific EDNS0 options on 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
|
|
|
|
|
|
.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 can be 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". Equivalent:
|
|
|
|
.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 filled with the value associated with that label. If that label is not provided,
|
|
the variable will be silently substitute by 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
|
|
|
|
.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.
|
|
|
|
.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 has source IP as IPv4, the first 24 bits in the IP will be the network subnet.
|
|
.IP \(bu 4
|
|
If the query has source IP as IPv6, the first 56 bits in the IP will be the network subnet.
|
|
|
|
|
|
.SH FULL SYNTAX
|
|
.PP
|
|
The full plugin usage syntax is harder to digest...
|
|
|
|
.PP
|
|
.RS
|
|
|
|
.nf
|
|
rewrite [continue|stop] {type|class|edns0|name [exact|prefix|suffix|substring|regex [FROM TO answer name]]} FROM TO
|
|
|
|
.fi
|
|
.RE
|
|
|
|
.PP
|
|
The syntax above doesn't cover the multi line block option for specifying a name request+response rewrite rule described in the \fBResponse Rewrite\fP section.
|
|
|