mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-05 23:56:50 +08:00
Flag -delegates
for delegated domains
Meant for obtaining wildcard certs from Let's Encrypt using the DNS-01 challenge. - introduce a variant of `blocklist.txt` to be used for testing (`blocklist-test.txt`) because the blocklist has grown so large it clutters the test output - more rigorous about lowercasing hostnames when matching against customized records. This needs to be extendend when we parse _any_ arguments TODOs: - remove the wildcard DNS servers - update instructions
This commit is contained in:
10
etc/blocklist-test.txt
Normal file
10
etc/blocklist-test.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
# TESTING ONLY: List of "Forbidden" (blocked) names & CIDRs
|
||||
|
||||
# This is a shortened variant meant to be used for testing (`ginkgo`) because
|
||||
# the legitimate one has grown so long it clutters the test output
|
||||
|
||||
raiffeisen # https://www.rbinternational.com/en/homepage.html
|
||||
43-134-66-67 # Netflix, https://nf-43-134-66-67.sslip.io/sg
|
||||
43.134.66.67/24 # Netflix
|
||||
2601:646:100:69f7:cafe:bebe:cafe:bebe/112 # personal (Comcast) IPv6 range for testing blocklist
|
||||
|
@@ -18,7 +18,7 @@ var _ = Describe("flags", func() {
|
||||
var flags []string
|
||||
|
||||
JustBeforeEach(func() {
|
||||
flags = append(flags, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist.txt")
|
||||
flags = append(flags, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist-test.txt")
|
||||
serverCmd = exec.Command(serverPath, flags...)
|
||||
serverSession, err = Start(serverCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
@@ -160,4 +160,77 @@ var _ = Describe("flags", func() {
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`fc00--\.sslip\.io\. \? fc00::`))
|
||||
})
|
||||
})
|
||||
When("-delegates is set", func() {
|
||||
BeforeEach(func() {
|
||||
flags = []string{"-delegates=" +
|
||||
"_acme-challenge.127-0-0-1.IP.io=ns.nono.io," +
|
||||
"2600--.IP.IO=ns-1.nono.com," +
|
||||
"_acme-challenge.73-189-219-4.ip.IO=ns-2.nono.com," +
|
||||
"a.b.C=d.E.f"}
|
||||
})
|
||||
When("the arguments are missing", func() {
|
||||
BeforeEach(func() {
|
||||
flags = []string{"-delegates="}
|
||||
})
|
||||
It("should give an informative message", func() {
|
||||
Expect(string(serverSession.Err.Contents())).Should(MatchRegexp(`-delegates: arguments should be in the format "delegatedDomain=nameserver", not ""`))
|
||||
})
|
||||
})
|
||||
When("the arguments are mangled", func() {
|
||||
BeforeEach(func() {
|
||||
flags = []string{"-delegates=blahblah"}
|
||||
})
|
||||
It("should give an informative message", func() {
|
||||
Expect(string(serverSession.Err.Contents())).Should(MatchRegexp(`-delegates: arguments should be in the format "delegatedDomain=nameserver", not "blahblah"`))
|
||||
})
|
||||
})
|
||||
When("only some of the arguments are mangled", func() {
|
||||
BeforeEach(func() {
|
||||
flags = []string{"-delegates=a.b=c.d,blahblah"}
|
||||
})
|
||||
It("adds the correct ones, gives an informative message for the mangled ones", func() {
|
||||
Expect(string(serverSession.Err.Contents())).Should(MatchRegexp(`Adding delegated NS record "a.b.=c.d."`))
|
||||
Expect(string(serverSession.Err.Contents())).Should(MatchRegexp(`-delegates: arguments should be in the format "delegatedDomain=nameserver", not "blahblah"`))
|
||||
})
|
||||
})
|
||||
When("looking up a delegated domain", func() {
|
||||
It("should return a non-authoritative NS record pointing to the nameserver", func() {
|
||||
digArgs := "@localhost _acme-challenge.127-0-0-1.IP.io -p " + strconv.Itoa(port)
|
||||
digCmd := exec.Command("dig", strings.Split(digArgs, " ")...)
|
||||
digSession, err := Start(digCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(digSession).Should(Say(`flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0`))
|
||||
Eventually(digSession).Should(Say(`;; AUTHORITY SECTION:`))
|
||||
Eventually(digSession).Should(Say(`_acme-challenge.127-0-0-1.IP.io. 604800 IN NS ns.nono.io.\n`))
|
||||
Eventually(digSession, 1).Should(Exit(0))
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`_acme-challenge\.127-0-0-1\.IP\.io\. \? nil, NS ns\.nono\.io\.`))
|
||||
})
|
||||
})
|
||||
When("looking up the subdomain of a delegated domain", func() {
|
||||
It("should return a non-authoritative NS record pointing to the nameserver", func() {
|
||||
digArgs := "@localhost subdomain.2600--.IP.IO -p " + strconv.Itoa(port)
|
||||
digCmd := exec.Command("dig", strings.Split(digArgs, " ")...)
|
||||
digSession, err := Start(digCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(digSession).Should(Say(`flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0`))
|
||||
Eventually(digSession).Should(Say(`;; AUTHORITY SECTION:`))
|
||||
Eventually(digSession).Should(Say(`subdomain.2600--.IP.IO. 604800 IN NS ns-1.nono.com.\n`))
|
||||
Eventually(digSession, 1).Should(Exit(0))
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`subdomain\.2600--\.IP\.IO\. \? nil, NS ns-1\.nono\.com\.`))
|
||||
})
|
||||
})
|
||||
When("looking up a delegated domain that wouldn't have resolved to an IP address", func() {
|
||||
It("it delegates", func() {
|
||||
digArgs := "@localhost a.b.c -p " + strconv.Itoa(port)
|
||||
digCmd := exec.Command("dig", strings.Split(digArgs, " ")...)
|
||||
digSession, err := Start(digCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(digSession).Should(Say(`flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0`))
|
||||
Eventually(digSession).Should(Say(`;; AUTHORITY SECTION:`))
|
||||
Eventually(digSession).Should(Say(`a.b.c. 604800 IN NS d.e.f.`))
|
||||
Eventually(digSession, 1).Should(Exit(0))
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`a\.b\.c\. \? nil, NS d\.e\.f\.`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@@ -20,7 +20,7 @@ var _ = Describe("speed", func() {
|
||||
var flags []string
|
||||
|
||||
JustBeforeEach(func() {
|
||||
flags = append(flags, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist.txt")
|
||||
flags = append(flags, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist-test.txt")
|
||||
serverCmd = exec.Command(serverPath, flags...)
|
||||
serverSession, err = Start(serverCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
@@ -26,7 +26,7 @@ var serverPath, _ = Build("main.go")
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
serverCmd = exec.Command(serverPath, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist.txt")
|
||||
serverCmd = exec.Command(serverPath, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist-test.txt")
|
||||
serverSession, err = Start(serverCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
// takes 0.455s to start up on macOS Big Sur 3.7 GHz Quad Core 22-nm Xeon E5-1620v2 processor (2013 Mac Pro)
|
||||
@@ -414,7 +414,7 @@ var _ = Describe("sslip.io-dns-server", func() {
|
||||
When("it can't bind to any UDP port", func() {
|
||||
It("prints an error message and exits", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist.txt")
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(port), "-blocklistURL", "file://etc/blocklist-test.txt")
|
||||
secondServerSession, err := Start(secondServerCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(secondServerSession.Err, 10).Should(Say("I couldn't bind via UDP to any IPs"))
|
||||
@@ -436,7 +436,7 @@ var _ = Describe("sslip.io-dns-server", func() {
|
||||
})
|
||||
It("prints an error message and continues running", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(newPort), "-blocklistURL", "file://etc/blocklist.txt")
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(newPort), "-blocklistURL", "file://etc/blocklist-test.txt")
|
||||
secondServerSession, err := Start(secondServerCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(secondServerSession.Err, 10).Should(Say(` version \d+\.\d+\.\d+ starting`))
|
||||
@@ -456,7 +456,7 @@ var _ = Describe("sslip.io-dns-server", func() {
|
||||
})
|
||||
It("prints an informative message and binds to the addresses it can", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(newPort), "-blocklistURL", "file://etc/blocklist.txt")
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(newPort), "-blocklistURL", "file://etc/blocklist-test.txt")
|
||||
secondServerSession, err := Start(secondServerCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(secondServerSession.Err, 10).Should(Say(` version \d+\.\d+\.\d+ starting`))
|
||||
@@ -479,7 +479,7 @@ var _ = Describe("sslip.io-dns-server", func() {
|
||||
})
|
||||
It("prints an informative message and binds to the addresses it can", func() {
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(newPort), "-blocklistURL", "file://etc/blocklist.txt")
|
||||
secondServerCmd := exec.Command(serverPath, "-port", strconv.Itoa(newPort), "-blocklistURL", "file://etc/blocklist-test.txt")
|
||||
secondServerSession, err := Start(secondServerCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(secondServerSession.Err, 10).Should(Say(` version \d+\.\d+\.\d+ starting`))
|
||||
|
6
main.go
6
main.go
@@ -33,6 +33,10 @@ func main() {
|
||||
"ns-gce.sslip.io=104.155.144.4,"+
|
||||
"ns-gce.sslip.io=2600:1900:4000:4d12::",
|
||||
"comma-separated list of hosts and corresponding IPv4 and/or IPv6 address(es). If you're running your own sslip.io nameservers, add their hostnames and addresses here. If unsure, add to the list rather than replace")
|
||||
var delegates = flag.String("delegates", "", "comma-separated list of domains you own "+
|
||||
"and nameservers you control to which to delegate, often used to acquire wildcard certificates from "+
|
||||
"Let's Encrypt via DNS challenge. Example: "+
|
||||
`-delegates=_acme-challenge.73-189-219-4.xip.nono.io=ns-437.awsdns-54.com.,_acme-challenge.73-189-219-4.xip.nono.io=ns-1097.awsdns-09.org."`)
|
||||
var bindPort = flag.Int("port", 53, "port the DNS server should bind to")
|
||||
var quiet = flag.Bool("quiet", false, "suppresses logging of each DNS response. Use this to avoid Google Cloud charging you $30/month to retain the logs of your GKE-based sslip.io server")
|
||||
var public = flag.Bool("public", true, "allows resolution of public IP addresses. If false, only resolves private IPs including localhost (127/8, ::1), link-local (169.254/16, fe80::/10), CG-NAT (100.64/12), private (10/8, 172.16/12, 192.168/16, fc/7). Set to false if you don't want miscreants impersonating you via public IPs. If unsure, set to false")
|
||||
@@ -41,7 +45,7 @@ func main() {
|
||||
log.Printf("blocklist URL: %s, name servers: %s, bind port: %d, quiet: %t",
|
||||
*blocklistURL, *nameservers, *bindPort, *quiet)
|
||||
|
||||
x, logmessages := xip.NewXip(*blocklistURL, strings.Split(*nameservers, ","), strings.Split(*addresses, ","))
|
||||
x, logmessages := xip.NewXip(*blocklistURL, strings.Split(*nameservers, ","), strings.Split(*addresses, ","), strings.Split(*delegates, ","))
|
||||
x.Public = *public
|
||||
for _, logmessage := range logmessages {
|
||||
log.Println(logmessage)
|
||||
|
87
xip/xip.go
87
xip/xip.go
@@ -64,6 +64,7 @@ type DomainCustomization struct {
|
||||
AAAA []dnsmessage.AAAAResource
|
||||
CNAME dnsmessage.CNAMEResource
|
||||
MX []dnsmessage.MXResource
|
||||
NS []dnsmessage.NSResource
|
||||
TXT func(*Xip, net.IP) ([]dnsmessage.TXTResource, error)
|
||||
// Unlike the other record types, TXT is a function in order to enable more complex behavior
|
||||
// e.g. IP address of the query's source
|
||||
@@ -167,7 +168,7 @@ type Response struct {
|
||||
}
|
||||
|
||||
// NewXip follows convention for constructors: https://go.dev/doc/effective_go#allocation_new
|
||||
func NewXip(blocklistURL string, nameservers []string, addresses []string) (x *Xip, logmessages []string) {
|
||||
func NewXip(blocklistURL string, nameservers []string, addresses []string, delegates []string) (x *Xip, logmessages []string) {
|
||||
x = &Xip{Metrics: Metrics{Start: time.Now()}}
|
||||
|
||||
// Download the blocklist
|
||||
@@ -213,7 +214,7 @@ func NewXip(blocklistURL string, nameservers []string, addresses []string) (x *X
|
||||
if host[len(host)-1] != '.' {
|
||||
host += "."
|
||||
}
|
||||
if ip == nil { // bad IP address
|
||||
if ip == nil { // bad IP delegate
|
||||
logmessages = append(logmessages, fmt.Sprintf(`-addresses: "%s" is not assigned a valid IP "%s"`, hostAddr, ip.String()))
|
||||
continue
|
||||
}
|
||||
@@ -247,6 +248,38 @@ func NewXip(blocklistURL string, nameservers []string, addresses []string) (x *X
|
||||
// print out the added records in a manner similar to the way they're set on the cmdline
|
||||
logmessages = append(logmessages, fmt.Sprintf(`Adding record "%s=%s"`, host, ip))
|
||||
}
|
||||
// Parse and set the nameservers of our delegated domains
|
||||
for _, delegate := range delegates {
|
||||
delegatedDomainAndNameserver := strings.Split(strings.ToLower(delegate), "=")
|
||||
if len(delegatedDomainAndNameserver) != 2 {
|
||||
logmessages = append(logmessages, fmt.Sprintf(`-delegates: arguments should be in the format "delegatedDomain=nameserver", not "%s"`, delegate))
|
||||
continue
|
||||
}
|
||||
delegatedDomain := delegatedDomainAndNameserver[0]
|
||||
nameServer := delegatedDomainAndNameserver[1]
|
||||
// all domains & nameservers must be absolute (end in ".")
|
||||
if delegatedDomain[len(delegatedDomain)-1] != '.' {
|
||||
delegatedDomain += "."
|
||||
}
|
||||
if nameServer[len(nameServer)-1] != '.' {
|
||||
nameServer += "."
|
||||
}
|
||||
|
||||
// nameservers must be DNS-compliant
|
||||
nsName, err := dnsmessage.NewName(nameServer)
|
||||
if err != nil {
|
||||
logmessages = append(logmessages, fmt.Sprintf(`-nameservers: ignoring invalid nameserver "%s"`, nameServer))
|
||||
continue
|
||||
}
|
||||
var domainEntry = DomainCustomization{}
|
||||
if _, ok := Customizations[delegatedDomain]; ok {
|
||||
domainEntry = Customizations[delegatedDomain]
|
||||
}
|
||||
domainEntry.NS = append(domainEntry.NS, dnsmessage.NSResource{NS: nsName})
|
||||
Customizations[delegatedDomain] = domainEntry
|
||||
// print out the added records in a manner similar to the way they're set on the cmdline
|
||||
logmessages = append(logmessages, fmt.Sprintf(`Adding delegated NS record "%s=%s"`, delegatedDomain, nsName.String()))
|
||||
}
|
||||
|
||||
// We want to make sure that our DNS server isn't used in a DNS amplification attack.
|
||||
// The endpoint we're worried about is metrics.status.sslip.io, whose reply is
|
||||
@@ -360,11 +393,19 @@ func (x *Xip) processQuestion(q dnsmessage.Question, srcAddr net.IP) (response R
|
||||
RCode: dnsmessage.RCodeSuccess, // assume success, may be replaced later
|
||||
},
|
||||
}
|
||||
if IsDelegated(q.Name.String()) {
|
||||
// if xip.pivotal.io has been delegated to ns-437.awsdns-54.com.
|
||||
// and a query comes in for 127-0-0-1.cloudfoundry.xip.pivotal.io
|
||||
// then don't resolve the A record; instead, return the delegated
|
||||
// NS record, ns-437.awsdns-54.com.
|
||||
response.Header.Authoritative = false
|
||||
return x.NSResponse(q.Name, response, logMessage)
|
||||
}
|
||||
if IsAcmeChallenge(q.Name.String()) && !x.blocklist(q.Name.String()) {
|
||||
// thanks, @NormanR
|
||||
// delegate everything to its stripped (remove "_acme-challenge.") address, e.g.
|
||||
// dig _acme-challenge.127-0-0-1.sslip.io mx → NS 127-0-0-1.sslip.io
|
||||
response.Header.Authoritative = false // we're delegating, so we're not authoritative
|
||||
response.Header.Authoritative = false
|
||||
return x.NSResponse(q.Name, response, logMessage)
|
||||
}
|
||||
switch q.Type {
|
||||
@@ -598,8 +639,6 @@ func (x *Xip) processQuestion(q dnsmessage.Question, srcAddr net.IP) (response R
|
||||
}
|
||||
|
||||
// NSResponse sets the Answers/Authorities depending upon whether we're delegating or authoritative
|
||||
// (whether it's an "_acme-challenge." domain or not). Either way, it supplies the Additionals
|
||||
// (IP addresses of the nameservers).
|
||||
func (x *Xip) NSResponse(name dnsmessage.Name, response Response, logMessage string) (Response, string, error) {
|
||||
nameServers := x.NSResources(name.String())
|
||||
var logMessages []string
|
||||
@@ -753,9 +792,10 @@ func MXResources(fqdnString string) []dnsmessage.MXResource {
|
||||
}
|
||||
|
||||
func IsAcmeChallenge(fqdnString string) bool {
|
||||
if dns01ChallengeRE.MatchString(fqdnString) {
|
||||
ipv4s := NameToA(fqdnString, true)
|
||||
ipv6s := NameToAAAA(fqdnString, true)
|
||||
fqdnStringLowerCased := strings.ToLower(fqdnString)
|
||||
if dns01ChallengeRE.MatchString(fqdnStringLowerCased) {
|
||||
ipv4s := NameToA(fqdnStringLowerCased, true)
|
||||
ipv6s := NameToAAAA(fqdnStringLowerCased, true)
|
||||
if len(ipv4s) > 0 || len(ipv6s) > 0 {
|
||||
return true
|
||||
}
|
||||
@@ -763,15 +803,40 @@ func IsAcmeChallenge(fqdnString string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func IsDelegated(fqdnString string) bool {
|
||||
fqdnStringLowerCased := strings.ToLower(fqdnString)
|
||||
for domain := range Customizations {
|
||||
if Customizations[domain].NS == nil { // no nameserver? then it can't be delegated
|
||||
continue
|
||||
}
|
||||
// the "." prevents "where.com" from being mistakenly recognized as a subdomain of "here.com"
|
||||
if strings.HasSuffix(fqdnStringLowerCased, "."+domain) || fqdnStringLowerCased == domain {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Xip) NSResources(fqdnString string) []dnsmessage.NSResource {
|
||||
if x.blocklist(fqdnString) {
|
||||
fqdnStringLowerCased := strings.ToLower(fqdnString)
|
||||
if x.blocklist(fqdnStringLowerCased) {
|
||||
x.Metrics.AnsweredQueries++
|
||||
x.Metrics.AnsweredBlockedQueries++
|
||||
return x.NameServers
|
||||
}
|
||||
if IsAcmeChallenge(fqdnString) {
|
||||
// Is this a delegated domain? Let's return the delegated nameservers
|
||||
for domain := range Customizations {
|
||||
if Customizations[domain].NS == nil { // no nameserver? then it can't be delegated
|
||||
continue
|
||||
}
|
||||
// the "." prevents "where.com" from being mistakenly recognized as a subdomain of "here.com"
|
||||
if strings.HasSuffix(fqdnStringLowerCased, "."+domain) || fqdnStringLowerCased == domain {
|
||||
return Customizations[domain].NS
|
||||
}
|
||||
}
|
||||
if IsAcmeChallenge(fqdnStringLowerCased) {
|
||||
x.Metrics.AnsweredNSDNS01ChallengeQueries++
|
||||
strippedFqdn := dns01ChallengeRE.ReplaceAllString(fqdnString, "")
|
||||
strippedFqdn := dns01ChallengeRE.ReplaceAllString(fqdnStringLowerCased, "")
|
||||
ns, _ := dnsmessage.NewName(strippedFqdn)
|
||||
return []dnsmessage.NSResource{{NS: ns}}
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ var _ = Describe("Xip", func() {
|
||||
|
||||
Describe("NSResources()", func() {
|
||||
When("we use the default nameservers", func() {
|
||||
var x, _ = xip.NewXip("file:///", []string{"ns-aws.sslip.io.", "ns-azure.sslip.io.", "ns-gce.sslip.io."}, []string{})
|
||||
var x, _ = xip.NewXip("file:///", []string{"ns-aws.sslip.io.", "ns-azure.sslip.io.", "ns-gce.sslip.io."}, []string{}, []string{})
|
||||
It("returns the name servers", func() {
|
||||
randomDomain := testhelper.Random8ByteString() + ".com."
|
||||
ns := x.NSResources(randomDomain)
|
||||
@@ -94,7 +94,7 @@ var _ = Describe("Xip", func() {
|
||||
randomDomain := "192.168.0.1." + testhelper.Random8ByteString() + ".com."
|
||||
ns := x.NSResources("_acme-challenge." + randomDomain)
|
||||
Expect(len(ns)).To(Equal(1))
|
||||
Expect(ns[0].NS.String()).To(Equal(randomDomain))
|
||||
Expect(ns[0].NS.String()).To(Equal(strings.ToLower(randomDomain)))
|
||||
aResources := xip.NameToA(randomDomain, true)
|
||||
Expect(len(aResources)).To(Equal(1))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
@@ -109,9 +109,25 @@ var _ = Describe("Xip", func() {
|
||||
})
|
||||
})
|
||||
})
|
||||
When("we delegate domains to other nameservers", func() {
|
||||
When(`we don't use the "=" in the arguments`, func() {
|
||||
It("returns an informative log message", func() {
|
||||
var _, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-aws.sslip.io.", "ns-azure.sslip.io.", "ns-gce.sslip.io."}, []string{}, []string{"noEquals"})
|
||||
Expect(strings.Join(logs, "")).To(MatchRegexp(`"-delegates: arguments should be in the format "delegatedDomain=nameserver", not "noEquals"`))
|
||||
})
|
||||
})
|
||||
When(`there's no "." at the end of the delegated domain or nameserver`, func() {
|
||||
It(`helpfully adds the "."`, func() {
|
||||
var x, logs = xip.NewXip("file://etc/blocklist-test.txt", []string{"ns-aws.sslip.io.", "ns-azure.sslip.io.", "ns-gce.sslip.io."}, []string{}, []string{"a=b"})
|
||||
Expect(strings.Join(logs, "")).To(MatchRegexp(`Adding delegated NS record "a\.=b\."`))
|
||||
ns := x.NSResources("a.")
|
||||
Expect(len(ns)).To(Equal(1))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
When("we override the default nameservers", func() {
|
||||
var x, _ = xip.NewXip("file:///", []string{"mickey", "minn.ie.", "goo.fy"}, []string{})
|
||||
var x, _ = xip.NewXip("file:///", []string{"mickey", "minn.ie.", "goo.fy"}, []string{}, []string{})
|
||||
It("returns the configured servers", func() {
|
||||
randomDomain := testhelper.Random8ByteString() + ".com."
|
||||
ns := x.NSResources(randomDomain)
|
||||
@@ -287,6 +303,36 @@ var _ = Describe("Xip", func() {
|
||||
})
|
||||
})
|
||||
})
|
||||
Describe("IsDelegated()", func() {
|
||||
var nsName dnsmessage.Name
|
||||
nsName, err = dnsmessage.NewName("1.com")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
xip.Customizations["a.com"] = xip.DomainCustomization{NS: []dnsmessage.NSResource{dnsmessage.NSResource{NS: nsName}}}
|
||||
xip.Customizations["b.com"] = xip.DomainCustomization{}
|
||||
|
||||
When("the domain is delegated", func() {
|
||||
When("the fqdn exactly matches the domain", func() {
|
||||
It("returns true", func() {
|
||||
Expect(xip.IsDelegated("A.com")).To(BeTrue())
|
||||
})
|
||||
})
|
||||
When("the fqdn is a subdomain of the domain", func() {
|
||||
It("returns true", func() {
|
||||
Expect(xip.IsDelegated("b.a.COM")).To(BeTrue())
|
||||
})
|
||||
})
|
||||
When("the fqdn doesn't match the domain", func() {
|
||||
It("returns false", func() {
|
||||
Expect(xip.IsDelegated("Aa.com")).To(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
When("the domain is customized but not delegated", func() {
|
||||
It("returns false", func() {
|
||||
Expect(xip.IsDelegated("b.COM")).To(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("NameToAAAA()", func() {
|
||||
DescribeTable("when it succeeds",
|
||||
|
Reference in New Issue
Block a user