traefik/integration/fake_dns_server.go

120 lines
3 KiB
Go
Raw Normal View History

2018-07-03 10:44:04 +00:00
package integration
import (
"fmt"
"net"
"os"
"github.com/miekg/dns"
"github.com/traefik/traefik/v2/pkg/log"
2018-07-03 10:44:04 +00:00
)
type handler struct{}
// ServeDNS a fake DNS server
// Simplified version of the Challenge Test Server from Boulder
// https://github.com/letsencrypt/boulder/blob/a6597b9f120207eff192c3e4107a7e49972a0250/test/challtestsrv/dnsone.go#L40
func (s *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
2019-09-13 17:28:04 +00:00
logger := log.WithoutContext()
2018-07-03 10:44:04 +00:00
m := new(dns.Msg)
m.SetReply(r)
m.Compress = false
fakeDNS := os.Getenv("DOCKER_HOST_IP")
if fakeDNS == "" {
fakeDNS = "127.0.0.1"
}
2019-09-13 17:28:04 +00:00
2018-07-03 10:44:04 +00:00
for _, q := range r.Question {
2019-09-13 17:28:04 +00:00
logger.Infof("Query -- [%s] %s", q.Name, dns.TypeToString[q.Qtype])
2018-07-03 10:44:04 +00:00
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.TypeCAA:
addCAARecord := true
var value string
switch q.Name {
case "bad-caa-reserved.com.":
value = "sad-hacker-ca.invalid"
case "good-caa-reserved.com.":
value = "happy-hacker-ca.invalid"
case "accounturi.good-caa-reserved.com.":
uri := os.Getenv("ACCOUNT_URI")
value = fmt.Sprintf("happy-hacker-ca.invalid; accounturi=%s", uri)
case "recheck.good-caa-reserved.com.":
// Allow issuance when we're running in the past
// (under FAKECLOCK), otherwise deny issuance.
if os.Getenv("FAKECLOCK") != "" {
value = "happy-hacker-ca.invalid"
} else {
value = "sad-hacker-ca.invalid"
}
case "dns-01-only.good-caa-reserved.com.":
value = "happy-hacker-ca.invalid; validationmethods=dns-01"
case "http-01-only.good-caa-reserved.com.":
value = "happy-hacker-ca.invalid; validationmethods=http-01"
case "dns-01-or-http-01.good-caa-reserved.com.":
value = "happy-hacker-ca.invalid; validationmethods=dns-01,http-01"
default:
addCAARecord = false
}
if addCAARecord {
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 = value
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)
2018-08-06 18:00:03 +00:00
if err := w.WriteMsg(m); err != nil {
2019-09-13 17:28:04 +00:00
logger.Fatalf("Failed to write message %v", err)
2018-08-06 18:00:03 +00:00
}
2018-07-03 10:44:04 +00:00
}
func startFakeDNSServer() *dns.Server {
srv := &dns.Server{
Addr: ":5053",
Net: "udp",
Handler: &handler{},
}
go func() {
2019-09-13 17:28:04 +00:00
log.WithoutContext().Infof("Start a fake DNS server.")
2018-07-03 10:44:04 +00:00
if err := srv.ListenAndServe(); err != nil {
2019-09-13 17:28:04 +00:00
log.WithoutContext().Fatalf("Failed to set udp listener %v", err)
2018-07-03 10:44:04 +00:00
}
}()
return srv
}