mirror of
				https://github.com/coredns/coredns.git
				synced 2025-11-03 02:33:21 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			471 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			471 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
.\" Generated by Mmark Markdown Processer - mmark.miek.nl
 | 
						|
.TH "COREDNS-REWRITE" 7 "March 2021" "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 [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 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
 | 
						|
 | 
						|
 | 
						|
.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
 | 
						|
 | 
						|
.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
 | 
						|
 | 
						|
 | 
						|
.PP
 | 
						|
If the match type is omitted, the \fB\fCexact\fR match type is assumed.
 | 
						|
 | 
						|
.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, 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
 | 
						|
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
 | 
						|
 | 
						|
.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\fR to a name regex 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 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, and only by match type
 | 
						|
\fB\fCregex\fR. The answer rewrite must be after the name, as in the
 | 
						|
syntax example.
 | 
						|
 | 
						|
.PP
 | 
						|
An alternate syntax for rewriting a 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
 | 
						|
When using \fB\fCexact\fR name rewrite rules, the answer gets rewritten automatically,
 | 
						|
and there is no need to define \fB\fCanswer name\fR. 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.
 | 
						|
 | 
						|
.PP
 | 
						|
.RS
 | 
						|
 | 
						|
.nf
 | 
						|
rewrite [continue|stop] ttl [exact|prefix|suffix|substring|regex] STRING SECONDS
 | 
						|
 | 
						|
.fi
 | 
						|
.RE
 | 
						|
 | 
						|
.SH "EDNS0 OPTIONS"
 | 
						|
.PP
 | 
						|
Using the FIELD edns0, you can set, append, or replace 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
 | 
						|
 | 
						|
 | 
						|
.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
 | 
						|
 | 
						|
.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'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.
 | 
						|
 | 
						|
 | 
						|
.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.
 | 
						|
 |