func answerSOA(q *dns.Question, e *DNSEntry) dns.RR { answer := new(dns.SOA) answer.Header().Name = q.Name answer.Header().Rrtype = dns.TypeSOA answer.Header().Class = dns.ClassINET answer.Ns = strings.TrimSuffix(e.Meta["ns"], ".") + "." answer.Mbox = strings.TrimSuffix(e.Meta["mbox"], ".") + "." answer.Serial = uint32(time.Now().Unix()) answer.Refresh = uint32(60) // only used for master->slave timing answer.Retry = uint32(60) // only used for master->slave timing answer.Expire = uint32(60) // only used for master->slave timing answer.Minttl = uint32(60) // how long caching resolvers should cache a miss (NXDOMAIN status) return answer }
func mockDNSQuery(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) m.Compress = false appendAnswer := func(rr dns.RR) { m.Answer = append(m.Answer, rr) } for _, q := range r.Question { q.Name = strings.ToLower(q.Name) if q.Name == "servfail.com." { m.Rcode = dns.RcodeServerFailure break } switch q.Qtype { case dns.TypeSOA: record := new(dns.SOA) record.Hdr = dns.RR_Header{Name: "letsencrypt.org.", Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: 0} record.Ns = "ns.letsencrypt.org." record.Mbox = "master.letsencrypt.org." record.Serial = 1 record.Refresh = 1 record.Retry = 1 record.Expire = 1 record.Minttl = 1 appendAnswer(record) case dns.TypeAAAA: if q.Name == "v6.letsencrypt.org." { record := new(dns.AAAA) record.Hdr = dns.RR_Header{Name: "v6.letsencrypt.org.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} record.AAAA = net.ParseIP("::1") appendAnswer(record) } if q.Name == "dualstack.letsencrypt.org." { record := new(dns.AAAA) record.Hdr = dns.RR_Header{Name: "dualstack.letsencrypt.org.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} record.AAAA = net.ParseIP("::1") appendAnswer(record) } if q.Name == "v4error.letsencrypt.org." { record := new(dns.AAAA) record.Hdr = dns.RR_Header{Name: "v4error.letsencrypt.org.", Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0} record.AAAA = net.ParseIP("::1") appendAnswer(record) } if q.Name == "v6error.letsencrypt.org." { m.SetRcode(r, dns.RcodeNotImplemented) } if q.Name == "nxdomain.letsencrypt.org." { m.SetRcode(r, dns.RcodeNameError) } if q.Name == "dualstackerror.letsencrypt.org." { m.SetRcode(r, dns.RcodeNotImplemented) } case dns.TypeA: if q.Name == "cps.letsencrypt.org." { record := new(dns.A) record.Hdr = dns.RR_Header{Name: "cps.letsencrypt.org.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} record.A = net.ParseIP("127.0.0.1") appendAnswer(record) } if q.Name == "dualstack.letsencrypt.org." { record := new(dns.A) record.Hdr = dns.RR_Header{Name: "dualstack.letsencrypt.org.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} record.A = net.ParseIP("127.0.0.1") appendAnswer(record) } if q.Name == "v6error.letsencrypt.org." { record := new(dns.A) record.Hdr = dns.RR_Header{Name: "dualstack.letsencrypt.org.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} record.A = net.ParseIP("127.0.0.1") appendAnswer(record) } if q.Name == "v4error.letsencrypt.org." { m.SetRcode(r, dns.RcodeNotImplemented) } if q.Name == "nxdomain.letsencrypt.org." { m.SetRcode(r, dns.RcodeNameError) } if q.Name == "dualstackerror.letsencrypt.org." { m.SetRcode(r, dns.RcodeRefused) } case dns.TypeCNAME: if q.Name == "cname.letsencrypt.org." { record := new(dns.CNAME) record.Hdr = dns.RR_Header{Name: "cname.letsencrypt.org.", Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 30} record.Target = "cps.letsencrypt.org." appendAnswer(record) } if q.Name == "cname.example.com." { record := new(dns.CNAME) record.Hdr = dns.RR_Header{Name: "cname.example.com.", Rrtype: dns.TypeCNAME, Class: dns.ClassINET, Ttl: 30} record.Target = "CAA.example.com." appendAnswer(record) } case dns.TypeDNAME: if q.Name == "dname.letsencrypt.org." { record := new(dns.DNAME) record.Hdr = dns.RR_Header{Name: "dname.letsencrypt.org.", Rrtype: dns.TypeDNAME, Class: dns.ClassINET, Ttl: 30} record.Target = "cps.letsencrypt.org." appendAnswer(record) } case dns.TypeCAA: if q.Name == "bracewel.net." || q.Name == "caa.example.com." { record := new(dns.CAA) record.Hdr = dns.RR_Header{Name: q.Name, Rrtype: dns.TypeCAA, Class: dns.ClassINET, Ttl: 0} record.Tag = "issue" record.Value = "letsencrypt.org" record.Flag = 1 appendAnswer(record) } if q.Name == "cname.example.com." { record := new(dns.CAA) record.Hdr = dns.RR_Header{Name: "caa.example.com.", Rrtype: dns.TypeCAA, Class: dns.ClassINET, Ttl: 0} record.Tag = "issue" record.Value = "letsencrypt.org" record.Flag = 1 appendAnswer(record) } case dns.TypeTXT: if q.Name == "split-txt.letsencrypt.org." { record := new(dns.TXT) record.Hdr = dns.RR_Header{Name: "split-txt.letsencrypt.org.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} record.Txt = []string{"a", "b", "c"} appendAnswer(record) } else { auth := new(dns.SOA) auth.Hdr = dns.RR_Header{Name: "letsencrypt.org.", Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: 0} auth.Ns = "ns.letsencrypt.org." auth.Mbox = "master.letsencrypt.org." auth.Serial = 1 auth.Refresh = 1 auth.Retry = 1 auth.Expire = 1 auth.Minttl = 1 m.Ns = append(m.Ns, auth) } if q.Name == "nxdomain.letsencrypt.org." { m.SetRcode(r, dns.RcodeNameError) } } } err := w.WriteMsg(m) if err != nil { panic(err) // running tests, so panic is OK } return }
func (ts *testSrv) dnsHandler(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) m.Compress = false // Normally this test DNS server will return 127.0.0.1 for everything. // However, in some situations (for instance Docker), it's useful to return a // different hardcoded host. You can do so by setting the FAKE_DNS environment // variable. fakeDNS := os.Getenv("FAKE_DNS") if fakeDNS == "" { fakeDNS = "127.0.0.1" } for _, q := range r.Question { fmt.Printf("dns-srv: Query -- [%s] %s\n", q.Name, dns.TypeToString[q.Qtype]) switch q.Qtype { case dns.TypeA: record := new(dns.A) record.Hdr = dns.RR_Header{ Name: q.Name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0, } record.A = net.ParseIP(fakeDNS) m.Answer = append(m.Answer, record) case dns.TypeMX: record := new(dns.MX) record.Hdr = dns.RR_Header{ Name: q.Name, Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 0, } record.Mx = "mail." + q.Name record.Preference = 10 m.Answer = append(m.Answer, record) case dns.TypeTXT: ts.mu.RLock() value, present := ts.txtRecords[q.Name] ts.mu.RUnlock() if !present { continue } record := new(dns.TXT) record.Hdr = dns.RR_Header{ Name: q.Name, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0, } record.Txt = []string{value} m.Answer = append(m.Answer, record) case dns.TypeCAA: if q.Name == "bad-caa-reserved.com." || q.Name == "good-caa-reserved.com." { record := new(dns.CAA) record.Hdr = dns.RR_Header{ Name: q.Name, Rrtype: dns.TypeCAA, Class: dns.ClassINET, Ttl: 0, } record.Tag = "issue" if q.Name == "bad-caa-reserved.com." { record.Value = "sad-hacker-ca.invalid" } else if q.Name == "good-caa-reserved.com." { record.Value = "happy-hacker-ca.invalid" } m.Answer = append(m.Answer, record) } } } auth := new(dns.SOA) auth.Hdr = dns.RR_Header{Name: "boulder.invalid.", Rrtype: dns.TypeSOA, Class: dns.ClassINET, Ttl: 0} auth.Ns = "ns.boulder.invalid." auth.Mbox = "master.boulder.invalid." auth.Serial = 1 auth.Refresh = 1 auth.Retry = 1 auth.Expire = 1 auth.Minttl = 1 m.Ns = append(m.Ns, auth) w.WriteMsg(m) return }