COREDNS-TLS(7)

πŸ“¦
version 1.15.0 Β· 3 versions
, in opensuse-leap 16.0

πŸ’… COREDNS-TLS(7) β€” the tls page, but make it cute

okay so bestie, this is COREDNS-TLS(7) from the CoreDNS Plugins manual, and we're about to get so cozy with server certificates. Buckle up, it's giving cryptography but make it group-chat. πŸŽ€


✨ NAME ✨

tls β€” the plugin that lets you configure the server certificates for the TLS, gRPC, and DoH servers. literally the glow-up your traffic deserves πŸ’–


🌸 DESCRIPTION 🌸

So CoreDNS supports queries that are encrypted using TLS (that's DNS over Transport Layer Security, RFC 7858, iconic behavior) or that are using gRPC (https://grpc.io/, which is not an IETF standard, just so we're clear πŸ‘€). Normally DNS traffic isn't encrypted at all β€” like, at all β€” and DNSSEC only signs resource records, it doesn't wrap anything up. no cap.

The tls "plugin" is what lets you configure the cryptographic keys that are needed for both DNS-over-TLS and DNS-over-gRPC. And if the tls plugin is omitted? Then no encryption takes place. zero. nada. 🫠

The gRPC protobuffer is defined in pb/dns.proto β€” it defines the proto as a simple wrapper for the wire data of a DNS message. simple as that, slay.


πŸ¦‹ SYNTAX πŸ¦‹

the base form, look at her:

tls CERT KEY [CA]

Parameter CA is optional, okurr. If it's not set, system CAs can be used to verify the client certificate. 🫢

and then the full version with the lil block:

tls CERT KEY [CA] {
    client_auth nocert|request|require|verify_if_given|require_and_verify
    keylog FILE
}

πŸ’œ the options, one by one

  • client_auth β€” if this option is specified, it controls the client authentication policy. The option value corresponds to the ClientAuthType values of the Go tls package (https://golang.org/pkg/crypto/tls/#ClientAuthType): NoClientCert, RequestClientCert, RequireAnyClientCert, VerifyClientCertIfGiven, and RequireAndVerifyClientCert, respectively. The default is "nocert". And heads up β€” it makes no sense to specify parameter CA unless this option is set to verify_if_given or require_and_verify. like, it's just not the vibe. πŸ™ˆ
  • keylog β€” you can specify keylog to export TLS master secrets in key log format, which allows external programs to decrypt TLS connections.
⚠️ bestie. this one compromises security and should only be used for debugging. not a cute look for production, fr fr. πŸ’€

πŸ”₯ the TLS version tea

CoreDNS sets the minimum TLS version to TLS 1.2. The maximum TLS version, the TLS 1.2 cipher suites, and the key exchange mechanisms all just use the Go crypto/tls defaults. iconic, no drama. ✨

🌈 ACME: the auto-certificate era

Certificates can instead be obtained and renewed automatically with ACME:

tls {
    acme DOMAIN...
    email EMAIL
    ca URL
    storage DIRECTORY
    ca_root FILE
    resolver ADDRESS
}

The acme property enables automatic certificate management for one or more domain names. CoreDNS uses the DNS-01 challenge and answers the temporary _acme-challenge TXT queries on every DNS listener in the same CoreDNS instance. Because of that, the domains' authoritative DNS must reach this CoreDNS instance over port 53. HTTP-01 and TLS-ALPN-01 challenges are not used β€” we don't do those here. 🚫

The remaining properties are optional:

  • email β€” sets the ACME account contact address. πŸ“§
  • ca β€” sets the ACME directory URL. It defaults to the Let's Encrypt production directory.
  • storage β€” sets the directory for ACME accounts, certificates, and private keys. It defaults to .coredns/acme below the Corefile root.
  • ca_root β€” adds a PEM certificate bundle for connecting to a private ACME server. πŸ”
  • resolver β€” sets the DNS resolver used to reach the ACME server, and it must use HOST:PORT syntax.

Certificate management starts in the background after all listeners are active. A new encrypted listener can reject TLS handshakes until its first certificate has been obtained β€” so like, give her a second to get ready πŸ’…. Renewed certificates are used without restarting CoreDNS, which is honestly the main character energy we love to see. πŸ‘‘

🧚 one thing though: the DNS-01 challenge state is local to one CoreDNS process. When authoritative DNS is served by multiple replicas, validation queries must be routed to the replica performing the ACME operation. iykyk.

πŸ“ EXAMPLES πŸ“

1. DNS-over-TLS, classic

Start a DNS-over-TLS server that picks up incoming DNS-over-TLS queries on port 5553 and uses the nameservers defined in /etc/resolv.conf to resolve the query. This proxy path uses plain old DNS.

tls://.:5553 {
    tls cert.pem key.pem ca.pem
    forward . /etc/resolv.conf
}

2. DNS-over-gRPC, same energy

Start a DNS-over-gRPC server that is similar to the previous example, but using DNS-over-gRPC for incoming queries.

grpc://. {
    tls cert.pem key.pem ca.pem
    forward . /etc/resolv.conf
}

3. DoH on 443, she's fancy

Start a DoH server on port 443 that is similar to the previous example, but using DoH for incoming queries.

https://. {
    tls cert.pem key.pem ca.pem
    forward . /etc/resolv.conf
}

4. ACME, the auto-renewal queen

Obtain and renew a certificate for a DoT server. The plain DNS server answers the DNS-01 challenge; both server blocks must be in the same CoreDNS process. (this is the part people forget, don't be that person 🫢)

.:53 {
    file example.org
}

tls://.:853 {
    tls {
        acme dns.example.org
        email hostmaster@example.org
    }
    forward . /etc/resolv.conf
}

5. how do i even test this

Knot DNS' kdig as well as Bind9' dig (since 9.17.7, via +tls) can be used to make DNS-over-TLS queries. And no command line client supports gRPC β€” making debugging these transports harder than it should be. 😭 like why. why must we suffer.


⭐ SEE ALSO ⭐

RFC 7858 (https://www.rfc-editor.org/info/rfc7858/) and https://grpc.io. go read them, they're good for you πŸ’œ


and that's the page!! hope you slayed your certificates ✨ this was COREDNS-TLS(7), from the CoreDNS Plugins manual β€” page by CoreDNS, dated October 2026, and yes the manual name is COREDNS-TLS(7) because she contains multitudes. mwah πŸ’‹πŸŽ€

πŸ“¦ where this page comes from