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 }