mirror of
https://github.com/coredns/coredns.git
synced 2026-01-04 07:51:24 -05:00
Align plugin/template usage and syntax with other plugins (#1360)
* Align plugin/template usage and syntax with other plugins * Use new fallthrough logic in plugin/template * Use zone name normalization for plugin/template * Test fallthrough parsing in plugin/template * Rework scoping of match checks Most matches are not plugin global but per template. The plugin does only a very rough check while detailed checks are done per-template. Per template checks include: - Zones - Class/Type - Regex - Fallthrough * Remove trailing `.` from fully qualified domain names * Register template metrics with zone/class/type instead of regex * Remove trailing fqdn dot from multiple testcases
This commit is contained in:
committed by
Miek Gieben
parent
a7590897fb
commit
0091e1c9dc
@@ -9,29 +9,35 @@ The *template* plugin allows you to dynamically repond to queries by just writin
|
||||
## Syntax
|
||||
|
||||
~~~
|
||||
template CLASS TYPE [REGEX...] {
|
||||
template CLASS TYPE [ZONE...] {
|
||||
[match REGEX...]
|
||||
[answer RR]
|
||||
[additional RR]
|
||||
[authority RR]
|
||||
[...]
|
||||
[rcode CODE]
|
||||
[rcode responsecode]
|
||||
[fallthrough [fallthrough zone...]]
|
||||
}
|
||||
~~~
|
||||
|
||||
* **CLASS** the query class (usually IN or ANY)
|
||||
* **TYPE** the query type (A, PTR, ...)
|
||||
* **CLASS** the query class (usually IN or ANY).
|
||||
* **TYPE** the query type (A, PTR, ... can be ANY to match all types).
|
||||
* **ZONE** the zone scope(s) for this template. Defaults to the server zones.
|
||||
* **REGEX** [Go regexp](https://golang.org/pkg/regexp/) that are matched against the incoming question name. Specifying no regex matches everything (default: `.*`). First matching regex wins.
|
||||
* `answer|additional|authority` **RR** A [RFC 1035](https://tools.ietf.org/html/rfc1035#section-5) style resource record fragment
|
||||
build by a [Go template](https://golang.org/pkg/text/template/) that contains the reply.
|
||||
* `rcode` **CODE** A response code (`NXDOMAIN, SERVFAIL, ...`). The default is `SUCCESS`.
|
||||
* `fallthrough` Continue with the next plugin if the zone matched but no regex did not match.
|
||||
* `fallthrough zone` One or more zones that may fall through to other plugins. Defaults to all zones of the template.
|
||||
|
||||
At least one answer section or rcode is needed.
|
||||
At least one `answer` or `rcode` directive is needed (e.g. `rcode NXDOMAIN`).
|
||||
|
||||
[Also see](#also-see) contains an additional reading list.
|
||||
|
||||
## Templates
|
||||
|
||||
Each resource record is a full-featured [Go template](https://golang.org/pkg/text/template/) with the following predefined data
|
||||
* `.Zone` the matched zone string (e.g. `example.`).
|
||||
* `.Name` the query name, as a string (lowercased).
|
||||
* `.Class` the query class (usually `IN`).
|
||||
* `.Type` the RR type requested (e.g. `PTR`).
|
||||
@@ -57,6 +63,22 @@ Both failure cases indicate a problem with the template configuration.
|
||||
|
||||
## Examples
|
||||
|
||||
### Resolve everything to NXDOMAIN
|
||||
|
||||
The most simplistic template is
|
||||
|
||||
~~~ corefile
|
||||
. {
|
||||
template ANY ANY {
|
||||
rcode NXDOMAIN
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
1. This template uses the default zone (`.` or all queries)
|
||||
2. All queries will be answered (no `fallthrough`)
|
||||
3. The answer is always NXDOMAIN
|
||||
|
||||
### Resolve .invalid as NXDOMAIN
|
||||
|
||||
The `.invalid` domain is a reserved TLD (see [RFC-2606 Reserved Top Level DNS Names](https://tools.ietf.org/html/rfc2606#section-2)) to indicate invalid domains.
|
||||
@@ -65,7 +87,7 @@ The `.invalid` domain is a reserved TLD (see [RFC-2606 Reserved Top Level DNS Na
|
||||
. {
|
||||
proxy . 8.8.8.8
|
||||
|
||||
template ANY ANY "[.]invalid[.]$" {
|
||||
template ANY ANY invalid {
|
||||
rcode NXDOMAIN
|
||||
answer "invalid. 60 {{ .Class }} SOA a.invalid. b.invalid. (1 60 60 60 60)"
|
||||
}
|
||||
@@ -75,6 +97,7 @@ The `.invalid` domain is a reserved TLD (see [RFC-2606 Reserved Top Level DNS Na
|
||||
1. A query to .invalid will result in NXDOMAIN (rcode)
|
||||
2. A dummy SOA record is send to hand out a TTL of 60s for caching
|
||||
3. Querying `.invalid` of `CH` will also cause a NXDOMAIN/SOA response
|
||||
4. The default regex is `.*`
|
||||
|
||||
### Block invalid search domain completions
|
||||
|
||||
@@ -88,14 +111,29 @@ path (`dc1.example.com`) added.
|
||||
. {
|
||||
proxy . 8.8.8.8
|
||||
|
||||
template IN ANY "[.](example[.]com[.]dc1[.]example[.]com[.])$" {
|
||||
template IN ANY example.com.dc1.example.com {
|
||||
rcode NXDOMAIN
|
||||
answer "{{ index .Match 1 }} 60 IN SOA a.{{ index .Match 1 }} b.{{ index .Match 1 }} (1 60 60 60 60)"
|
||||
answer "{{ .Zone }} 60 IN SOA a.{{ .Zone }} b.{{ .Zone }} (1 60 60 60 60)"
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Using numbered matches works well if there are a few groups (1-4).
|
||||
A more verbose regex based equivalent would be
|
||||
|
||||
~~~ corefile
|
||||
. {
|
||||
proxy . 8.8.8.8
|
||||
|
||||
template IN ANY example.com {
|
||||
match "(example.com.dc1.example.com)$"
|
||||
rcode NXDOMAIN
|
||||
answer "{{ index .Match 1 }} 60 IN SOA a.{{ index .Match 1 }} b.{{ index .Match 1 }} (1 60 60 60 60)"
|
||||
fallthrough
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
The regex based version can do more complex matching/templating while zone based templating is easier to read and use.
|
||||
|
||||
### Resolve A/PTR for .example
|
||||
|
||||
@@ -105,13 +143,16 @@ Using numbered matches works well if there are a few groups (1-4).
|
||||
|
||||
# ip-a-b-c-d.example.com A a.b.c.d
|
||||
|
||||
template IN A (^|[.])ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$ {
|
||||
template IN A example {
|
||||
match (^|[.])ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
|
||||
answer "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
|
||||
fallthrough
|
||||
}
|
||||
|
||||
# d.c.b.a.in-addr.arpa PTR ip-a-b-c-d.example
|
||||
|
||||
template IN PTR ^(?P<d>[0-9]*)[.](?P<c>[0-9]*)[.](?P<b>[0-9]*)[.]10[.]in-addr[.]arpa[.]$ {
|
||||
template IN PTR 10.in-addr.arpa. {
|
||||
match ^(?P<d>[0-9]*)[.](?P<c>[0-9]*)[.](?P<b>[0-9]*)[.]10[.]in-addr[.]arpa[.]$
|
||||
answer "{{ .Name }} 60 IN PTR ip-10-{{ .Group.b }}-{{ .Group.c }}-{{ .Group.d }}.example.com."
|
||||
}
|
||||
}
|
||||
@@ -124,14 +165,19 @@ Note that the A record is actually a wildcard, any subdomain of the ip will reso
|
||||
|
||||
Having templates to map certain PTR/A pairs is a common pattern.
|
||||
|
||||
Fallthrough is needed for mixed domains where only some responses are templated.
|
||||
|
||||
### Resolve multiple ip patterns
|
||||
|
||||
~~~ corefile
|
||||
. {
|
||||
proxy . 8.8.8.8
|
||||
|
||||
template IN A "^ip-(?P<a>10)-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]dc[.]example[.]$" "^(?P<a>[0-9]*)[.](?P<b>[0-9]*)[.](?P<c>[0-9]*)[.](?P<d>[0-9]*)[.]ext[.]example[.]$" {
|
||||
template IN A example {
|
||||
match "^ip-(?P<a>10)-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]dc[.]example[.]$"
|
||||
match "^(?P<a>[0-9]*)[.](?P<b>[0-9]*)[.](?P<c>[0-9]*)[.](?P<d>[0-9]*)[.]ext[.]example[.]$"
|
||||
answer "{{ .Name }} 60 IN A {{ .Group.a}}.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
|
||||
fallthrough
|
||||
}
|
||||
}
|
||||
~~~
|
||||
@@ -144,12 +190,16 @@ Named capture groups can be used to template one response for multiple patterns.
|
||||
. {
|
||||
proxy . 8.8.8.8
|
||||
|
||||
template IN A ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$ {
|
||||
template IN A example {
|
||||
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
|
||||
answer "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
|
||||
fallthrough
|
||||
}
|
||||
template IN MX ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$ {
|
||||
template IN MX example {
|
||||
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
|
||||
answer "{{ .Name }} 60 IN MX 10 {{ .Name }}"
|
||||
additional "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
|
||||
fallthrough
|
||||
}
|
||||
}
|
||||
~~~
|
||||
@@ -160,20 +210,24 @@ Named capture groups can be used to template one response for multiple patterns.
|
||||
. {
|
||||
proxy . 8.8.8.8
|
||||
|
||||
template IN A ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$ {
|
||||
template IN A example {
|
||||
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
|
||||
answer "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
|
||||
authority "example. 60 IN NS ns0.example."
|
||||
authority "example. 60 IN NS ns1.example."
|
||||
additional "ns0.example. 60 IN A 203.0.113.8"
|
||||
additional "ns1.example. 60 IN A 198.51.100.8"
|
||||
fallthrough
|
||||
}
|
||||
template IN MX ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$ {
|
||||
template IN MX example {
|
||||
match ^ip-10-(?P<b>[0-9]*)-(?P<c>[0-9]*)-(?P<d>[0-9]*)[.]example[.]$
|
||||
answer "{{ .Name }} 60 IN MX 10 {{ .Name }}"
|
||||
additional "{{ .Name }} 60 IN A 10.{{ .Group.b }}.{{ .Group.c }}.{{ .Group.d }}"
|
||||
authority "example. 60 IN NS ns0.example."
|
||||
authority "example. 60 IN NS ns1.example."
|
||||
additional "ns0.example. 60 IN A 203.0.113.8"
|
||||
additional "ns1.example. 60 IN A 198.51.100.8"
|
||||
fallthrough
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
Reference in New Issue
Block a user