Name
template - use Go templates to reply
Description
The template handler allows you to dynamically respond to queries by just writing a Go template. The
template is a file that is watched and reloaded when it changes. The template is the string version of a message
is generated by codeberg.org/miekg/dns, i.e.:
;; QUERY, rcode: NOERROR, id: 49123, flags: qr rd ra
;; QUESTION SECTION:
miek.nl. IN MX
;; ANSWER SECTION:
miek.nl. 11381 IN MX 10 aspmx2.googlemail.com.
miek.nl. 11381 IN MX 10 aspmx3.googlemail.com.
miek.nl. 11381 IN MX 5 alt1.aspmx.l.google.com.
miek.nl. 11381 IN MX 5 alt2.aspmx.l.google.com.
miek.nl. 11381 IN MX 1 aspmx.l.google.com.
This is a valid template and will be parsed by template into a message and returned to the client.
However, for one thing, the query ID will not be correct, so that line should become:
;; QUERY, rcode: NOERROR, id: {{.ID}}, flags: qr rd ra
When nothing is matched template will call the next handler, see below for more details.
Syntax
template REGEX [TYPE]... {
TEMPLATE
}
- REGEX will be matched against the incoming question name.
- TYPE is the type to be matched, if not given all types are matched.
- TEMPLATE is that template file that should be parsed and executed. If that the path is relative the
global
root path is prepended.
Templates
A template must return a complete message that can be parsed back into an actual DNS message. The template
parsing is not case insensitive, i.e. answer section: will not be parsed but ANSWER SECTION: is.
Each template gets the following variables (see the godoc of Data):
.Zone the matched zone string (e.g. example.org.), from the context.
.ID the query ID.
.Name the query name.
.Class the query class.
.Type the query type.
.Question the matched question RR.
.Msg the complete message.
.ResponseWriter that holds all the data that can be extracted from the response writer.
And the following functions (all functions start with a capital letter):
Value(key string) return the value for the key from the current context. This allows extracting any data
other handlers have added to the context, such as the geoip handler.
Examples
Resolve to NXDOMAIN
example.org. {
template .* {
nxdomain.go.tmpl
}
}
Where nxdomain.go.tmpl contains:
;; QUERY, rcode: NOERROR, id: {{.ID}}, flags: qr rd ra
;; QUESTION SECTION:
{{.Question}}
;; AUTHORITY SECTION:
{{.Zone}} IN SOA ns.icann.org. noc.dns.icann.org. 2025082229 7200 3600 1209600 3600
{{if value "geoip/asn"}}
{{.Zone}} IN TXT "{{dnsctx.Value "geoip/asn"}}"
{{end}}
Also see
Go regexp for details about the regex implementation and
Go template for the template language reference. And atomdns-geoip(7)
for documentation on what elements are added to the context.
Bugs
The template is parsed on every query, which is a bit excessive. See https://codeberg.org/miekg/dns/issues/319.