97 lines
2.2 KiB
Go
97 lines
2.2 KiB
Go
package checker
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
|
|
sdk "git.happydns.org/checker-sdk-go/checker"
|
|
)
|
|
|
|
const (
|
|
hintKey = "hint"
|
|
codeKey = "code"
|
|
)
|
|
|
|
// defaults centralised so Definition's docs and runtime reads cannot drift.
|
|
const (
|
|
defaultNSEC3IterationsMax = 0 // RFC 9276 §3.1
|
|
defaultNSEC3IterationsSeverityWarn = "warn"
|
|
defaultSignatureFreshnessDays = 7
|
|
defaultSignatureFreshnessCrit = 1
|
|
defaultMinRSAKeySize = 2048
|
|
defaultRequireSEP = true
|
|
defaultDNSKEYTTLMinSec = 3600
|
|
)
|
|
|
|
func defaultAllowedAlgorithms() []uint8 { return []uint8{8, 13, 14, 15, 16} }
|
|
func defaultForbiddenAlgorithms() []uint8 { return []uint8{1, 3, 5, 6, 7, 12} }
|
|
|
|
func loadDNSSEC(ctx context.Context, obs sdk.ObservationGetter) (*DNSSECData, []sdk.CheckState) {
|
|
var data DNSSECData
|
|
if err := obs.Get(ctx, ObservationKeyDNSSEC, &data); err != nil {
|
|
return nil, []sdk.CheckState{{
|
|
Status: sdk.StatusError,
|
|
Message: fmt.Sprintf("failed to read dnssec observation: %v", err),
|
|
}}
|
|
}
|
|
return &data, nil
|
|
}
|
|
|
|
func skipped(reason string) []sdk.CheckState {
|
|
return []sdk.CheckState{{
|
|
Status: sdk.StatusUnknown,
|
|
Message: "skipped: " + reason,
|
|
}}
|
|
}
|
|
|
|
func okState(subject, message string) []sdk.CheckState {
|
|
return []sdk.CheckState{{
|
|
Status: sdk.StatusOK,
|
|
Subject: subject,
|
|
Message: message,
|
|
}}
|
|
}
|
|
|
|
func withMeta(s sdk.CheckState, hint, code string) sdk.CheckState {
|
|
if hint == "" && code == "" {
|
|
return s
|
|
}
|
|
if s.Meta == nil {
|
|
s.Meta = map[string]any{}
|
|
}
|
|
if hint != "" {
|
|
s.Meta[hintKey] = hint
|
|
}
|
|
if code != "" {
|
|
s.Meta[codeKey] = code
|
|
s.Code = code
|
|
}
|
|
return s
|
|
}
|
|
|
|
// sortedServers returns the servers map keys in stable order so per-server
|
|
// rule output is reproducible across runs.
|
|
func sortedServers(d *DNSSECData) []string {
|
|
keys := make([]string, 0, len(d.Servers))
|
|
for k := range d.Servers {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
return keys
|
|
}
|
|
|
|
// hasAnyDNSKEY returns true when at least one server returned at least one
|
|
// DNSKEY: a coarse "is the zone signed at all" probe.
|
|
func hasAnyDNSKEY(d *DNSSECData) bool {
|
|
for _, v := range d.Servers {
|
|
if len(v.DNSKEYs) > 0 {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func optionUint(opts sdk.CheckerOptions, key string, def uint) uint {
|
|
return uint(sdk.GetIntOption(opts, key, int(def)))
|
|
}
|