package checker import ( "fmt" "net" "strings" "time" "github.com/intodns/backend/internal/resolver" "github.com/miekg/dns" ) // checkWWW runs the 2 WWW checks. func checkWWW(domain string, r *resolver.Resolver) Category { cat := Category{Name: "www", Title: "WWW"} domain = dns.Fqdn(domain) wwwName := "www." + domain // 1. www-a-record cat.Checks = append(cat.Checks, checkWWWARecord(wwwName, r)) // 2. www-cname cat.Checks = append(cat.Checks, checkWWWCNAME(wwwName, r)) return cat } func checkWWWARecord(wwwName string, r *resolver.Resolver) CheckResult { start := time.Now() res := CheckResult{ID: "www-a-record", Title: "WWW A Record"} defer func() { res.DurationMs = measureDuration(start) }() resp, err := r.Query(wwwName, "8.8.8.8", dns.TypeA) if err != nil { res.Status = StatusWarn res.Message = fmt.Sprintf("Failed to query A record for %s: %v", wwwName, err) return res } var ips []string for _, rr := range resp.Answer { if a, ok := rr.(*dns.A); ok { ips = append(ips, a.A.String()) } } if len(ips) == 0 { res.Status = StatusInfo res.Message = fmt.Sprintf("No A record found for %s", wwwName) return res } allPublic := true for _, ipStr := range ips { ip := net.ParseIP(ipStr) if isPublicIP(ip) { res.Details = append(res.Details, fmt.Sprintf("%s -> %s (public)", wwwName, ipStr)) } else { allPublic = false res.Details = append(res.Details, fmt.Sprintf("%s -> %s (NOT public)", wwwName, ipStr)) } } if allPublic { res.Status = StatusPass res.Message = fmt.Sprintf("%s has A record(s) with public IP(s)", wwwName) } else { res.Status = StatusWarn res.Message = fmt.Sprintf("%s has A record(s) but some IPs are not public", wwwName) } return res } func checkWWWCNAME(wwwName string, r *resolver.Resolver) CheckResult { start := time.Now() res := CheckResult{ID: "www-cname", Title: "WWW CNAME"} defer func() { res.DurationMs = measureDuration(start) }() resp, err := r.Query(wwwName, "8.8.8.8", dns.TypeCNAME) if err != nil { res.Status = StatusInfo res.Message = fmt.Sprintf("Could not check CNAME for %s", wwwName) return res } var targets []string for _, rr := range resp.Answer { if cname, ok := rr.(*dns.CNAME); ok { targets = append(targets, cname.Target) } } if len(targets) > 0 { res.Status = StatusInfo res.Message = fmt.Sprintf("%s is a CNAME to %s", wwwName, strings.Join(targets, ", ")) for _, t := range targets { res.Details = append(res.Details, fmt.Sprintf("CNAME target: %s", t)) } } else { res.Status = StatusInfo res.Message = fmt.Sprintf("%s is not a CNAME (direct A/AAAA record)", wwwName) } return res }