71 lines
3.1 KiB
Go
71 lines
3.1 KiB
Go
// SPDX-License-Identifier: MIT
|
|
|
|
// Package checker implements a happyDomain checker that wraps DNSViz
|
|
// (https://github.com/dnsviz/dnsviz). It runs `dnsviz probe` followed by
|
|
// `dnsviz grok` against a domain, stores the structured analysis as the
|
|
// observation, and turns the per-zone errors/warnings into CheckStates.
|
|
//
|
|
// The container ships dnsviz alongside this binary, so the checker has no
|
|
// external dependency at runtime besides the network.
|
|
package checker
|
|
|
|
import (
|
|
sdk "git.happydns.org/checker-sdk-go/checker"
|
|
)
|
|
|
|
// ObservationKeyDNSViz is the observation key for DNSViz analysis output.
|
|
const ObservationKeyDNSViz sdk.ObservationKey = "dnsviz"
|
|
|
|
// DNSVizData is what Collect stores. It carries the full grok output
|
|
// (parsed into a permissive structure) plus the raw bytes for the report.
|
|
//
|
|
// DNSViz emits a single top-level object whose keys are zone FQDNs (with
|
|
// trailing dot), one per level of the chain. Inside each zone object the
|
|
// shape is permissive: many fields are conditional, so we keep most of them
|
|
// as map[string]any and only pluck out what the rules need.
|
|
type DNSVizData struct {
|
|
// Domain is the queried FQDN, with trailing dot stripped.
|
|
Domain string `json:"domain"`
|
|
|
|
// Zones is the per-zone analysis, keyed by zone FQDN (with trailing dot
|
|
// preserved, matching DNSViz's output).
|
|
Zones map[string]ZoneAnalysis `json:"zones"`
|
|
|
|
// Order is Zones' keys, sorted from the queried name up to the root.
|
|
// We surface it explicitly so the report can render in a stable order
|
|
// without having to re-sort on every render.
|
|
Order []string `json:"order,omitempty"`
|
|
|
|
// Raw is the unmodified `dnsviz grok` JSON. Kept around so the report
|
|
// can fall back on it for fields the typed view does not capture.
|
|
Raw []byte `json:"raw,omitempty"`
|
|
|
|
// ProbeStderr / GrokStderr capture the diagnostics dnsviz prints to
|
|
// stderr. Useful when collection succeeds but the analysis is partial.
|
|
ProbeStderr string `json:"probe_stderr,omitempty"`
|
|
GrokStderr string `json:"grok_stderr,omitempty"`
|
|
}
|
|
|
|
// ZoneAnalysis is a permissive view over one zone's grok block.
|
|
//
|
|
// DNSViz uses a small set of statuses ("SECURE", "BOGUS", "INSECURE",
|
|
// "INDETERMINATE", "NON_EXISTENT") and groups problems into "errors" and
|
|
// "warnings" arrays. Each finding has a "description" and may carry a
|
|
// "code" plus a list of servers it was observed on. We expose those as a
|
|
// stable Finding type and keep everything else under Extra for the report.
|
|
type ZoneAnalysis struct {
|
|
Status string `json:"status,omitempty"`
|
|
Errors []Finding `json:"errors,omitempty"`
|
|
Warnings []Finding `json:"warnings,omitempty"`
|
|
Extra map[string]any `json:"extra,omitempty"`
|
|
}
|
|
|
|
// Finding mirrors the shape DNSViz uses for entries in errors/warnings.
|
|
// Producers occasionally use slightly different field names across versions
|
|
// of dnsviz; we accept both `description`/`message` for the human text and
|
|
// fall back to a generic stringification at parse time.
|
|
type Finding struct {
|
|
Code string `json:"code,omitempty"`
|
|
Description string `json:"description"`
|
|
Servers []string `json:"servers,omitempty"`
|
|
}
|