mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-07 00:23:44 +08:00
Response queries include NS IP addrs in Additionals
When querying for NS (name server) records, the responses include an "Additionals" section which lists the IP addresses of the name server. This is a courtesy & an optimization: by sending the IP address, we avoid the client sending a second query for the IP address of the nameserver. With this change, the following command... ``` dig @ns-aws.nono.io sslip.io ns ``` ...will yield these additional records: ```diff +;; ADDITIONAL SECTION: +ns-aws.nono.io. 604800 IN A 52.0.56.137 +ns-azure.nono.io. 604800 IN A 52.187.42.158 +ns-gce.nono.io. 604800 IN A 104.155.144.4 ```
This commit is contained in:
@@ -134,30 +134,38 @@ var _ = Describe("sslip.io-dns-server", func() {
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeMX sslip.io. \? 10 mail.protonmail.ch., 20 mailsec.protonmail.ch.\n`))
|
||||
})
|
||||
})
|
||||
When("there are multiple NS records returned (e.g. almost NS query)", func() {
|
||||
When("there are multiple NS records returned (e.g. almost any NS query)", func() {
|
||||
It("returns all the records", func() {
|
||||
digArgs = "@localhost example.com ns"
|
||||
digCmd = exec.Command("dig", strings.Split(digArgs, " ")...)
|
||||
digSession, err = Start(digCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(digSession).Should(Say(`flags: qr aa rd;`))
|
||||
Eventually(digSession).Should(Say(`aws.nono.io.`))
|
||||
Eventually(digSession).Should(Say(`azure.nono.io.`))
|
||||
Eventually(digSession).Should(Say(`gce.nono.io.`))
|
||||
Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 3`))
|
||||
Eventually(digSession).Should(Say(`;; ANSWER SECTION:`))
|
||||
Eventually(digSession).Should(Say(`ns-aws.nono.io.\n`))
|
||||
Eventually(digSession).Should(Say(`ns-azure.nono.io.\n`))
|
||||
Eventually(digSession).Should(Say(`ns-gce.nono.io.\n`))
|
||||
Eventually(digSession).Should(Say(`;; ADDITIONAL SECTION:`))
|
||||
Eventually(digSession).Should(Say(`ns-aws.nono.io..*52.0.56.137\n`))
|
||||
Eventually(digSession).Should(Say(`ns-azure.nono.io..*52.187.42.158\n`))
|
||||
Eventually(digSession).Should(Say(`ns-gce.nono.io..*104.155.144.4\n`))
|
||||
Eventually(digSession, 1).Should(Exit(0))
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS example.com. \? ns-aws.nono.io., ns-azure.nono.io., ns-gce.nono.io.\n`))
|
||||
})
|
||||
})
|
||||
When(`the NS record for an "_acme-challenge" domain is queried`, func() {
|
||||
It(`returns the NS record of the query with the "_acme-challenge." stripped`, func() {
|
||||
digArgs = "@localhost _acme-challenge.127-0-0-1.sslip.io ns"
|
||||
digArgs = "@localhost _acme-challenge.fe80--.sslip.io ns"
|
||||
digCmd = exec.Command("dig", strings.Split(digArgs, " ")...)
|
||||
digSession, err = Start(digCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Eventually(digSession).Should(Say(`flags: qr aa rd;`))
|
||||
Eventually(digSession).Should(Say(`127-0-0-1.sslip.io.`))
|
||||
Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1`))
|
||||
Eventually(digSession).Should(Say(`;; ANSWER SECTION:`))
|
||||
Eventually(digSession).Should(Say(`fe80--.sslip.io.`))
|
||||
Eventually(digSession).Should(Say(`;; ADDITIONAL SECTION:`))
|
||||
Eventually(digSession).Should(Say(`fe80--.sslip.io..*fe80::\n`))
|
||||
Eventually(digSession, 1).Should(Exit(0))
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS _acme-challenge.127-0-0-1.sslip.io. \? 127-0-0-1.sslip.io.\n`))
|
||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS _acme-challenge.fe80--.sslip.io. \? fe80--.sslip.io.\n`))
|
||||
})
|
||||
})
|
||||
When(`there are multiple TXT records returned (e.g. SPF for sslip.io)`, func() {
|
||||
|
@@ -112,6 +112,7 @@ type Response struct {
|
||||
Header dnsmessage.Header
|
||||
Answers []func(*dnsmessage.Builder) error
|
||||
Authorities []func(*dnsmessage.Builder) error
|
||||
Additionals []func(*dnsmessage.Builder) error
|
||||
}
|
||||
|
||||
// QueryResponse takes in a raw (packed) DNS query and returns a raw (packed)
|
||||
@@ -170,6 +171,14 @@ func QueryResponse(queryBytes []byte) (responseBytes []byte, logMessage string,
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
if err = b.StartAdditionals(); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
for _, additionals := range response.Additionals {
|
||||
if err = additionals(&b); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
if responseBytes, err = b.Finish(); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -338,7 +347,6 @@ func processQuestion(q dnsmessage.Question, response *Response) (string, error)
|
||||
nameServers := NSResources(q.Name.String())
|
||||
var logMessages []string
|
||||
response.Answers = append(response.Answers,
|
||||
// 1 or more A records; A records > 1 only available via Customizations
|
||||
func(b *dnsmessage.Builder) error {
|
||||
for _, nameServer := range nameServers {
|
||||
err = b.NSResource(dnsmessage.ResourceHeader{
|
||||
@@ -354,6 +362,36 @@ func processQuestion(q dnsmessage.Question, response *Response) (string, error)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
response.Additionals = append(response.Additionals,
|
||||
func(b *dnsmessage.Builder) error {
|
||||
for _, nameServer := range nameServers {
|
||||
for _, aResource := range NameToA(nameServer.NS.String()) {
|
||||
err = b.AResource(dnsmessage.ResourceHeader{
|
||||
Name: nameServer.NS,
|
||||
Type: dnsmessage.TypeA,
|
||||
Class: dnsmessage.ClassINET,
|
||||
TTL: 604800, // 60 * 60 * 24 * 7 == 1 week; long TTL, these IP addrs don't change
|
||||
Length: 0,
|
||||
}, aResource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, aaaaResource := range NameToAAAA(nameServer.NS.String()) {
|
||||
err = b.AAAAResource(dnsmessage.ResourceHeader{
|
||||
Name: nameServer.NS,
|
||||
Type: dnsmessage.TypeAAAA,
|
||||
Class: dnsmessage.ClassINET,
|
||||
TTL: 604800, // 60 * 60 * 24 * 7 == 1 week; long TTL, these IP addrs don't change
|
||||
Length: 0,
|
||||
}, aaaaResource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
for _, nameServer := range nameServers {
|
||||
logMessages = append(logMessages, nameServer.NS.String())
|
||||
}
|
||||
@@ -512,8 +550,7 @@ func NameToA(fqdnString string) []dnsmessage.AResource {
|
||||
return []dnsmessage.AResource{}
|
||||
}
|
||||
|
||||
// NameToAAAA returns either []AAAAResource that matched the hostname
|
||||
// or ErrNotFound
|
||||
// NameToAAAA returns an []AAAAResource that matched the hostname
|
||||
func NameToAAAA(fqdnString string) []dnsmessage.AAAAResource {
|
||||
fqdn := []byte(fqdnString)
|
||||
// is it a customized AAAA record? If so, return early
|
||||
|
Reference in New Issue
Block a user