checker-ptr/checker/types.go

115 lines
4.4 KiB
Go

package checker
import (
"encoding/json"
"github.com/miekg/dns"
)
// ObservationKeyPTR is the observation key for the PTR checker payload.
const ObservationKeyPTR = "ptr"
// ForwardAddress records a single A/AAAA answer collected for the PTR target.
type ForwardAddress struct {
Type string `json:"type"` // "A" or "AAAA"
Address string `json:"address"`
TTL uint32 `json:"ttl,omitempty"`
}
// PTRData is the raw observation payload persisted by the checker. It
// contains NO judgement: severity, pass/fail and derived issues are the
// responsibility of CheckRule implementations.
type PTRData struct {
// OwnerName is the FQDN of the PTR record as declared by the service
// (the reverse-arpa name, e.g. "4.3.2.1.in-addr.arpa.").
OwnerName string `json:"owner_name"`
// DeclaredTarget is the hostname the service says the PTR should point
// to. Always fully-qualified and lowercased.
DeclaredTarget string `json:"declared_target"`
// DeclaredTTL is the TTL declared by the service.
DeclaredTTL uint32 `json:"declared_ttl,omitempty"`
// InReverseArpa reports whether OwnerName lies under in-addr.arpa or
// ip6.arpa.
InReverseArpa bool `json:"in_reverse_arpa"`
// IsIPv6 reports whether OwnerName is an ip6.arpa name.
IsIPv6 bool `json:"is_ipv6"`
// ReverseIP is the IP address reconstructed from OwnerName (if parseable).
ReverseIP string `json:"reverse_ip,omitempty"`
// OwnerDecodeFailed is true when OwnerName lies under *.arpa but no IP
// could be decoded from it (malformed labels).
OwnerDecodeFailed bool `json:"owner_decode_failed,omitempty"`
// ReverseZone is the apex of the reverse zone serving OwnerName (where
// the SOA lives). Empty when it could not be located.
ReverseZone string `json:"reverse_zone,omitempty"`
// ReverseNS are the authoritative servers of the reverse zone.
ReverseNS []string `json:"reverse_ns,omitempty"`
// ZoneLookupError captures the transport/NXDOMAIN-style failure
// encountered while walking up to find the SOA. Empty on success.
ZoneLookupError string `json:"zone_lookup_error,omitempty"`
// ObservedTargets lists every PTR target observed at OwnerName. In a
// healthy setup, this has exactly one entry equal to DeclaredTarget.
ObservedTargets []string `json:"observed_targets,omitempty"`
// ObservedTTL is the TTL of the PTR RRset as seen from authoritative
// servers.
ObservedTTL uint32 `json:"observed_ttl,omitempty"`
// QueryError captures a transport-level failure while querying the PTR
// RRset (unreachable servers, timeouts, …). Empty on success.
QueryError string `json:"query_error,omitempty"`
// Rcode is the textual rcode of the PTR lookup (e.g. "NOERROR",
// "NXDOMAIN", "SERVFAIL"); empty when not applicable.
Rcode string `json:"rcode,omitempty"`
// EffectiveTarget is the hostname actually examined for hygiene and
// FCrDNS (the first observed target, or the declared one when none is
// observed). Empty when neither is available.
EffectiveTarget string `json:"effective_target,omitempty"`
// TargetSyntaxValid reports whether EffectiveTarget parses as a valid
// DNS hostname. False when EffectiveTarget is empty or malformed.
TargetSyntaxValid bool `json:"target_syntax_valid,omitempty"`
// TargetLooksGeneric reports whether EffectiveTarget embeds the IP or
// matches common ISP auto-generated patterns.
TargetLooksGeneric bool `json:"target_looks_generic,omitempty"`
// ForwardAddresses are the A/AAAA addresses the target resolves to
// (recursive resolution from the system resolver).
ForwardAddresses []ForwardAddress `json:"forward_addresses,omitempty"`
// ForwardMatch is true when ReverseIP appears among ForwardAddresses
// (Forward-Confirmed Reverse DNS).
ForwardMatch bool `json:"forward_match,omitempty"`
// TargetResolves is true when the PTR target produced at least one A or
// AAAA. Distinct from ForwardMatch: a target can resolve yet point
// somewhere else.
TargetResolves bool `json:"target_resolves,omitempty"`
}
// ptrService is the minimal local mirror of happyDomain's `svcs.PTR`. It
// carries a single *dns.PTR. The JSON key matches the Go struct field name
// used in happyDomain (`Record`).
type ptrService struct {
Record *dns.PTR `json:"Record"`
}
// serviceMessage is the minimal local mirror of happyDomain's ServiceMessage
// envelope.
type serviceMessage struct {
Type string `json:"_svctype"`
Domain string `json:"_domain"`
Service json.RawMessage `json:"Service"`
}