Initial commit
This commit is contained in:
commit
d4a59fb9e8
18 changed files with 1439 additions and 0 deletions
238
checker/deprecated.go
Normal file
238
checker/deprecated.go
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
package checker
|
||||
|
||||
import (
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// DeprecatedSeverity grades a deprecated record family.
|
||||
//
|
||||
// "Critical" reflects record types whose continued use breaks DNSSEC
|
||||
// validation or modern resolvers (KEY/SIG/NXT, replaced by the DNSSEC-bis
|
||||
// triplet, RFC 3755). "Warning" covers types that still parse but have a
|
||||
// long-standing replacement (SPF→TXT, A6→AAAA, …). "Info" is reserved for
|
||||
// experimental types nobody implements anymore (NULL, NSAP, …): present in
|
||||
// a zone is harmless but pointless.
|
||||
type DeprecatedSeverity int
|
||||
|
||||
const (
|
||||
SeverityInfo DeprecatedSeverity = iota
|
||||
SeverityWarn
|
||||
SeverityCrit
|
||||
)
|
||||
|
||||
func (s DeprecatedSeverity) String() string {
|
||||
switch s {
|
||||
case SeverityCrit:
|
||||
return "crit"
|
||||
case SeverityWarn:
|
||||
return "warn"
|
||||
default:
|
||||
return "info"
|
||||
}
|
||||
}
|
||||
|
||||
// DeprecationInfo describes one deprecated RR type.
|
||||
type DeprecationInfo struct {
|
||||
Reason string
|
||||
|
||||
// Replacement is the modern record type to use instead, or "" when the
|
||||
// type has no replacement (just remove the record).
|
||||
Replacement string
|
||||
|
||||
// HowToFix is the actionable instruction shown in the HTML report.
|
||||
// Phrased as a direct imperative so the user can act without context
|
||||
// switching to the relevant RFC.
|
||||
HowToFix string
|
||||
|
||||
Severity DeprecatedSeverity
|
||||
}
|
||||
|
||||
// deprecatedTypes is the source of truth for what counts as legacy.
|
||||
//
|
||||
// Numeric keys (instead of dns.TypeXxx) are used for types miekg/dns does
|
||||
// not export as named constants; they remain valid wire types and may
|
||||
// well show up in zones imported from BIND or older tooling.
|
||||
var deprecatedTypes = map[uint16]DeprecationInfo{
|
||||
// --- DNSSEC predecessors (RFC 3755, RFC 4033 family) -----------------
|
||||
dns.TypeKEY: {
|
||||
Reason: "RFC 3755 obsoleted KEY in favour of DNSKEY",
|
||||
Replacement: "DNSKEY",
|
||||
HowToFix: "Re-sign the zone with a DNSSEC implementation that emits DNSKEY/RRSIG/NSEC records, then remove the KEY entries.",
|
||||
Severity: SeverityCrit,
|
||||
},
|
||||
dns.TypeSIG: {
|
||||
Reason: "RFC 3755 obsoleted SIG in favour of RRSIG",
|
||||
Replacement: "RRSIG",
|
||||
HowToFix: "SIG records are not validated by modern resolvers. Drop them; RRSIG records are produced automatically when the zone is DNSSEC-signed.",
|
||||
Severity: SeverityCrit,
|
||||
},
|
||||
dns.TypeNXT: {
|
||||
Reason: "RFC 3755 obsoleted NXT in favour of NSEC",
|
||||
Replacement: "NSEC",
|
||||
HowToFix: "NXT predates DNSSEC-bis and is not understood by current validators. Re-sign the zone to produce NSEC (or NSEC3) records and remove NXT.",
|
||||
Severity: SeverityCrit,
|
||||
},
|
||||
|
||||
// --- Replaced by a clear modern equivalent ---------------------------
|
||||
dns.TypeSPF: {
|
||||
Reason: "RFC 7208 §3.1 deprecated the SPF record type; publish SPF policy in TXT only",
|
||||
Replacement: "TXT",
|
||||
HowToFix: "Publish the SPF policy as a TXT record (`v=spf1 …`) at the same owner name, then delete the SPF-typed record. Some receivers ignore SPF-typed records entirely.",
|
||||
Severity: SeverityWarn,
|
||||
},
|
||||
38: { // A6
|
||||
Reason: "RFC 6563 moved A6 to historic status",
|
||||
Replacement: "AAAA",
|
||||
HowToFix: "Replace each A6 record with an equivalent AAAA record carrying the full IPv6 address.",
|
||||
Severity: SeverityWarn,
|
||||
},
|
||||
dns.TypeMD: {
|
||||
Reason: "RFC 973 obsoleted MD in 1986; use MX",
|
||||
Replacement: "MX",
|
||||
HowToFix: "Translate the mail-destination into an MX record (preference + exchange host) and delete the MD record.",
|
||||
Severity: SeverityWarn,
|
||||
},
|
||||
dns.TypeMF: {
|
||||
Reason: "RFC 973 obsoleted MF in 1986; use MX",
|
||||
Replacement: "MX",
|
||||
HowToFix: "Translate the mail-forwarder into an MX record (preference + exchange host) and delete the MF record.",
|
||||
Severity: SeverityWarn,
|
||||
},
|
||||
dns.TypeGPOS: {
|
||||
Reason: "RFC 1712 superseded GPOS with LOC",
|
||||
Replacement: "LOC",
|
||||
HowToFix: "If geolocation is genuinely needed, publish a LOC record instead. Otherwise delete the GPOS record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
|
||||
// --- Privacy/info-leak deprecations ----------------------------------
|
||||
dns.TypeMB: {
|
||||
Reason: "RFC 2505/RFC 1035 §3.3: experimental, unused; replaced by MX",
|
||||
Replacement: "MX",
|
||||
HowToFix: "Delete the MB record; route mailbox traffic via MX.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeMG: {
|
||||
Reason: "RFC 1035 §3.3: experimental mail-group record, never widely deployed",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the MG record; mail-group semantics now belong on the SMTP layer.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeMR: {
|
||||
Reason: "RFC 1035 §3.3: experimental mail-rename record, never widely deployed",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the MR record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeMINFO: {
|
||||
Reason: "RFC 1035 §3.3: experimental mailbox-info record, never widely deployed",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the MINFO record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeNULL: {
|
||||
Reason: "RFC 1035 §3.3.10: experimental, must not appear in master files",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the NULL record. If it is used as a private channel, switch to TXT or a dedicated underscore label.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
11: { // WKS
|
||||
Reason: "RFC 1123 §6.1.3.6 discouraged WKS; modern stacks ignore it",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the WKS record. Service availability belongs in SRV, ALPN, or HTTPS/SVCB records, not WKS.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
|
||||
// --- Historical address families (no live deployment) ----------------
|
||||
22: { // NSAP
|
||||
Reason: "RFC 1706 historical: OSI/CLNP addressing, no current deployment",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the NSAP record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeNSAPPTR: {
|
||||
Reason: "RFC 1706 historical: OSI reverse mapping, no current deployment",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the NSAP-PTR record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeX25: {
|
||||
Reason: "RFC 1183 historical: X.25 addressing, no current deployment",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the X25 record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeISDN: {
|
||||
Reason: "RFC 1183 historical: ISDN addressing, no current deployment",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the ISDN record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeRT: {
|
||||
Reason: "RFC 1183 historical: route-through, superseded by direct routing",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the RT record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
dns.TypeATMA: {
|
||||
Reason: "ATM Forum AF-SAA-0069 historical: ATM addressing, no current deployment",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the ATMA record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
31: { // EID
|
||||
Reason: "Nimrod EID: never deployed beyond the experiment",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the EID record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
32: { // NIMLOC
|
||||
Reason: "Nimrod NIMLOC: never deployed beyond the experiment",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the NIMLOC record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
40: { // SINK
|
||||
Reason: "draft-eastlake-kitchen-sink: never standardised",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the SINK record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
56: { // NINFO
|
||||
Reason: "draft-reid-dnsext-zs: never standardised",
|
||||
Replacement: "TXT",
|
||||
HowToFix: "If you need free-form zone metadata, use a TXT record at the apex with a clearly scoped prefix.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
57: { // RKEY
|
||||
Reason: "draft-reid-dnsext-rkey: never standardised",
|
||||
Replacement: "",
|
||||
HowToFix: "Delete the RKEY record.",
|
||||
Severity: SeverityInfo,
|
||||
},
|
||||
}
|
||||
|
||||
// extraTypeNames covers the deprecated record types that miekg/dns does
|
||||
// not list in TypeToString (WKS, NSAP, A6, SINK). Without this fallback,
|
||||
// typeLabel would return "TYPEnnn" for them and the report would lose the
|
||||
// human-friendly name.
|
||||
var extraTypeNames = map[uint16]string{
|
||||
11: "WKS",
|
||||
22: "NSAP",
|
||||
38: "A6",
|
||||
40: "SINK",
|
||||
}
|
||||
|
||||
// typeLabel returns the textual record type name. dns.TypeToString covers
|
||||
// the well-known set; for unknown rrtypes we fall back to RFC 3597 form
|
||||
// ("TYPEnnn") so the report stays readable.
|
||||
func typeLabel(rrtype uint16) string {
|
||||
if name, ok := dns.TypeToString[rrtype]; ok {
|
||||
return name
|
||||
}
|
||||
if name, ok := extraTypeNames[rrtype]; ok {
|
||||
return name
|
||||
}
|
||||
// dns.Type stringer produces "TYPEnnn" for unknown types (RFC 3597).
|
||||
return dns.Type(rrtype).String()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue