TEMPLATE(7)

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. Expressions larger than a 1000 charactes return an error during setup.

•   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):

•   Ctx(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 does, i.e. with Ctx("geoip/city").

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 Ctx "geoip/asn"}}
    {{.Zone}}   IN TXT "{{Ctx "geoip/asn"}}"
    {{end}}

ALSO SEE

Go regexp ⟨https://golang.org/pkg/regexp/⟩ for details about the regex implementation and Go template ⟨https://golang.org/pkg/text/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 ⟨https://codeberg.org/miekg/dns/issues/319⟩.