Initial commit
This commit is contained in:
commit
34ce70272a
18 changed files with 1866 additions and 0 deletions
140
checker/types.go
Normal file
140
checker/types.go
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
// This file is part of the happyDomain (R) project.
|
||||
// Copyright (c) 2026 happyDomain
|
||||
// Authors: Pierre-Olivier Mercier, et al.
|
||||
//
|
||||
// This program is offered under a commercial and under the AGPL license.
|
||||
// For commercial licensing, contact us at <contact@happydomain.org>.
|
||||
//
|
||||
// For AGPL licensing:
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
package checker
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// ObservationKeyAlias is the observation key for alias data.
|
||||
const ObservationKeyAlias = "alias"
|
||||
|
||||
// Severity classifies a finding emitted by the alias checker.
|
||||
type Severity string
|
||||
|
||||
const (
|
||||
SeverityInfo Severity = "info"
|
||||
SeverityWarn Severity = "warn"
|
||||
SeverityCrit Severity = "crit"
|
||||
)
|
||||
|
||||
// AliasKind identifies the flavour of indirection involved in a hop.
|
||||
type AliasKind string
|
||||
|
||||
const (
|
||||
KindCNAME AliasKind = "CNAME"
|
||||
KindDNAME AliasKind = "DNAME"
|
||||
KindALIAS AliasKind = "ALIAS" // provider-flattened apex alias (pseudo-record)
|
||||
KindTarget AliasKind = "TARGET"
|
||||
)
|
||||
|
||||
// ChainHop represents one step of the resolution chain.
|
||||
type ChainHop struct {
|
||||
Owner string `json:"owner"`
|
||||
Kind AliasKind `json:"kind"`
|
||||
Target string `json:"target,omitempty"`
|
||||
TTL uint32 `json:"ttl,omitempty"`
|
||||
// Server is the authoritative server that answered for this hop.
|
||||
Server string `json:"server,omitempty"`
|
||||
// Synthesized is true when this hop is a CNAME synthesized from a DNAME.
|
||||
Synthesized bool `json:"synthesized,omitempty"`
|
||||
}
|
||||
|
||||
// AliasFinding describes a single observation produced while running
|
||||
// the alias testsuite.
|
||||
type AliasFinding struct {
|
||||
Code string `json:"code"`
|
||||
Severity Severity `json:"severity"`
|
||||
Message string `json:"message"`
|
||||
// Subject names the owner/target the finding applies to.
|
||||
Subject string `json:"subject,omitempty"`
|
||||
// Hint is a short remediation suggestion, surfaced by the HTML report.
|
||||
Hint string `json:"hint,omitempty"`
|
||||
}
|
||||
|
||||
// CoexistingRRset records an RRset that sits next to a CNAME at the same owner.
|
||||
type CoexistingRRset struct {
|
||||
Type string `json:"type"`
|
||||
TTL uint32 `json:"ttl,omitempty"`
|
||||
}
|
||||
|
||||
// AliasData is the observation payload persisted by the checker.
|
||||
type AliasData struct {
|
||||
// Owner is the name we started resolving from (FQDN).
|
||||
Owner string `json:"owner"`
|
||||
|
||||
// Apex is the zone apex of Owner (where SOA lives).
|
||||
Apex string `json:"apex,omitempty"`
|
||||
|
||||
// AuthServers are the authoritative servers of the apex zone.
|
||||
AuthServers []string `json:"auth_servers,omitempty"`
|
||||
|
||||
// Chain is the ordered list of hops from Owner down to the final
|
||||
// resolvable (or unresolvable) target.
|
||||
Chain []ChainHop `json:"chain,omitempty"`
|
||||
|
||||
// FinalTarget is the last name in the chain (possibly Owner itself when
|
||||
// there is no indirection).
|
||||
FinalTarget string `json:"final_target,omitempty"`
|
||||
|
||||
// FinalA / FinalAAAA hold the addresses that the chain ultimately resolves
|
||||
// to. Empty when the target does not produce any address.
|
||||
FinalA []string `json:"final_a,omitempty"`
|
||||
FinalAAAA []string `json:"final_aaaa,omitempty"`
|
||||
|
||||
// Rcode is the textual rcode of the final lookup (e.g. "NOERROR",
|
||||
// "NXDOMAIN", "SERVFAIL"); empty when not applicable.
|
||||
Rcode string `json:"rcode,omitempty"`
|
||||
|
||||
// Coexisting lists RRsets that share the owner with a CNAME. Populated
|
||||
// only when a CNAME is present at Owner.
|
||||
Coexisting []CoexistingRRset `json:"coexisting,omitempty"`
|
||||
|
||||
// OwnerIsApex is true when the queried name is the zone apex.
|
||||
OwnerIsApex bool `json:"owner_is_apex,omitempty"`
|
||||
|
||||
// ApexFlattening is true when the apex returns A/AAAA alongside SOA/NS
|
||||
// (classic ALIAS/ANAME provider-side flattening).
|
||||
ApexFlattening bool `json:"apex_flattening,omitempty"`
|
||||
|
||||
// ZoneSigned reports whether the apex has DNSKEY records (DNSSEC signed).
|
||||
ZoneSigned bool `json:"zone_signed,omitempty"`
|
||||
|
||||
// CNAMESigned reports whether the CNAME hop at Owner carries an RRSIG.
|
||||
CNAMESigned bool `json:"cname_signed,omitempty"`
|
||||
|
||||
// DNAMESubstitutions records any DNAME record encountered above Owner
|
||||
// that rewrote the name during resolution.
|
||||
DNAMESubstitutions []ChainHop `json:"dname_substitutions,omitempty"`
|
||||
|
||||
// Findings is the full list of issues produced by the run.
|
||||
Findings []AliasFinding `json:"findings"`
|
||||
}
|
||||
|
||||
// cnameService is the minimal local mirror of happyDomain's `svcs.CNAME` and
|
||||
// `svcs.SpecialCNAME` types. Both carry a single *dns.CNAME under the key
|
||||
// "cname". github.com/miekg/dns marshals it in the shape happyDomain uses.
|
||||
type cnameService struct {
|
||||
Record *dns.CNAME `json:"cname"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue