aboutsummaryrefslogtreecommitdiff
path: root/man/coredns-rewrite.7
blob: 8e22ee0d906e25fe4bc91a6e221387ed5975d3b7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
.\" Generated by Mmark Markdown Processer - mmark.miek.nl
.TH "COREDNS-REWRITE" 7 "February 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
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 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 rewriting a 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, 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.