56 lines
2.1 KiB
Go
56 lines
2.1 KiB
Go
|
|
// Package rfc2136 implements a CoreDNS plugin that accepts dynamic DNS
|
||
|
|
// updates per RFC 2136 (UPDATE opcode), authenticated via TSIG. The
|
||
|
|
// primary use case is self-hosted ACME DNS-01 cert automation: an ACME
|
||
|
|
// client (e.g. Caddy via caddy-dns/rfc2136) injects _acme-challenge TXT
|
||
|
|
// records into a delegated sub-zone that this plugin serves.
|
||
|
|
//
|
||
|
|
// Scope:
|
||
|
|
// - Handles UPDATE messages (OPCODE=5) for configured zones.
|
||
|
|
// - Verifies TSIG signatures (HMAC-SHA256 today; algorithm-pluggable).
|
||
|
|
// - Stores records in memory; optional periodic snapshot to disk.
|
||
|
|
// - Serves queries (SOA, NS, A, AAAA, TXT) for the configured zone
|
||
|
|
// from the in-memory store plus a synthetic SOA/NS apex.
|
||
|
|
//
|
||
|
|
// Non-goals:
|
||
|
|
// - General-purpose authoritative DNS (use `auto`/`file` for that).
|
||
|
|
// - DNSSEC signing (add later via the `dnssec` plugin in front).
|
||
|
|
//
|
||
|
|
// Phase 1 status: skeleton only. ServeDNS passes through to the next
|
||
|
|
// plugin; setup parses the Corefile but does not yet do anything with
|
||
|
|
// the parsed configuration. See plan at
|
||
|
|
// ~/.claude/plans/dood-does-coredns-offer-enumerated-piglet.md
|
||
|
|
package rfc2136
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
|
||
|
|
"github.com/coredns/coredns/plugin"
|
||
|
|
"github.com/miekg/dns"
|
||
|
|
)
|
||
|
|
|
||
|
|
// RFC2136 is the plugin handler. One instance per Corefile server block.
|
||
|
|
type RFC2136 struct {
|
||
|
|
// Next is the downstream plugin in the chain.
|
||
|
|
Next plugin.Handler
|
||
|
|
|
||
|
|
// Zones is the set of canonical (dot-terminated, lowercase) zone
|
||
|
|
// names this instance is authoritative for. Queries outside these
|
||
|
|
// zones pass through to Next.
|
||
|
|
Zones []string
|
||
|
|
|
||
|
|
// Phase 2 will add:
|
||
|
|
// - tsigKeys map[string]tsigKey
|
||
|
|
// - store *recordStore
|
||
|
|
// - ttl uint32
|
||
|
|
}
|
||
|
|
|
||
|
|
// Name implements plugin.Handler.
|
||
|
|
func (p *RFC2136) Name() string { return "rfc2136" }
|
||
|
|
|
||
|
|
// ServeDNS implements plugin.Handler. Phase 1 is a pass-through so the
|
||
|
|
// plugin can register, parse config, and live in the chain without
|
||
|
|
// changing behavior. Phase 2 wires the UPDATE handler and zone serving.
|
||
|
|
func (p *RFC2136) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
|
||
|
|
return plugin.NextOrFailure(p.Name(), p.Next, ctx, w, r)
|
||
|
|
}
|