Documentation
¶
Overview ¶
Package localroot maintains a local, verified copy of the root zone (RFC 8806) and answers the three questions the resolver's walk would otherwise ask a root server: where a TLD's delegation lives, whether a TLD's DS exists, and the signed proof that a TLD does not exist.
A copy is only ever served after ZONEMD verification (RFC 8976) chained to the resolver's root trust anchors; refresh follows the zone's own SOA schedule; and a copy past its SOA expire is withdrawn, returning the walk to the real root servers.
Index ¶
- Variables
- func ComputeDigest(rrs []dns.RR, apex string) ([]byte, error)
- func CountApex()
- func CountDS()
- func CountDenial()
- func CountFallback()
- func CountReferral()
- func TLDOf(name string) string
- type Manager
- type Referral
- type Snapshot
- func (s *Snapshot) ApexAnswer(qtype uint16) (rrs, sigs, nsec, nsecSig []dns.RR, ok bool)
- func (s *Snapshot) ApexGlue() []dns.RR
- func (s *Snapshot) BoundTo(until time.Time)
- func (s *Snapshot) DSAnswer(tld string) (ds, dsSig []dns.RR, nsec, nsecSig []dns.RR, ok bool)
- func (s *Snapshot) Denial(name string) (proof []dns.RR, ok bool)
- func (s *Snapshot) Expired(now time.Time) bool
- func (s *Snapshot) Loaded() time.Time
- func (s *Snapshot) Referral(tld string) (Referral, bool)
- func (s *Snapshot) SOA() (*dns.SOA, []dns.RR)
- func (s *Snapshot) Serial() uint32
- func (s *Snapshot) ValidUntil() time.Time
Constants ¶
This section is empty.
Variables ¶
var DefaultSources = []string{
"b.root-servers.net:53",
"c.root-servers.net:53",
"d.root-servers.net:53",
"f.root-servers.net:53",
"g.root-servers.net:53",
"k.root-servers.net:53",
"xfr.cjr.dns.icann.org:53",
"xfr.lax.dns.icann.org:53",
}
DefaultSources are the root servers and ICANN hosts that publish the root zone over AXFR (RFC 8806 appendix A).
Functions ¶
func ComputeDigest ¶
ComputeDigest is RFC 8976 §3.3.1's SIMPLE scheme over SHA-384: every record in canonical wire form and canonical order — owner order (§6.1 of RFC 4034), then ascending TYPE for RRsets sharing an owner, then RDATA (§6.3) — with duplicates collapsed and two exclusions at the apex: the ZONEMD RRset itself, and the RRSIGs covering it.
func CountApex ¶
func CountApex()
CountApex counts a question at the root's own name answered from the copy.
func CountDenial ¶
func CountDenial()
CountDenial counts an NXDOMAIN synthesized from the local copy.
func CountFallback ¶
func CountFallback()
CountFallback counts a root consult the copy did not answer, so the walk went to the real root servers: no verified copy was active, or the copy held no proof of the answer being asked for. Every consult is either an answer of one kind or a fallback, so the kinds sum to the consults.
func CountReferral ¶
func CountReferral()
CountReferral, CountDenial, CountDS and CountFallback attribute walk consultations on the resolver side without exporting the metric vec.
Types ¶
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns the verified snapshot and its refresh lifecycle. Refresh follows the zone's own SOA schedule (RFC 8806 defers to RFC 1035 secondary semantics): probe the serial every REFRESH seconds, fall to RETRY on failure, and never serve a copy past EXPIRE — Active goes nil and the resolver walks to the real roots.
func New ¶
New builds a Manager over the given transfer sources (DefaultSources when empty) and a trust-anchor supplier.
func (*Manager) Active ¶
Active returns the verified snapshot to serve from, or nil when there is none — never transferred, the copy has outlived its horizon, or the trust anchors that verified it are no longer the resolver's.
func (*Manager) Load ¶
Load installs a zone copy obtained by any means, subject to the same gate as a live transfer: full ZONEMD verification against the trust anchors, RFC 1982 serial acceptance against the live copy, then an atomic swap. There is no unverified path into the active snapshot, and no path backwards — a replayed older zone, however validly signed for its day, cannot displace a newer copy or restart its expire horizon.
type Referral ¶
type Referral struct {
NS []dns.RR
DS []dns.RR
Glue map[string][]dns.RR // canonical NS host -> A/AAAA records
// NSTTL is the delegation's own lifetime: the smallest TTL among its NS
// records. Computed here, with the same helper as every other RRset
// lifetime, so callers do not each grow their own notion of what an
// empty or zero-TTL set means.
NSTTL uint32
// SecurityTTL is how long the delegation's DNSSEC status may be relied
// on: the DS RRset's own smallest TTL when the delegation is signed, or
// the TTL of the NSEC that proves no DS exists when it is not. A
// delegation whose status the copy cannot evidence at all reports zero,
// which drives the caller's lease to zero and sends the walk to the
// real roots rather than asserting an unproven security status.
SecurityTTL uint32
}
Referral is the delegation material for one TLD: the NS set, the DS set (empty for an unsigned delegation), and the glue addresses for each NS target present in the zone.
type Snapshot ¶
type Snapshot struct {
// contains filtered or unexported fields
}
Snapshot is one immutable, verified copy of the root zone, indexed for the three lookups the resolver makes. It is built once and never mutated; the manager publishes it with an atomic pointer swap.
func (*Snapshot) ApexAnswer ¶
ApexAnswer returns what the copy holds at the root's own name for qtype: the RRset with its signatures when the type exists there, or the apex NSEC with its signatures as the NODATA proof when it does not. ok=false when the copy can say neither — the caller then asks the real roots.
The apex is the one part of the zone the copy is authoritative-shaped about in the ordinary sense: NS, SOA, DNSKEY and the rest are the root's own records, signed, and the copy carries them. Sending those questions to a root server while holding a verified copy of the answer is the one thing this whole package exists to stop doing.
func (*Snapshot) ApexGlue ¶
ApexGlue returns the address records the copy holds for the root's own NS targets — the additional section of a priming response (RFC 9609). The root zone carries these as glue below the delegation that owns them, so they have no signatures of their own; the ZONEMD digest is what authenticates them, and the additional section is outside what AD claims (RFC 4035 §3.2.3) exactly as it is in a real root server's answer.
Without them the copy's answer to a root priming query names the servers but gives no way to reach them, and the resolver's own 12-hourly priming cannot refresh its root server list from it.
func (*Snapshot) BoundTo ¶
BoundTo shortens the horizon to at most until. The caller uses it for a bound the records themselves cannot express — the expiration of the signature that authenticated the zone digest, which is what makes the whole copy evidence in the first place.
func (*Snapshot) DSAnswer ¶
DSAnswer returns the material for an authoritative DS response at tld: the DS set with its RRSIGs when the delegation is signed, or the TLD's own NSEC with its RRSIGs as the exact-owner NODATA proof when it is not. ok=false when the TLD does not exist, or when the copy holds no NSEC that actually proves the DS absent — the absence of a DS record in the index is not itself a proof, and an answer that cannot be proven is left to the real roots.
func (*Snapshot) Denial ¶
Denial returns the NSEC records proving name does not exist under the root: the covering NSEC for the name and the apex NSEC as the wildcard proof (deduplicated when they are the same record), each with RRSIGs. ok=false when the chain cannot cover the name — a snapshot in that state is not usable for denial and the caller falls back.
func (*Snapshot) Expired ¶
Expired reports whether the copy has outlived its horizon — the SOA expire interval (RFC 1035 secondary semantics) or the earliest RRSIG expiration in the zone, whichever comes first — and must no longer be served.
func (*Snapshot) Referral ¶
Referral returns the delegation for tld (a canonical, rooted, one-label name) or ok=false when the zone holds no such delegation.
func (*Snapshot) ValidUntil ¶
ValidUntil is the copy's serving horizon; nothing derived from the copy may claim a longer life.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package roottest builds a miniature signed root zone for tests: an apex with SOA/NS/DNSKEY/NSEC sealed by a ZONEMD, a signed delegation (com., with DS), an unsigned delegation (org., NSEC without the DS bit), and in-zone glue.
|
Package roottest builds a miniature signed root zone for tests: an apex with SOA/NS/DNSKEY/NSEC sealed by a ZONEMD, a signed delegation (com., with DS), an unsigned delegation (org., NSEC without the DS bit), and in-zone glue. |