mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-06 16:18:00 +08:00
Return NS records randomly
Previously when the NS records were returned, ns-aws was always returned first. Coincidentally, 64% of the queries were directed to ns-aws. And once I exceeded AWS's 10 TB bandwidth limit, AWS began gouging me for bandwidth charges, and $12.66/month rapidly climbed to $62.30 I'm hoping that by randomly rotating the order of nameservers, the traffic will balance across the nameservers. Current snapshot (already ns-ovh is helping): ns-aws.sslip.io "Queries: 237744377 (1800.6/s)" "Answered Queries: 63040894 (477.5/s)" ns-azure.sslip.io "Queries: 42610823 (323.4/s)" "Answered Queries: 14660603 (111.3/s)" ns-gce.sslip.io "Queries: 59734371 (454.1/s)" "Answered Queries: 17636444 (134.1/s)" ns-ovh.sslip.io "Queries: 135897332 (1034.4/s)" "Answered Queries: 36010164 (274.1/s)"
This commit is contained in:
@@ -42,12 +42,13 @@ var _ = Describe("flags", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0`))
|
Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0`))
|
||||||
Eventually(digSession).Should(Say(`;; ANSWER SECTION:`))
|
Eventually(digSession).Should(Say(`;; ANSWER SECTION:`))
|
||||||
Eventually(digSession).Should(Say(`mickey.minnie.\n`))
|
|
||||||
Eventually(digSession).Should(Say(`daffy.duck.\n`))
|
|
||||||
Eventually(digSession, 1).Should(Exit(0))
|
Eventually(digSession, 1).Should(Exit(0))
|
||||||
|
Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`mickey.minnie.\n`))
|
||||||
|
Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`daffy.duck.\n`))
|
||||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`Adding nameserver "mickey\.minnie\."\n`))
|
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`Adding nameserver "mickey\.minnie\."\n`))
|
||||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`Adding nameserver "daffy\.duck\."\n`))
|
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`Adding nameserver "daffy\.duck\."\n`))
|
||||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS example.com. \? mickey\.minnie\., daffy\.duck\.\n`))
|
// we don't know the order in which the nameservers will be returned, so we try both
|
||||||
|
Eventually(string(serverSession.Err.Contents())).Should(Or(MatchRegexp(`TypeNS example.com. \? mickey\.minnie\., daffy\.duck\.\n`), MatchRegexp(`TypeNS example.com. \? daffy\.duck\., mickey\.minnie\.\n`)))
|
||||||
})
|
})
|
||||||
When("a nameserver is an empty string", func() {
|
When("a nameserver is an empty string", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
|
@@ -268,10 +268,6 @@ var _ = Describe("sslip.io-dns-server", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 7`))
|
Eventually(digSession).Should(Say(`flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 7`))
|
||||||
Eventually(digSession).Should(Say(`;; ANSWER SECTION:`))
|
Eventually(digSession).Should(Say(`;; ANSWER SECTION:`))
|
||||||
Eventually(digSession).Should(Say(`ns-aws.sslip.io.\n`))
|
|
||||||
Eventually(digSession).Should(Say(`ns-azure.sslip.io.\n`))
|
|
||||||
Eventually(digSession).Should(Say(`ns-gce.sslip.io.\n`))
|
|
||||||
Eventually(digSession).Should(Say(`ns-ovh.sslip.io.\n`))
|
|
||||||
Eventually(digSession).Should(Say(`;; ADDITIONAL SECTION:`))
|
Eventually(digSession).Should(Say(`;; ADDITIONAL SECTION:`))
|
||||||
Eventually(digSession).Should(Say(`ns-aws.sslip.io..*52.0.56.137\n`))
|
Eventually(digSession).Should(Say(`ns-aws.sslip.io..*52.0.56.137\n`))
|
||||||
Eventually(digSession).Should(Say(`ns-aws.sslip.io..*2600:1f18:aaf:6900::a\n`))
|
Eventually(digSession).Should(Say(`ns-aws.sslip.io..*2600:1f18:aaf:6900::a\n`))
|
||||||
@@ -281,6 +277,11 @@ var _ = Describe("sslip.io-dns-server", func() {
|
|||||||
Eventually(digSession).Should(Say(`ns-ovh.sslip.io..*51.75.53.19\n`))
|
Eventually(digSession).Should(Say(`ns-ovh.sslip.io..*51.75.53.19\n`))
|
||||||
Eventually(digSession).Should(Say(`ns-ovh.sslip.io..*2001:41d0:602:2313::1\n`))
|
Eventually(digSession).Should(Say(`ns-ovh.sslip.io..*2001:41d0:602:2313::1\n`))
|
||||||
Eventually(digSession, 1).Should(Exit(0))
|
Eventually(digSession, 1).Should(Exit(0))
|
||||||
|
// the server names may appear out-of-order
|
||||||
|
Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-aws.sslip.io.\n`))
|
||||||
|
Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-azure.sslip.io.\n`))
|
||||||
|
Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-gce.sslip.io.\n`))
|
||||||
|
Eventually(string(digSession.Out.Contents())).Should(MatchRegexp(`NS\tns-ovh.sslip.io.\n`))
|
||||||
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS example.com. \? ns-aws.sslip.io., ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n`))
|
Eventually(string(serverSession.Err.Contents())).Should(MatchRegexp(`TypeNS example.com. \? ns-aws.sslip.io., ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n`))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -400,9 +401,10 @@ var _ = Describe("sslip.io-dns-server", func() {
|
|||||||
"@localhost international-raiffeisen-bank.fc00--.sslip.io aaaa +short",
|
"@localhost international-raiffeisen-bank.fc00--.sslip.io aaaa +short",
|
||||||
`\Afc00::\n\z`,
|
`\Afc00::\n\z`,
|
||||||
`TypeAAAA international-raiffeisen-bank.fc00--.sslip.io. \? fc00::\n$`),
|
`TypeAAAA international-raiffeisen-bank.fc00--.sslip.io. \? fc00::\n$`),
|
||||||
|
// use regex to account for rotated nameserver order
|
||||||
Entry("an NS record with acme_challenge with a forbidden string is not delegated",
|
Entry("an NS record with acme_challenge with a forbidden string is not delegated",
|
||||||
"@localhost _acme-challenge.raiffeisen.fe80--.sslip.io ns +short",
|
"@localhost _acme-challenge.raiffeisen.fe80--.sslip.io ns +short",
|
||||||
`\Ans-aws.sslip.io.\nns-azure.sslip.io.\nns-gce.sslip.io.\nns-ovh.sslip.io.\n\z`,
|
`\Ans-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\nns-[a-z]+.sslip.io.\n\z`,
|
||||||
`TypeNS _acme-challenge.raiffeisen.fe80--.sslip.io. \? ns-aws.sslip.io., ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n$`),
|
`TypeNS _acme-challenge.raiffeisen.fe80--.sslip.io. \? ns-aws.sslip.io., ns-azure.sslip.io., ns-gce.sslip.io., ns-ovh.sslip.io.\n$`),
|
||||||
Entry("an A record with a forbidden CIDR is redirected",
|
Entry("an A record with a forbidden CIDR is redirected",
|
||||||
"@localhost nf.43.134.66.67.sslip.io +short",
|
"@localhost nf.43.134.66.67.sslip.io +short",
|
||||||
|
@@ -647,9 +647,13 @@ func (x *Xip) NSResponse(name dnsmessage.Name, response Response, logMessage str
|
|||||||
var logMessages []string
|
var logMessages []string
|
||||||
if response.Header.Authoritative {
|
if response.Header.Authoritative {
|
||||||
// we're authoritative, so we reply with the answers
|
// we're authoritative, so we reply with the answers
|
||||||
|
// but we rotate the nameservers every second so ns-aws doesn't bear the brunt (64%) of the traffic
|
||||||
|
epoch := time.Now().UTC().Unix()
|
||||||
|
index := int(epoch) % len(x.NameServers)
|
||||||
|
rotatedNameservers := append(x.NameServers[index:], x.NameServers[0:index]...)
|
||||||
response.Answers = append(response.Answers,
|
response.Answers = append(response.Answers,
|
||||||
func(b *dnsmessage.Builder) error {
|
func(b *dnsmessage.Builder) error {
|
||||||
return buildNSRecords(b, name, x.NameServers)
|
return buildNSRecords(b, name, rotatedNameservers)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// we're NOT authoritative, so we reply who is authoritative
|
// we're NOT authoritative, so we reply who is authoritative
|
||||||
|
Reference in New Issue
Block a user