63 lines
2.2 KiB
Go
63 lines
2.2 KiB
Go
package checker
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
sdk "git.happydns.org/checker-sdk-go/checker"
|
|
)
|
|
|
|
// cnameCoexistenceRule flags sibling RRsets at the CNAME's owner (RFC 1034
|
|
// §3.6.2, RFC 2181 §10.1). Severity follows the shared allowApexCNAME option
|
|
// when the owner is the apex; A/AAAA siblings at apex are excused when the
|
|
// zone publishes ALIAS/ANAME flattening and recognizeApexFlattening is on.
|
|
type cnameCoexistenceRule struct{}
|
|
|
|
func (cnameCoexistenceRule) Name() string { return "cname_coexistence" }
|
|
func (cnameCoexistenceRule) Description() string {
|
|
return "Flags other RRsets that sit at the same owner as a CNAME (RFC 1034 §3.6.2 / RFC 2181 §10.1). Honours allowApexCNAME and recognizeApexFlattening."
|
|
}
|
|
|
|
func (cnameCoexistenceRule) Evaluate(ctx context.Context, obs sdk.ObservationGetter, opts sdk.CheckerOptions) []sdk.CheckState {
|
|
data, errState := loadAlias(ctx, obs)
|
|
if errState != nil {
|
|
return errState
|
|
}
|
|
if !apexKnown(data) {
|
|
return skipped("apex lookup failed")
|
|
}
|
|
if !data.OwnerHasCNAME {
|
|
return skipped("owner has no CNAME")
|
|
}
|
|
if len(data.Coexisting) == 0 {
|
|
return okState(data.Owner, "CNAME is the only RRset at its owner")
|
|
}
|
|
|
|
isApex := data.OwnerIsApex
|
|
recognize := recognizeApexFlattening(opts)
|
|
allow := allowApexCNAME(opts)
|
|
|
|
var out []sdk.CheckState
|
|
for _, rr := range data.Coexisting {
|
|
// A/AAAA at apex alongside a CNAME is excused when we recognise
|
|
// ALIAS/ANAME flattening: two different owners cannot legally
|
|
// coexist, but a provider-side flattener can still serve that.
|
|
if isApex && recognize && data.ApexFlattening && (rr.Type == "A" || rr.Type == "AAAA") {
|
|
continue
|
|
}
|
|
status := sdk.StatusCrit
|
|
if isApex && allow {
|
|
status = sdk.StatusWarn
|
|
}
|
|
out = append(out, withHint(sdk.CheckState{
|
|
Status: status,
|
|
Subject: data.Owner,
|
|
Message: fmt.Sprintf("%s and CNAME both exist at %s (RFC 1034 §3.6.2 / RFC 2181 §10.1)", rr.Type, data.Owner),
|
|
Code: rr.Type,
|
|
}, "Remove the sibling record or move it under a different label; a name cannot simultaneously carry a CNAME and other data."))
|
|
}
|
|
if len(out) == 0 {
|
|
return okState(data.Owner, "CNAME coexistence exempted by ALIAS/ANAME flattening")
|
|
}
|
|
return out
|
|
}
|