coredns-https provides the dohproxy CoreDNS
plugin, which proxies DNS messages to upstream resolvers using DNS-over-HTTPS.
See RFC 8484.
The plugin must be compiled into CoreDNS. The following commands build the latest plugin release against the tested CoreDNS version:
git clone --depth 1 --branch v1.14.6 https://github.com/coredns/coredns.git
cd coredns
go get github.com/v-byte-cpu/coredns-https@latest
COREDNS_PLUGINS="dohproxy:github.com/v-byte-cpu/coredns-https" go generate coredns.go
go build
./coredns -plugins | grep -Fx dohproxyImportant
The Corefile directive was renamed from https to dohproxy to avoid a collision with the
built-in CoreDNS https plugin. Prometheus metrics were also renamed from
coredns_https_* to coredns_dohproxy_*.
Run the unit tests first:
go test ./...To test the current checkout in a real CoreDNS binary, clone the tested CoreDNS version into a separate directory and replace the module with the absolute path to this repository:
git clone --depth 1 --branch v1.14.6 https://github.com/coredns/coredns.git
cd coredns
go mod edit -replace github.com/v-byte-cpu/coredns-https=/absolute/path/to/coredns-https
go get github.com/v-byte-cpu/coredns-https@v0.0.0
COREDNS_PLUGINS="dohproxy:github.com/v-byte-cpu/coredns-https" go generate coredns.go
go build
./coredns -plugins | grep -Fx dohproxyCreate a Corefile for a manual end-to-end check:
.:1053 {
dohproxy . cloudflare-dns.com/dns-query
errors
log
}
Start CoreDNS, then query it from another terminal:
./coredns -conf Corefile
dig @127.0.0.1 -p 1053 example.org AIn its most basic form:
dohproxy FROM TO...
- FROM is the base domain to match for the request to be proxied.
- TO... are the destination endpoints to proxy to. The number of upstreams is limited to 15.
Multiple upstreams are randomized (see policy) on first use. When a proxy returns an error
the next upstream in the list is tried.
Extra knobs are available with an expanded syntax:
dohproxy FROM TO... {
except IGNORED_NAMES...
tls CERT KEY CA
tls_servername NAME
policy random|round_robin|sequential
}
-
FROM and TO... as above.
-
IGNORED_NAMES in
exceptis a space-separated list of domains to exclude from proxying. Requests that match none of these names will be passed through. -
tlsCERT KEY CA define the TLS properties for TLS connection. From 0 to 3 arguments can be provided with the meaning as described belowtls- no client authentication is used, and the system CAs are used to verify the server certificate (by default)tlsCA - no client authentication is used, and the file CA is used to verify the server certificatetlsCERT KEY - client authentication is used with the specified cert/key pair. The server certificate is verified with the system CAstlsCERT KEY CA - client authentication is used with the specified cert/key pair. The server certificate is verified using the specified CA file
-
policyspecifies the policy to use for selecting upstream servers. The default israndom.
If monitoring is enabled via the prometheus plugin, the following metrics are exported:
coredns_dohproxy_request_duration_seconds{to}- duration per upstream interaction.coredns_dohproxy_requests_total{to}- query count per upstream.coredns_dohproxy_responses_total{to, rcode}- count of RCODEs per upstream.
Proxy all requests within example.org. to a DoH nameserver:
example.org {
dohproxy . cloudflare-dns.com/dns-query
}
Forward everything except requests to example.org
. {
dohproxy . dns.quad9.net/dns-query {
except example.org
}
}
Load balance all requests between multiple upstreams
. {
dohproxy . dns.quad9.net/dns-query cloudflare-dns.com:443/dns-query dns.google/dns-query
}
Internal DoH server:
. {
dohproxy . 10.0.0.10:853/dns-query {
tls ca.crt
tls_servername internal.domain
}
}